LCOV - code coverage report
Current view: top level - source3/torture - torture.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 4456 8212 54.3 %
Date: 2024-05-31 13:13:24 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 "tldap_tls_connect.h"
      31             : #include "../librpc/gen_ndr/svcctl.h"
      32             : #include "../lib/util/memcache.h"
      33             : #include "nsswitch/winbind_client.h"
      34             : #include "dbwrap/dbwrap.h"
      35             : #include "dbwrap/dbwrap_open.h"
      36             : #include "dbwrap/dbwrap_rbt.h"
      37             : #include "async_smb.h"
      38             : #include "libsmb/libsmb.h"
      39             : #include "libsmb/clirap.h"
      40             : #include "trans2.h"
      41             : #include "libsmb/nmblib.h"
      42             : #include "../lib/util/tevent_ntstatus.h"
      43             : #include "util_tdb.h"
      44             : #include "../libcli/smb/read_smb.h"
      45             : #include "../libcli/smb/smbXcli_base.h"
      46             : #include "lib/util/sys_rw_data.h"
      47             : #include "lib/util/base64.h"
      48             : #include "lib/util/time.h"
      49             : #include "lib/gencache.h"
      50             : #include "lib/util/sys_rw.h"
      51             : #include "lib/util/asn1.h"
      52             : #include "lib/util/util_file.h"
      53             : #include "lib/param/param.h"
      54             : #include "auth/gensec/gensec.h"
      55             : #include "lib/util/string_wrappers.h"
      56             : #include "source3/lib/substitute.h"
      57             : #include "ads.h"
      58             : 
      59             : #include <gnutls/gnutls.h>
      60             : #include <gnutls/crypto.h>
      61             : 
      62             : extern char *optarg;
      63             : extern int optind;
      64             : 
      65             : fstring host, workgroup, share, password, username, myname;
      66             : struct cli_credentials *torture_creds;
      67             : static const char *sockops="TCP_NODELAY";
      68             : int torture_nprocs=1;
      69             : static int port_to_use=0;
      70             : int torture_numops=100;
      71             : int torture_blocksize=1024*1024;
      72             : static int procnum; /* records process count number when forking */
      73             : static struct cli_state *current_cli;
      74             : static fstring randomfname;
      75             : static bool use_oplocks;
      76             : static bool use_level_II_oplocks;
      77             : static const char *client_txt = "client_oplocks.txt";
      78             : static bool disable_spnego;
      79             : static bool use_kerberos;
      80             : static bool force_dos_errors;
      81             : static fstring multishare_conn_fname;
      82             : static bool use_multishare_conn = False;
      83             : static bool do_encrypt;
      84             : static const char *local_path = NULL;
      85             : static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
      86             : char *test_filename;
      87             : 
      88             : bool torture_showall = False;
      89             : 
      90             : static double create_procs(bool (*fn)(int), bool *result);
      91             : 
      92             : /********************************************************************
      93             :  Ensure a connection is encrypted.
      94             : ********************************************************************/
      95             : 
      96         200 : static bool force_cli_encryption(struct cli_state *c,
      97             :                         const char *sharename)
      98             : {
      99           0 :         uint16_t major, minor;
     100           0 :         uint32_t caplow, caphigh;
     101           0 :         NTSTATUS status;
     102             : 
     103         200 :         if (!SERVER_HAS_UNIX_CIFS(c)) {
     104           0 :                 d_printf("Encryption required and "
     105             :                         "server that doesn't support "
     106             :                         "UNIX extensions - failing connect\n");
     107           0 :                         return false;
     108             :         }
     109             : 
     110         200 :         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
     111             :                                              &caphigh);
     112         200 :         if (!NT_STATUS_IS_OK(status)) {
     113           0 :                 d_printf("Encryption required and "
     114             :                         "can't get UNIX CIFS extensions "
     115             :                         "version from server: %s\n", nt_errstr(status));
     116           0 :                 return false;
     117             :         }
     118             : 
     119         200 :         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
     120           0 :                 d_printf("Encryption required and "
     121             :                         "share %s doesn't support "
     122             :                         "encryption.\n", sharename);
     123           0 :                 return false;
     124             :         }
     125             : 
     126         200 :         status = cli_smb1_setup_encryption(c, torture_creds);
     127         200 :         if (!NT_STATUS_IS_OK(status)) {
     128           0 :                 d_printf("Encryption required and "
     129             :                         "setup failed with error %s.\n",
     130             :                         nt_errstr(status));
     131           0 :                 return false;
     132             :         }
     133             : 
     134         200 :         return true;
     135             : }
     136             : 
     137             : 
     138         100 : static struct cli_state *open_nbt_connection(void)
     139             : {
     140           0 :         struct cli_state *c;
     141           0 :         NTSTATUS status;
     142         100 :         int flags = 0;
     143             : 
     144         100 :         if (disable_spnego) {
     145           0 :                 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
     146             :         }
     147             : 
     148         100 :         if (use_oplocks) {
     149           0 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     150             :         }
     151             : 
     152         100 :         if (use_level_II_oplocks) {
     153           0 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     154             :         }
     155             : 
     156         100 :         if (force_dos_errors) {
     157           0 :                 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
     158             :         }
     159             : 
     160         100 :         status = cli_connect_nb(NULL,
     161             :                                 host,
     162             :                                 NULL,
     163             :                                 port_to_use,
     164             :                                 0x20,
     165             :                                 myname,
     166             :                                 signing_state,
     167             :                                 flags,
     168             :                                 &c);
     169         100 :         if (!NT_STATUS_IS_OK(status)) {
     170           0 :                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
     171           0 :                 return NULL;
     172             :         }
     173             : 
     174         100 :         cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
     175             : 
     176         100 :         return c;
     177             : }
     178             : 
     179             : /****************************************************************************
     180             :  Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
     181             : ****************************************************************************/
     182             : 
     183           4 : static bool cli_bad_session_request(int fd,
     184             :                          struct nmb_name *calling, struct nmb_name *called)
     185             : {
     186           0 :         TALLOC_CTX *frame;
     187           0 :         uint8_t len_buf[4];
     188           0 :         struct iovec iov[3];
     189           0 :         ssize_t len;
     190           0 :         uint8_t *inbuf;
     191           0 :         int err;
     192           4 :         bool ret = false;
     193           0 :         uint8_t message_type;
     194           0 :         uint8_t error;
     195           0 :         struct tevent_context *ev;
     196           0 :         struct tevent_req *req;
     197             : 
     198           4 :         frame = talloc_stackframe();
     199             : 
     200           4 :         iov[0].iov_base = len_buf;
     201           4 :         iov[0].iov_len  = sizeof(len_buf);
     202             : 
     203             :         /* put in the destination name */
     204             : 
     205           4 :         iov[1].iov_base = name_mangle(talloc_tos(), called->name,
     206           4 :                                       called->name_type);
     207           4 :         if (iov[1].iov_base == NULL) {
     208           0 :                 goto fail;
     209             :         }
     210           4 :         iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
     211           4 :                                   talloc_get_size(iov[1].iov_base));
     212             : 
     213             :         /* and my name */
     214             : 
     215           4 :         iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
     216           4 :                                       calling->name_type);
     217           4 :         if (iov[2].iov_base == NULL) {
     218           0 :                 goto fail;
     219             :         }
     220           4 :         iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
     221           4 :                                   talloc_get_size(iov[2].iov_base));
     222             : 
     223             :         /* Deliberately corrupt the name len (first byte) */
     224           4 :         *((uint8_t *)iov[2].iov_base) = 100;
     225             : 
     226             :         /* send a session request (RFC 1002) */
     227             :         /* setup the packet length
     228             :          * Remove four bytes from the length count, since the length
     229             :          * field in the NBT Session Service header counts the number
     230             :          * of bytes which follow.  The cli_send_smb() function knows
     231             :          * about this and accounts for those four bytes.
     232             :          * CRH.
     233             :          */
     234             : 
     235           4 :         _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
     236           4 :         SCVAL(len_buf,0,0x81);
     237             : 
     238           4 :         len = write_data_iov(fd, iov, 3);
     239           4 :         if (len == -1) {
     240           0 :                 goto fail;
     241             :         }
     242             : 
     243           4 :         ev = samba_tevent_context_init(frame);
     244           4 :         if (ev == NULL) {
     245           0 :                 goto fail;
     246             :         }
     247           4 :         req = read_smb_send(frame, ev, fd);
     248           4 :         if (req == NULL) {
     249           0 :                 goto fail;
     250             :         }
     251           4 :         if (!tevent_req_poll(req, ev)) {
     252           0 :                 goto fail;
     253             :         }
     254           4 :         len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
     255           4 :         if (len == -1) {
     256           0 :                 errno = err;
     257           0 :                 goto fail;
     258             :         }
     259           4 :         TALLOC_FREE(ev);
     260             : 
     261           4 :         message_type = CVAL(inbuf, 0);
     262           4 :         if (message_type != 0x83) {
     263           0 :                 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
     264             :                           message_type);
     265           0 :                 goto fail;
     266             :         }
     267             : 
     268           4 :         if (smb_len(inbuf) != 1) {
     269           0 :                 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
     270           0 :                           (int)smb_len(inbuf));
     271           0 :                 goto fail;
     272             :         }
     273             : 
     274           4 :         error = CVAL(inbuf, 4);
     275           4 :         if (error !=  0x82) {
     276           0 :                 d_fprintf(stderr, "Expected error 0x82, got %d\n",
     277             :                           (int)error);
     278           0 :                 goto fail;
     279             :         }
     280             : 
     281           4 :         ret = true;
     282           4 : fail:
     283           4 :         TALLOC_FREE(frame);
     284           4 :         return ret;
     285             : }
     286             : 
     287             : /* Insert a NULL at the first separator of the given path and return a pointer
     288             :  * to the remainder of the string.
     289             :  */
     290             : static char *
     291           0 : terminate_path_at_separator(char * path)
     292             : {
     293           0 :         char * p;
     294             : 
     295           0 :         if (!path) {
     296           0 :                 return NULL;
     297             :         }
     298             : 
     299           0 :         if ((p = strchr_m(path, '/'))) {
     300           0 :                 *p = '\0';
     301           0 :                 return p + 1;
     302             :         }
     303             : 
     304           0 :         if ((p = strchr_m(path, '\\'))) {
     305           0 :                 *p = '\0';
     306           0 :                 return p + 1;
     307             :         }
     308             : 
     309             :         /* No separator. */
     310           0 :         return NULL;
     311             : }
     312             : 
     313             : /*
     314             :   parse a //server/share type UNC name
     315             : */
     316           0 : bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
     317             :                       char **hostname, char **sharename)
     318             : {
     319           0 :         char *p;
     320             : 
     321           0 :         *hostname = *sharename = NULL;
     322             : 
     323           0 :         if (strncmp(unc_name, "\\\\", 2) &&
     324           0 :             strncmp(unc_name, "//", 2)) {
     325           0 :                 return False;
     326             :         }
     327             : 
     328           0 :         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
     329           0 :         p = terminate_path_at_separator(*hostname);
     330             : 
     331           0 :         if (p && *p) {
     332           0 :                 *sharename = talloc_strdup(mem_ctx, p);
     333           0 :                 terminate_path_at_separator(*sharename);
     334             :         }
     335             : 
     336           0 :         if (*hostname && *sharename) {
     337           0 :                 return True;
     338             :         }
     339             : 
     340           0 :         TALLOC_FREE(*hostname);
     341           0 :         TALLOC_FREE(*sharename);
     342           0 :         return False;
     343             : }
     344             : 
     345         497 : static bool torture_open_connection_share(struct cli_state **c,
     346             :                                    const char *hostname,
     347             :                                    const char *sharename,
     348             :                                    int flags)
     349             : {
     350           0 :         NTSTATUS status;
     351             : 
     352         497 :         status = cli_full_connection_creds(NULL,
     353             :                                            c,
     354             :                                            myname,
     355             :                                            hostname,
     356             :                                            NULL, /* dest_ss */
     357             :                                            port_to_use,
     358             :                                            sharename,
     359             :                                            "?????",
     360             :                                            torture_creds,
     361             :                                            flags);
     362         497 :         if (!NT_STATUS_IS_OK(status)) {
     363           2 :                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
     364             :                         hostname, sharename, port_to_use, nt_errstr(status));
     365           2 :                 return False;
     366             :         }
     367             : 
     368         495 :         cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
     369             : 
     370         495 :         if (do_encrypt) {
     371         198 :                 return force_cli_encryption(*c,
     372             :                                         sharename);
     373             :         }
     374         297 :         return True;
     375             : }
     376             : 
     377         497 : bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
     378             : {
     379         497 :         char **unc_list = NULL;
     380         497 :         int num_unc_names = 0;
     381           0 :         bool result;
     382             : 
     383         497 :         if (use_multishare_conn==True) {
     384           0 :                 char *h, *s;
     385           0 :                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
     386           0 :                 if (!unc_list || num_unc_names <= 0) {
     387           0 :                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
     388           0 :                         exit(1);
     389             :                 }
     390             : 
     391           0 :                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
     392             :                                       NULL, &h, &s)) {
     393           0 :                         printf("Failed to parse UNC name %s\n",
     394           0 :                                unc_list[conn_index % num_unc_names]);
     395           0 :                         TALLOC_FREE(unc_list);
     396           0 :                         exit(1);
     397             :                 }
     398             : 
     399           0 :                 result = torture_open_connection_share(c, h, s, flags);
     400             : 
     401             :                 /* h, s were copied earlier */
     402           0 :                 TALLOC_FREE(unc_list);
     403           0 :                 return result;
     404             :         }
     405             : 
     406         497 :         return torture_open_connection_share(c, host, share, flags);
     407             : }
     408             : 
     409         485 : bool torture_open_connection(struct cli_state **c, int conn_index)
     410             : {
     411         485 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
     412             : 
     413         485 :         if (use_oplocks) {
     414           8 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     415             :         }
     416         485 :         if (use_level_II_oplocks) {
     417           8 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     418             :         }
     419             : 
     420         485 :         return torture_open_connection_flags(c, conn_index, flags);
     421             : }
     422             : 
     423          90 : bool torture_init_connection(struct cli_state **pcli)
     424             : {
     425           0 :         struct cli_state *cli;
     426             : 
     427          90 :         cli = open_nbt_connection();
     428          90 :         if (cli == NULL) {
     429           0 :                 return false;
     430             :         }
     431             : 
     432          90 :         *pcli = cli;
     433          90 :         return true;
     434             : }
     435             : 
     436           5 : bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
     437             : {
     438           5 :         uint16_t old_vuid = cli_state_get_uid(cli);
     439           0 :         NTSTATUS status;
     440           0 :         bool ret;
     441             : 
     442           5 :         cli_state_set_uid(cli, 0);
     443           5 :         status = cli_session_setup_creds(cli, torture_creds);
     444           5 :         ret = NT_STATUS_IS_OK(status);
     445           5 :         *new_vuid = cli_state_get_uid(cli);
     446           5 :         cli_state_set_uid(cli, old_vuid);
     447           5 :         return ret;
     448             : }
     449             : 
     450             : 
     451         421 : bool torture_close_connection(struct cli_state *c)
     452             : {
     453         421 :         bool ret = True;
     454           0 :         NTSTATUS status;
     455             : 
     456         421 :         status = cli_tdis(c);
     457         421 :         if (!NT_STATUS_IS_OK(status)) {
     458           5 :                 printf("tdis failed (%s)\n", nt_errstr(status));
     459           5 :                 ret = False;
     460             :         }
     461             : 
     462         421 :         cli_shutdown(c);
     463             : 
     464         421 :         return ret;
     465             : }
     466             : 
     467          48 : void torture_conn_set_sockopt(struct cli_state *cli)
     468             : {
     469          48 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     470          48 : }
     471             : 
     472          58 : static NTSTATUS torture_delete_fn(struct file_info *finfo,
     473             :                                   const char *pattern,
     474             :                                   void *state)
     475             : {
     476           0 :         NTSTATUS status;
     477          58 :         char *filename = NULL;
     478          58 :         char *dirname = NULL;
     479          58 :         char *p = NULL;
     480          58 :         TALLOC_CTX *frame = talloc_stackframe();
     481          58 :         struct cli_state *cli = (struct cli_state *)state;
     482             : 
     483          58 :         if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
     484          36 :                 TALLOC_FREE(frame);
     485          36 :                 return NT_STATUS_OK;
     486             :         }
     487             : 
     488          22 :         dirname = talloc_strdup(frame, pattern);
     489          22 :         if (dirname == NULL) {
     490           0 :                 TALLOC_FREE(frame);
     491           0 :                 return NT_STATUS_NO_MEMORY;
     492             :         }
     493          22 :         p = strrchr_m(dirname, '\\');
     494          22 :         if (p != NULL) {
     495             :                 /* Remove the terminating '\' */
     496          22 :                 *p = '\0';
     497             :         }
     498          22 :         if (dirname[0] != '\0') {
     499          22 :                 filename = talloc_asprintf(frame,
     500             :                                            "%s\\%s",
     501             :                                            dirname,
     502             :                                            finfo->name);
     503             :         } else {
     504           0 :                 filename = talloc_asprintf(frame,
     505             :                                            "%s",
     506             :                                            finfo->name);
     507             :         }
     508          22 :         if (filename == NULL) {
     509           0 :                 TALLOC_FREE(frame);
     510           0 :                 return NT_STATUS_NO_MEMORY;
     511             :         }
     512          22 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
     513           5 :                 char *subdirname = talloc_asprintf(frame,
     514             :                                                    "%s\\*",
     515             :                                                    filename);
     516           5 :                 if (subdirname == NULL) {
     517           0 :                         TALLOC_FREE(frame);
     518           0 :                         return NT_STATUS_NO_MEMORY;
     519             :                 }
     520           5 :                 status = cli_list(cli,
     521             :                                   subdirname,
     522             :                                   FILE_ATTRIBUTE_DIRECTORY |
     523             :                                           FILE_ATTRIBUTE_HIDDEN |
     524             :                                           FILE_ATTRIBUTE_SYSTEM,
     525             :                                   torture_delete_fn,
     526             :                                   cli);
     527           5 :                 if (!NT_STATUS_IS_OK(status)) {
     528           0 :                         printf("torture_delete_fn: cli_list "
     529             :                                 "of %s failed (%s)\n",
     530             :                                 subdirname,
     531             :                                 nt_errstr(status));
     532           0 :                         TALLOC_FREE(frame);
     533           0 :                         return status;
     534             :                 }
     535           5 :                 status = cli_rmdir(cli, filename);
     536             :         } else {
     537          17 :                 status = cli_unlink(cli,
     538             :                                     filename,
     539             :                                     FILE_ATTRIBUTE_SYSTEM |
     540             :                                         FILE_ATTRIBUTE_HIDDEN);
     541             :         }
     542          22 :         if (!NT_STATUS_IS_OK(status)) {
     543           0 :                 if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
     544           0 :                         printf("torture_delete_fn: cli_rmdir"
     545             :                                 " of %s failed (%s)\n",
     546             :                                 filename,
     547             :                                 nt_errstr(status));
     548             :                 } else {
     549           0 :                         printf("torture_delete_fn: cli_unlink"
     550             :                                 " of %s failed (%s)\n",
     551             :                                 filename,
     552             :                                 nt_errstr(status));
     553             :                 }
     554             :         }
     555          22 :         TALLOC_FREE(frame);
     556          22 :         return status;
     557             : }
     558             : 
     559          30 : void torture_deltree(struct cli_state *cli, const char *dname)
     560             : {
     561          30 :         char *mask = NULL;
     562           0 :         NTSTATUS status;
     563             : 
     564             :         /* It might be a file */
     565          30 :         (void)cli_unlink(cli,
     566             :                          dname,
     567             :                          FILE_ATTRIBUTE_SYSTEM |
     568             :                                 FILE_ATTRIBUTE_HIDDEN);
     569             : 
     570          30 :         mask = talloc_asprintf(cli,
     571             :                                "%s\\*",
     572             :                                dname);
     573          30 :         if (mask == NULL) {
     574           0 :                 printf("torture_deltree: talloc_asprintf failed\n");
     575           0 :                 return;
     576             :         }
     577             : 
     578          30 :         status = cli_list(cli,
     579             :                         mask,
     580             :                         FILE_ATTRIBUTE_DIRECTORY |
     581             :                                 FILE_ATTRIBUTE_HIDDEN|
     582             :                                 FILE_ATTRIBUTE_SYSTEM,
     583             :                         torture_delete_fn,
     584             :                         cli);
     585          30 :         if (!NT_STATUS_IS_OK(status)) {
     586          17 :                 printf("torture_deltree: cli_list of %s failed (%s)\n",
     587             :                         mask,
     588             :                         nt_errstr(status));
     589             :         }
     590          30 :         TALLOC_FREE(mask);
     591          30 :         status = cli_rmdir(cli, dname);
     592          30 :         if (!NT_STATUS_IS_OK(status)) {
     593          17 :                 printf("torture_deltree: cli_rmdir of %s failed (%s)\n",
     594             :                         dname,
     595             :                         nt_errstr(status));
     596             :         }
     597             : }
     598             : 
     599             : /* check if the server produced the expected dos or nt error code */
     600          53 : static bool check_both_error(int line, NTSTATUS status,
     601             :                              uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     602             : {
     603          53 :         if (NT_STATUS_IS_DOS(status)) {
     604           0 :                 uint8_t cclass;
     605           0 :                 uint32_t num;
     606             : 
     607             :                 /* Check DOS error */
     608           0 :                 cclass = NT_STATUS_DOS_CLASS(status);
     609           0 :                 num = NT_STATUS_DOS_CODE(status);
     610             : 
     611           0 :                 if (eclass != cclass || ecode != num) {
     612           0 :                         printf("unexpected error code class=%d code=%d\n",
     613             :                                (int)cclass, (int)num);
     614           0 :                         printf(" expected %d/%d %s (line=%d)\n",
     615             :                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
     616           0 :                         return false;
     617             :                 }
     618             :         } else {
     619             :                 /* Check NT error */
     620          53 :                 if (!NT_STATUS_EQUAL(nterr, status)) {
     621           0 :                         printf("unexpected error code %s\n",
     622             :                                 nt_errstr(status));
     623           0 :                         printf(" expected %s (line=%d)\n",
     624             :                                 nt_errstr(nterr), line);
     625           0 :                         return false;
     626             :                 }
     627             :         }
     628             : 
     629          53 :         return true;
     630             : }
     631             : 
     632             : 
     633             : /* check if the server produced the expected error code */
     634          38 : static bool check_error(int line, NTSTATUS status,
     635             :                         uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     636             : {
     637          38 :         if (NT_STATUS_IS_DOS(status)) {
     638           0 :                 uint8_t cclass;
     639           0 :                 uint32_t num;
     640             : 
     641             :                 /* Check DOS error */
     642             : 
     643           0 :                 cclass = NT_STATUS_DOS_CLASS(status);
     644           0 :                 num = NT_STATUS_DOS_CODE(status);
     645             : 
     646           0 :                 if (eclass != cclass || ecode != num) {
     647           0 :                         printf("unexpected error code class=%d code=%d\n",
     648             :                                (int)cclass, (int)num);
     649           0 :                         printf(" expected %d/%d %s (line=%d)\n",
     650             :                                (int)eclass, (int)ecode, nt_errstr(nterr),
     651             :                                line);
     652           0 :                         return False;
     653             :                 }
     654             : 
     655             :         } else {
     656             :                 /* Check NT error */
     657             : 
     658          38 :                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
     659           1 :                         printf("unexpected error code %s\n",
     660             :                                nt_errstr(status));
     661           1 :                         printf(" expected %s (line=%d)\n", nt_errstr(nterr),
     662             :                                line);
     663           1 :                         return False;
     664             :                 }
     665             :         }
     666             : 
     667          37 :         return True;
     668             : }
     669             : 
     670           9 : NTSTATUS cli_qpathinfo1(struct cli_state *cli,
     671             :                         const char *fname,
     672             :                         time_t *change_time,
     673             :                         time_t *access_time,
     674             :                         time_t *write_time,
     675             :                         off_t *size,
     676             :                         uint32_t *pattr)
     677             : {
     678           9 :         int timezone = smb1cli_conn_server_time_zone(cli->conn);
     679           9 :         time_t (*date_fn)(const void *buf, int serverzone) = NULL;
     680           9 :         uint8_t *rdata = NULL;
     681           0 :         uint32_t num_rdata;
     682           0 :         NTSTATUS status;
     683             : 
     684           9 :         status = cli_qpathinfo(talloc_tos(),
     685             :                                cli,
     686             :                                fname,
     687             :                                SMB_INFO_STANDARD,
     688             :                                22,
     689             :                                CLI_BUFFER_SIZE,
     690             :                                &rdata,
     691             :                                &num_rdata);
     692           9 :         if (!NT_STATUS_IS_OK(status)) {
     693           4 :                 return status;
     694             :         }
     695           5 :         if (cli->win95) {
     696           0 :                 date_fn = make_unix_date;
     697             :         } else {
     698           5 :                 date_fn = make_unix_date2;
     699             :         }
     700             : 
     701           5 :         if (change_time) {
     702           5 :                 *change_time = date_fn(rdata + 0, timezone);
     703             :         }
     704           5 :         if (access_time) {
     705           5 :                 *access_time = date_fn(rdata + 4, timezone);
     706             :         }
     707           5 :         if (write_time) {
     708           5 :                 *write_time = date_fn(rdata + 8, timezone);
     709             :         }
     710           5 :         if (size) {
     711           5 :                 *size = PULL_LE_U32(rdata, 12);
     712             :         }
     713           5 :         if (pattr) {
     714           0 :                 *pattr = PULL_LE_U16(rdata, l1_attrFile);
     715             :         }
     716           5 :         return NT_STATUS_OK;
     717             : }
     718             : 
     719           0 : static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
     720             : {
     721           0 :         NTSTATUS status;
     722             : 
     723           0 :         status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     724             : 
     725           0 :         while (!NT_STATUS_IS_OK(status)) {
     726           0 :                 if (!check_both_error(__LINE__, status, ERRDOS,
     727           0 :                                       ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
     728           0 :                         return false;
     729             :                 }
     730             : 
     731           0 :                 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     732             :         }
     733             : 
     734           0 :         return true;
     735             : }
     736             : 
     737             : 
     738           0 : static bool rw_torture(struct cli_state *c)
     739             : {
     740           0 :         const char *lockfname = "\\torture.lck";
     741           0 :         fstring fname;
     742           0 :         uint16_t fnum;
     743           0 :         uint16_t fnum2;
     744           0 :         pid_t pid2, pid = getpid();
     745           0 :         int i, j;
     746           0 :         char buf[1024];
     747           0 :         bool correct = True;
     748           0 :         size_t nread = 0;
     749           0 :         NTSTATUS status;
     750             : 
     751           0 :         memset(buf, '\0', sizeof(buf));
     752             : 
     753           0 :         status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
     754             :                          DENY_NONE, &fnum2);
     755           0 :         if (!NT_STATUS_IS_OK(status)) {
     756           0 :                 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
     757             :         }
     758           0 :         if (!NT_STATUS_IS_OK(status)) {
     759           0 :                 printf("open of %s failed (%s)\n",
     760             :                        lockfname, nt_errstr(status));
     761           0 :                 return False;
     762             :         }
     763             : 
     764           0 :         for (i=0;i<torture_numops;i++) {
     765           0 :                 unsigned n = (unsigned)sys_random()%10;
     766             : 
     767           0 :                 if (i % 10 == 0) {
     768           0 :                         printf("%d\r", i); fflush(stdout);
     769             :                 }
     770           0 :                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
     771             : 
     772           0 :                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
     773           0 :                         return False;
     774             :                 }
     775             : 
     776           0 :                 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
     777             :                                   DENY_ALL, &fnum);
     778           0 :                 if (!NT_STATUS_IS_OK(status)) {
     779           0 :                         printf("open failed (%s)\n", nt_errstr(status));
     780           0 :                         correct = False;
     781           0 :                         break;
     782             :                 }
     783             : 
     784           0 :                 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
     785             :                                       sizeof(pid), NULL);
     786           0 :                 if (!NT_STATUS_IS_OK(status)) {
     787           0 :                         printf("write failed (%s)\n", nt_errstr(status));
     788           0 :                         correct = False;
     789             :                 }
     790             : 
     791           0 :                 for (j=0;j<50;j++) {
     792           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
     793           0 :                                               sizeof(pid)+(j*sizeof(buf)),
     794             :                                               sizeof(buf), NULL);
     795           0 :                         if (!NT_STATUS_IS_OK(status)) {
     796           0 :                                 printf("write failed (%s)\n",
     797             :                                        nt_errstr(status));
     798           0 :                                 correct = False;
     799             :                         }
     800             :                 }
     801             : 
     802           0 :                 pid2 = 0;
     803             : 
     804           0 :                 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
     805             :                                   &nread);
     806           0 :                 if (!NT_STATUS_IS_OK(status)) {
     807           0 :                         printf("read failed (%s)\n", nt_errstr(status));
     808           0 :                         correct = false;
     809           0 :                 } else if (nread != sizeof(pid)) {
     810           0 :                         printf("read/write compare failed: "
     811             :                                "recv %ld req %ld\n", (unsigned long)nread,
     812             :                                (unsigned long)sizeof(pid));
     813           0 :                         correct = false;
     814             :                 }
     815             : 
     816           0 :                 if (pid2 != pid) {
     817           0 :                         printf("data corruption!\n");
     818           0 :                         correct = False;
     819             :                 }
     820             : 
     821           0 :                 status = cli_close(c, fnum);
     822           0 :                 if (!NT_STATUS_IS_OK(status)) {
     823           0 :                         printf("close failed (%s)\n", nt_errstr(status));
     824           0 :                         correct = False;
     825             :                 }
     826             : 
     827           0 :                 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     828           0 :                 if (!NT_STATUS_IS_OK(status)) {
     829           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
     830           0 :                         correct = False;
     831             :                 }
     832             : 
     833           0 :                 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
     834           0 :                 if (!NT_STATUS_IS_OK(status)) {
     835           0 :                         printf("unlock failed (%s)\n", nt_errstr(status));
     836           0 :                         correct = False;
     837             :                 }
     838             :         }
     839             : 
     840           0 :         cli_close(c, fnum2);
     841           0 :         cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     842             : 
     843           0 :         printf("%d\n", i);
     844             : 
     845           0 :         return correct;
     846             : }
     847             : 
     848           0 : static bool run_torture(int dummy)
     849             : {
     850           0 :         struct cli_state *cli;
     851           0 :         bool ret;
     852             : 
     853           0 :         cli = current_cli;
     854             : 
     855           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     856             : 
     857           0 :         ret = rw_torture(cli);
     858             : 
     859           0 :         if (!torture_close_connection(cli)) {
     860           0 :                 ret = False;
     861             :         }
     862             : 
     863           0 :         return ret;
     864             : }
     865             : 
     866           0 : static bool rw_torture3(struct cli_state *c, char *lockfname)
     867             : {
     868           0 :         uint16_t fnum = (uint16_t)-1;
     869           0 :         unsigned int i = 0;
     870           0 :         char buf[131072];
     871           0 :         char buf_rd[131072];
     872           0 :         unsigned count;
     873           0 :         unsigned countprev = 0;
     874           0 :         size_t sent = 0;
     875           0 :         bool correct = True;
     876           0 :         NTSTATUS status = NT_STATUS_OK;
     877             : 
     878           0 :         srandom(1);
     879           0 :         for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
     880             :         {
     881           0 :                 SIVAL(buf, i, sys_random());
     882             :         }
     883             : 
     884           0 :         if (procnum == 0)
     885             :         {
     886           0 :                 status = cli_unlink(
     887             :                         c, lockfname,
     888             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     889           0 :                 if (!NT_STATUS_IS_OK(status)) {
     890           0 :                         printf("unlink failed (%s) (normal, this file should "
     891             :                                "not exist)\n", nt_errstr(status));
     892             :                 }
     893             : 
     894           0 :                 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
     895             :                                   DENY_NONE, &fnum);
     896           0 :                 if (!NT_STATUS_IS_OK(status)) {
     897           0 :                         printf("first open read/write of %s failed (%s)\n",
     898             :                                         lockfname, nt_errstr(status));
     899           0 :                         return False;
     900             :                 }
     901             :         }
     902             :         else
     903             :         {
     904           0 :                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
     905             :                 {
     906           0 :                         status = cli_openx(c, lockfname, O_RDONLY,
     907             :                                          DENY_NONE, &fnum);
     908           0 :                         if (NT_STATUS_IS_OK(status)) {
     909           0 :                                 break;
     910             :                         }
     911           0 :                         smb_msleep(10);
     912             :                 }
     913           0 :                 if (!NT_STATUS_IS_OK(status)) {
     914           0 :                         printf("second open read-only of %s failed (%s)\n",
     915             :                                         lockfname, nt_errstr(status));
     916           0 :                         return False;
     917             :                 }
     918             :         }
     919             : 
     920           0 :         i = 0;
     921           0 :         for (count = 0; count < sizeof(buf); count += sent)
     922             :         {
     923           0 :                 if (count >= countprev) {
     924           0 :                         printf("%d %8d\r", i, count);
     925           0 :                         fflush(stdout);
     926           0 :                         i++;
     927           0 :                         countprev += (sizeof(buf) / 20);
     928             :                 }
     929             : 
     930           0 :                 if (procnum == 0)
     931             :                 {
     932           0 :                         sent = ((unsigned)sys_random()%(20))+ 1;
     933           0 :                         if (sent > sizeof(buf) - count)
     934             :                         {
     935           0 :                                 sent = sizeof(buf) - count;
     936             :                         }
     937             : 
     938           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
     939             :                                               count, sent, NULL);
     940           0 :                         if (!NT_STATUS_IS_OK(status)) {
     941           0 :                                 printf("write failed (%s)\n",
     942             :                                        nt_errstr(status));
     943           0 :                                 correct = False;
     944             :                         }
     945             :                 }
     946             :                 else
     947             :                 {
     948           0 :                         status = cli_read(c, fnum, buf_rd+count, count,
     949             :                                           sizeof(buf)-count, &sent);
     950           0 :                         if(!NT_STATUS_IS_OK(status)) {
     951           0 :                                 printf("read failed offset:%d size:%ld (%s)\n",
     952             :                                        count, (unsigned long)sizeof(buf)-count,
     953             :                                        nt_errstr(status));
     954           0 :                                 correct = False;
     955           0 :                                 sent = 0;
     956           0 :                         } else if (sent > 0) {
     957           0 :                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
     958             :                                 {
     959           0 :                                         printf("read/write compare failed\n");
     960           0 :                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
     961           0 :                                         correct = False;
     962           0 :                                         break;
     963             :                                 }
     964             :                         }
     965             :                 }
     966             : 
     967             :         }
     968             : 
     969           0 :         status = cli_close(c, fnum);
     970           0 :         if (!NT_STATUS_IS_OK(status)) {
     971           0 :                 printf("close failed (%s)\n", nt_errstr(status));
     972           0 :                 correct = False;
     973             :         }
     974             : 
     975           0 :         return correct;
     976             : }
     977             : 
     978          18 : static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
     979             : {
     980          18 :         const char *lockfname = "\\torture2.lck";
     981           0 :         uint16_t fnum1;
     982           0 :         uint16_t fnum2;
     983           0 :         int i;
     984           0 :         char buf[131072];
     985           0 :         char buf_rd[131072];
     986          18 :         bool correct = True;
     987           0 :         size_t bytes_read;
     988           0 :         NTSTATUS status;
     989             : 
     990          18 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     991          18 :         if (!NT_STATUS_IS_OK(status)) {
     992          18 :                 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
     993             :         }
     994             : 
     995          18 :         status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
     996             :                           DENY_NONE, &fnum1);
     997          18 :         if (!NT_STATUS_IS_OK(status)) {
     998           0 :                 printf("first open read/write of %s failed (%s)\n",
     999             :                                 lockfname, nt_errstr(status));
    1000           0 :                 return False;
    1001             :         }
    1002             : 
    1003          18 :         status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
    1004          18 :         if (!NT_STATUS_IS_OK(status)) {
    1005           0 :                 printf("second open read-only of %s failed (%s)\n",
    1006             :                                 lockfname, nt_errstr(status));
    1007           0 :                 cli_close(c1, fnum1);
    1008           0 :                 return False;
    1009             :         }
    1010             : 
    1011        1818 :         for (i = 0; i < torture_numops; i++)
    1012             :         {
    1013        1800 :                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
    1014        1800 :                 if (i % 10 == 0) {
    1015         180 :                         printf("%d\r", i); fflush(stdout);
    1016             :                 }
    1017             : 
    1018        1800 :                 generate_random_buffer((unsigned char *)buf, buf_size);
    1019             : 
    1020        1800 :                 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
    1021             :                                       buf_size, NULL);
    1022        1800 :                 if (!NT_STATUS_IS_OK(status)) {
    1023           0 :                         printf("write failed (%s)\n", nt_errstr(status));
    1024           0 :                         correct = False;
    1025           0 :                         break;
    1026             :                 }
    1027             : 
    1028        1800 :                 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
    1029        1800 :                 if(!NT_STATUS_IS_OK(status)) {
    1030           0 :                         printf("read failed (%s)\n", nt_errstr(status));
    1031           0 :                         correct = false;
    1032           0 :                         break;
    1033        1800 :                 } else if (bytes_read != buf_size) {
    1034           0 :                         printf("read failed\n");
    1035           0 :                         printf("read %ld, expected %ld\n",
    1036             :                                (unsigned long)bytes_read,
    1037             :                                (unsigned long)buf_size);
    1038           0 :                         correct = False;
    1039           0 :                         break;
    1040             :                 }
    1041             : 
    1042        1800 :                 if (memcmp(buf_rd, buf, buf_size) != 0)
    1043             :                 {
    1044           0 :                         printf("read/write compare failed\n");
    1045           0 :                         correct = False;
    1046           0 :                         break;
    1047             :                 }
    1048             :         }
    1049             : 
    1050          18 :         status = cli_close(c2, fnum2);
    1051          18 :         if (!NT_STATUS_IS_OK(status)) {
    1052           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1053           0 :                 correct = False;
    1054             :         }
    1055             : 
    1056          18 :         status = cli_close(c1, fnum1);
    1057          18 :         if (!NT_STATUS_IS_OK(status)) {
    1058           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1059           0 :                 correct = False;
    1060             :         }
    1061             : 
    1062          18 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1063          18 :         if (!NT_STATUS_IS_OK(status)) {
    1064           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1065           0 :                 correct = False;
    1066             :         }
    1067             : 
    1068          18 :         return correct;
    1069             : }
    1070             : 
    1071           9 : static bool run_readwritetest(int dummy)
    1072             : {
    1073           0 :         struct cli_state *cli1, *cli2;
    1074           9 :         bool test1, test2 = False;
    1075             : 
    1076           9 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1077           0 :                 return False;
    1078             :         }
    1079           9 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1080           9 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1081             : 
    1082           9 :         printf("starting readwritetest\n");
    1083             : 
    1084           9 :         test1 = rw_torture2(cli1, cli2);
    1085           9 :         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
    1086             : 
    1087           9 :         if (test1) {
    1088           9 :                 test2 = rw_torture2(cli1, cli1);
    1089           9 :                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
    1090             :         }
    1091             : 
    1092           9 :         if (!torture_close_connection(cli1)) {
    1093           0 :                 test1 = False;
    1094             :         }
    1095             : 
    1096           9 :         if (!torture_close_connection(cli2)) {
    1097           0 :                 test2 = False;
    1098             :         }
    1099             : 
    1100           9 :         return (test1 && test2);
    1101             : }
    1102             : 
    1103           0 : static bool run_readwritemulti(int dummy)
    1104             : {
    1105           0 :         struct cli_state *cli;
    1106           0 :         bool test;
    1107             : 
    1108           0 :         cli = current_cli;
    1109             : 
    1110           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1111             : 
    1112           0 :         printf("run_readwritemulti: fname %s\n", randomfname);
    1113           0 :         test = rw_torture3(cli, randomfname);
    1114             : 
    1115           0 :         if (!torture_close_connection(cli)) {
    1116           0 :                 test = False;
    1117             :         }
    1118             : 
    1119           0 :         return test;
    1120             : }
    1121             : 
    1122          14 : static bool run_readwritelarge_internal(void)
    1123             : {
    1124           0 :         static struct cli_state *cli1;
    1125           0 :         uint16_t fnum1;
    1126          14 :         const char *lockfname = "\\large.dat";
    1127           0 :         off_t fsize;
    1128           0 :         char buf[126*1024];
    1129          14 :         bool correct = True;
    1130           0 :         NTSTATUS status;
    1131             : 
    1132          14 :         if (!torture_open_connection(&cli1, 0)) {
    1133           0 :                 return False;
    1134             :         }
    1135          14 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1136          14 :         memset(buf,'\0',sizeof(buf));
    1137             : 
    1138          14 :         printf("starting readwritelarge_internal\n");
    1139             : 
    1140          14 :         cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1141             : 
    1142          14 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
    1143             :                           DENY_NONE, &fnum1);
    1144          14 :         if (!NT_STATUS_IS_OK(status)) {
    1145           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
    1146           0 :                 return False;
    1147             :         }
    1148             : 
    1149          14 :         cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
    1150             : 
    1151          14 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
    1152             :                                      NULL, NULL, NULL);
    1153          14 :         if (!NT_STATUS_IS_OK(status)) {
    1154           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
    1155           0 :                 correct = False;
    1156             :         }
    1157             : 
    1158          14 :         if (fsize == sizeof(buf))
    1159          14 :                 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
    1160             :                        (unsigned long)fsize);
    1161             :         else {
    1162           0 :                 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
    1163             :                        (unsigned long)fsize);
    1164           0 :                 correct = False;
    1165             :         }
    1166             : 
    1167          14 :         status = cli_close(cli1, fnum1);
    1168          14 :         if (!NT_STATUS_IS_OK(status)) {
    1169           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1170           0 :                 correct = False;
    1171             :         }
    1172             : 
    1173          14 :         status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1174          14 :         if (!NT_STATUS_IS_OK(status)) {
    1175           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1176           0 :                 correct = False;
    1177             :         }
    1178             : 
    1179          14 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
    1180             :                           DENY_NONE, &fnum1);
    1181          14 :         if (!NT_STATUS_IS_OK(status)) {
    1182           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
    1183           0 :                 return False;
    1184             :         }
    1185             : 
    1186          14 :         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
    1187             : 
    1188          14 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
    1189             :                                      NULL, NULL, NULL);
    1190          14 :         if (!NT_STATUS_IS_OK(status)) {
    1191           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
    1192           0 :                 correct = False;
    1193             :         }
    1194             : 
    1195          14 :         if (fsize == sizeof(buf))
    1196          14 :                 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
    1197             :                        (unsigned long)fsize);
    1198             :         else {
    1199           0 :                 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
    1200             :                        (unsigned long)fsize);
    1201           0 :                 correct = False;
    1202             :         }
    1203             : 
    1204          14 :         status = cli_close(cli1, fnum1);
    1205          14 :         if (!NT_STATUS_IS_OK(status)) {
    1206           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1207           0 :                 correct = False;
    1208             :         }
    1209             : 
    1210          14 :         if (!torture_close_connection(cli1)) {
    1211           0 :                 correct = False;
    1212             :         }
    1213          14 :         return correct;
    1214             : }
    1215             : 
    1216           9 : static bool run_readwritelarge(int dummy)
    1217             : {
    1218           9 :         return run_readwritelarge_internal();
    1219             : }
    1220             : 
    1221           5 : static bool run_readwritelarge_signtest(int dummy)
    1222             : {
    1223           0 :         bool ret;
    1224           5 :         signing_state = SMB_SIGNING_REQUIRED;
    1225           5 :         ret = run_readwritelarge_internal();
    1226           5 :         signing_state = SMB_SIGNING_DEFAULT;
    1227           5 :         return ret;
    1228             : }
    1229             : 
    1230             : int line_count = 0;
    1231             : int nbio_id;
    1232             : 
    1233             : #define ival(s) strtol(s, NULL, 0)
    1234             : 
    1235             : /* run a test that simulates an approximate netbench client load */
    1236           0 : static bool run_netbench(int client)
    1237             : {
    1238           0 :         struct cli_state *cli;
    1239           0 :         int i;
    1240           0 :         char line[1024];
    1241           0 :         char cname[20];
    1242           0 :         FILE *f;
    1243           0 :         const char *params[20];
    1244           0 :         bool correct = True;
    1245             : 
    1246           0 :         cli = current_cli;
    1247             : 
    1248           0 :         nbio_id = client;
    1249             : 
    1250           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1251             : 
    1252           0 :         nb_setup(cli);
    1253             : 
    1254           0 :         slprintf(cname,sizeof(cname)-1, "client%d", client);
    1255             : 
    1256           0 :         f = fopen(client_txt, "r");
    1257             : 
    1258           0 :         if (!f) {
    1259           0 :                 perror(client_txt);
    1260           0 :                 return False;
    1261             :         }
    1262             : 
    1263           0 :         while (fgets(line, sizeof(line)-1, f)) {
    1264           0 :                 char *saveptr;
    1265           0 :                 line_count++;
    1266             : 
    1267           0 :                 line[strlen(line)-1] = 0;
    1268             : 
    1269             :                 /* printf("[%d] %s\n", line_count, line); */
    1270             : 
    1271           0 :                 all_string_sub(line,"client1", cname, sizeof(line));
    1272             : 
    1273             :                 /* parse the command parameters */
    1274           0 :                 params[0] = strtok_r(line, " ", &saveptr);
    1275           0 :                 i = 0;
    1276           0 :                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
    1277             : 
    1278           0 :                 params[i] = "";
    1279             : 
    1280           0 :                 if (i < 2) continue;
    1281             : 
    1282           0 :                 if (!strncmp(params[0],"SMB", 3)) {
    1283           0 :                         printf("ERROR: You are using a dbench 1 load file\n");
    1284           0 :                         exit(1);
    1285             :                 }
    1286             : 
    1287           0 :                 if (!strcmp(params[0],"NTCreateX")) {
    1288           0 :                         nb_createx(params[1], ival(params[2]), ival(params[3]),
    1289           0 :                                    ival(params[4]));
    1290           0 :                 } else if (!strcmp(params[0],"Close")) {
    1291           0 :                         nb_close(ival(params[1]));
    1292           0 :                 } else if (!strcmp(params[0],"Rename")) {
    1293           0 :                         nb_rename(params[1], params[2]);
    1294           0 :                 } else if (!strcmp(params[0],"Unlink")) {
    1295           0 :                         nb_unlink(params[1]);
    1296           0 :                 } else if (!strcmp(params[0],"Deltree")) {
    1297           0 :                         nb_deltree(params[1]);
    1298           0 :                 } else if (!strcmp(params[0],"Rmdir")) {
    1299           0 :                         nb_rmdir(params[1]);
    1300           0 :                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
    1301           0 :                         nb_qpathinfo(params[1]);
    1302           0 :                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
    1303           0 :                         nb_qfileinfo(ival(params[1]));
    1304           0 :                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
    1305           0 :                         nb_qfsinfo(ival(params[1]));
    1306           0 :                 } else if (!strcmp(params[0],"FIND_FIRST")) {
    1307           0 :                         nb_findfirst(params[1]);
    1308           0 :                 } else if (!strcmp(params[0],"WriteX")) {
    1309           0 :                         nb_writex(ival(params[1]),
    1310           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1311           0 :                 } else if (!strcmp(params[0],"ReadX")) {
    1312           0 :                         nb_readx(ival(params[1]),
    1313           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1314           0 :                 } else if (!strcmp(params[0],"Flush")) {
    1315           0 :                         nb_flush(ival(params[1]));
    1316             :                 } else {
    1317           0 :                         printf("Unknown operation %s\n", params[0]);
    1318           0 :                         exit(1);
    1319             :                 }
    1320             :         }
    1321           0 :         fclose(f);
    1322             : 
    1323           0 :         nb_cleanup();
    1324             : 
    1325           0 :         if (!torture_close_connection(cli)) {
    1326           0 :                 correct = False;
    1327             :         }
    1328             : 
    1329           0 :         return correct;
    1330             : }
    1331             : 
    1332             : 
    1333             : /* run a test that simulates an approximate netbench client load */
    1334           0 : static bool run_nbench(int dummy)
    1335             : {
    1336           0 :         double t;
    1337           0 :         bool correct = True;
    1338             : 
    1339           0 :         nbio_shmem(torture_nprocs);
    1340             : 
    1341           0 :         nbio_id = -1;
    1342             : 
    1343           0 :         signal(SIGALRM, nb_alarm);
    1344           0 :         alarm(1);
    1345           0 :         t = create_procs(run_netbench, &correct);
    1346           0 :         alarm(0);
    1347             : 
    1348           0 :         printf("\nThroughput %g MB/sec\n",
    1349           0 :                1.0e-6 * nbio_total() / t);
    1350           0 :         return correct;
    1351             : }
    1352             : 
    1353             : 
    1354             : /*
    1355             :   This test checks for two things:
    1356             : 
    1357             :   1) correct support for retaining locks over a close (ie. the server
    1358             :      must not use posix semantics)
    1359             :   2) support for lock timeouts
    1360             :  */
    1361           5 : static bool run_locktest1(int dummy)
    1362             : {
    1363           0 :         struct cli_state *cli1, *cli2;
    1364           5 :         const char *fname = "\\lockt1.lck";
    1365           0 :         uint16_t fnum1, fnum2, fnum3;
    1366           0 :         time_t t1, t2;
    1367           0 :         unsigned lock_timeout;
    1368           0 :         NTSTATUS status;
    1369             : 
    1370           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1371           0 :                 return False;
    1372             :         }
    1373           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1374           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1375             : 
    1376           5 :         printf("starting locktest1\n");
    1377             : 
    1378           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1379             : 
    1380           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1381             :                           &fnum1);
    1382           5 :         if (!NT_STATUS_IS_OK(status)) {
    1383           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1384           0 :                 return False;
    1385             :         }
    1386             : 
    1387           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
    1388           5 :         if (!NT_STATUS_IS_OK(status)) {
    1389           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1390           0 :                 return False;
    1391             :         }
    1392             : 
    1393           5 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
    1394           5 :         if (!NT_STATUS_IS_OK(status)) {
    1395           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1396           0 :                 return False;
    1397             :         }
    1398             : 
    1399           5 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    1400           5 :         if (!NT_STATUS_IS_OK(status)) {
    1401           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1402           0 :                 return false;
    1403             :         }
    1404             : 
    1405           5 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1406           5 :         if (NT_STATUS_IS_OK(status)) {
    1407           0 :                 printf("lock2 succeeded! This is a locking bug\n");
    1408           0 :                 return false;
    1409             :         } else {
    1410           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1411           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1412           0 :                         return false;
    1413             :                 }
    1414             :         }
    1415             : 
    1416           5 :         lock_timeout = (1 + (random() % 20));
    1417           5 :         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
    1418           5 :         t1 = time(NULL);
    1419           5 :         status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
    1420           5 :         if (NT_STATUS_IS_OK(status)) {
    1421           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1422           0 :                 return false;
    1423             :         } else {
    1424           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1425           5 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1426           0 :                         return false;
    1427             :                 }
    1428             :         }
    1429           5 :         t2 = time(NULL);
    1430             : 
    1431           5 :         if (ABS(t2 - t1) < lock_timeout-1) {
    1432           0 :                 printf("error: This server appears not to support timed lock requests\n");
    1433             :         }
    1434             : 
    1435           5 :         printf("server slept for %u seconds for a %u second timeout\n",
    1436             :                (unsigned int)(t2-t1), lock_timeout);
    1437             : 
    1438           5 :         status = cli_close(cli1, fnum2);
    1439           5 :         if (!NT_STATUS_IS_OK(status)) {
    1440           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1441           0 :                 return False;
    1442             :         }
    1443             : 
    1444           5 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1445           5 :         if (NT_STATUS_IS_OK(status)) {
    1446           0 :                 printf("lock4 succeeded! This is a locking bug\n");
    1447           0 :                 return false;
    1448             :         } else {
    1449           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1450           5 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1451           0 :                         return false;
    1452             :                 }
    1453             :         }
    1454             : 
    1455           5 :         status = cli_close(cli1, fnum1);
    1456           5 :         if (!NT_STATUS_IS_OK(status)) {
    1457           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1458           0 :                 return False;
    1459             :         }
    1460             : 
    1461           5 :         status = cli_close(cli2, fnum3);
    1462           5 :         if (!NT_STATUS_IS_OK(status)) {
    1463           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1464           0 :                 return False;
    1465             :         }
    1466             : 
    1467           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1468           5 :         if (!NT_STATUS_IS_OK(status)) {
    1469           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1470           0 :                 return False;
    1471             :         }
    1472             : 
    1473             : 
    1474           5 :         if (!torture_close_connection(cli1)) {
    1475           0 :                 return False;
    1476             :         }
    1477             : 
    1478           5 :         if (!torture_close_connection(cli2)) {
    1479           0 :                 return False;
    1480             :         }
    1481             : 
    1482           5 :         printf("Passed locktest1\n");
    1483           5 :         return True;
    1484             : }
    1485             : 
    1486             : /*
    1487             :   this checks to see if a secondary tconx can use open files from an
    1488             :   earlier tconx
    1489             :  */
    1490           5 : static bool run_tcon_test(int dummy)
    1491             : {
    1492           0 :         static struct cli_state *cli;
    1493           5 :         const char *fname = "\\tcontest.tmp";
    1494           0 :         uint16_t fnum1;
    1495           0 :         uint32_t cnum1, cnum2, cnum3;
    1496           5 :         struct smbXcli_tcon *orig_tcon = NULL;
    1497           5 :         char *orig_share = NULL;
    1498           0 :         uint16_t vuid1, vuid2;
    1499           0 :         char buf[4];
    1500           5 :         bool ret = True;
    1501           0 :         NTSTATUS status;
    1502             : 
    1503           5 :         memset(buf, '\0', sizeof(buf));
    1504             : 
    1505           5 :         if (!torture_open_connection(&cli, 0)) {
    1506           0 :                 return False;
    1507             :         }
    1508           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1509             : 
    1510           5 :         printf("starting tcontest\n");
    1511             : 
    1512           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1513             : 
    1514           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1515           5 :         if (!NT_STATUS_IS_OK(status)) {
    1516           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1517           0 :                 return False;
    1518             :         }
    1519             : 
    1520           5 :         cnum1 = cli_state_get_tid(cli);
    1521           5 :         vuid1 = cli_state_get_uid(cli);
    1522             : 
    1523           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1524           5 :         if (!NT_STATUS_IS_OK(status)) {
    1525           0 :                 printf("initial write failed (%s)", nt_errstr(status));
    1526           0 :                 return False;
    1527             :         }
    1528             : 
    1529           5 :         cli_state_save_tcon_share(cli, &orig_tcon, &orig_share);
    1530             : 
    1531           5 :         status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
    1532           5 :         if (!NT_STATUS_IS_OK(status)) {
    1533           0 :                 printf("%s refused 2nd tree connect (%s)\n", host,
    1534             :                        nt_errstr(status));
    1535           0 :                 cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1536           0 :                 cli_shutdown(cli);
    1537           0 :                 return False;
    1538             :         }
    1539             : 
    1540           5 :         cnum2 = cli_state_get_tid(cli);
    1541           5 :         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
    1542           5 :         vuid2 = cli_state_get_uid(cli) + 1;
    1543             : 
    1544             :         /* try a write with the wrong tid */
    1545           5 :         cli_state_set_tid(cli, cnum2);
    1546             : 
    1547           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1548           5 :         if (NT_STATUS_IS_OK(status)) {
    1549           0 :                 printf("* server allows write with wrong TID\n");
    1550           0 :                 ret = False;
    1551             :         } else {
    1552           5 :                 printf("server fails write with wrong TID : %s\n",
    1553             :                        nt_errstr(status));
    1554             :         }
    1555             : 
    1556             : 
    1557             :         /* try a write with an invalid tid */
    1558           5 :         cli_state_set_tid(cli, cnum3);
    1559             : 
    1560           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1561           5 :         if (NT_STATUS_IS_OK(status)) {
    1562           0 :                 printf("* server allows write with invalid TID\n");
    1563           0 :                 ret = False;
    1564             :         } else {
    1565           5 :                 printf("server fails write with invalid TID : %s\n",
    1566             :                        nt_errstr(status));
    1567             :         }
    1568             : 
    1569             :         /* try a write with an invalid vuid */
    1570           5 :         cli_state_set_uid(cli, vuid2);
    1571           5 :         cli_state_set_tid(cli, cnum1);
    1572             : 
    1573           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1574           5 :         if (NT_STATUS_IS_OK(status)) {
    1575           0 :                 printf("* server allows write with invalid VUID\n");
    1576           0 :                 ret = False;
    1577             :         } else {
    1578           5 :                 printf("server fails write with invalid VUID : %s\n",
    1579             :                        nt_errstr(status));
    1580             :         }
    1581             : 
    1582           5 :         cli_state_set_tid(cli, cnum1);
    1583           5 :         cli_state_set_uid(cli, vuid1);
    1584             : 
    1585           5 :         status = cli_close(cli, fnum1);
    1586           5 :         if (!NT_STATUS_IS_OK(status)) {
    1587           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1588           0 :                 cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1589           0 :                 cli_shutdown(cli);
    1590           0 :                 return False;
    1591             :         }
    1592             : 
    1593           5 :         cli_state_set_tid(cli, cnum2);
    1594             : 
    1595           5 :         status = cli_tdis(cli);
    1596           5 :         if (!NT_STATUS_IS_OK(status)) {
    1597           0 :                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
    1598           0 :                 cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1599           0 :                 cli_shutdown(cli);
    1600           0 :                 return False;
    1601             :         }
    1602             : 
    1603           5 :         cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
    1604             : 
    1605           5 :         cli_state_set_tid(cli, cnum1);
    1606             : 
    1607           5 :         if (!torture_close_connection(cli)) {
    1608           0 :                 return False;
    1609             :         }
    1610             : 
    1611           5 :         return ret;
    1612             : }
    1613             : 
    1614             : 
    1615             : /*
    1616             :  checks for old style tcon support
    1617             :  */
    1618           5 : static bool run_tcon2_test(int dummy)
    1619             : {
    1620           0 :         static struct cli_state *cli;
    1621           0 :         uint16_t cnum, max_xmit;
    1622           0 :         char *service;
    1623           0 :         NTSTATUS status;
    1624             : 
    1625           5 :         if (!torture_open_connection(&cli, 0)) {
    1626           0 :                 return False;
    1627             :         }
    1628           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1629             : 
    1630           5 :         printf("starting tcon2 test\n");
    1631             : 
    1632           5 :         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
    1633           0 :                 return false;
    1634             :         }
    1635             : 
    1636           5 :         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
    1637             : 
    1638           5 :         SAFE_FREE(service);
    1639             : 
    1640           5 :         if (!NT_STATUS_IS_OK(status)) {
    1641           5 :                 printf("tcon2 failed : %s\n", nt_errstr(status));
    1642             :         } else {
    1643           0 :                 printf("tcon OK : max_xmit=%d cnum=%d\n",
    1644             :                        (int)max_xmit, (int)cnum);
    1645             :         }
    1646             : 
    1647           5 :         if (!torture_close_connection(cli)) {
    1648           0 :                 return False;
    1649             :         }
    1650             : 
    1651           5 :         printf("Passed tcon2 test\n");
    1652           5 :         return True;
    1653             : }
    1654             : 
    1655          50 : static bool tcon_devtest(struct cli_state *cli,
    1656             :                          const char *myshare, const char *devtype,
    1657             :                          const char *return_devtype,
    1658             :                          NTSTATUS expected_error)
    1659             : {
    1660           0 :         NTSTATUS status;
    1661           0 :         bool ret;
    1662             : 
    1663          50 :         status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
    1664             : 
    1665          50 :         if (NT_STATUS_IS_OK(expected_error)) {
    1666          20 :                 if (NT_STATUS_IS_OK(status)) {
    1667          40 :                         if (return_devtype != NULL &&
    1668          20 :                             strequal(cli->dev, return_devtype)) {
    1669          20 :                                 ret = True;
    1670             :                         } else {
    1671           0 :                                 printf("tconX to share %s with type %s "
    1672             :                                        "succeeded but returned the wrong "
    1673             :                                        "device type (got [%s] but should have got [%s])\n",
    1674             :                                        myshare, devtype, cli->dev, return_devtype);
    1675           0 :                                 ret = False;
    1676             :                         }
    1677             :                 } else {
    1678           0 :                         printf("tconX to share %s with type %s "
    1679             :                                "should have succeeded but failed\n",
    1680             :                                myshare, devtype);
    1681           0 :                         ret = False;
    1682             :                 }
    1683          20 :                 cli_tdis(cli);
    1684             :         } else {
    1685          30 :                 if (NT_STATUS_IS_OK(status)) {
    1686           0 :                         printf("tconx to share %s with type %s "
    1687             :                                "should have failed but succeeded\n",
    1688             :                                myshare, devtype);
    1689           0 :                         ret = False;
    1690             :                 } else {
    1691          30 :                         if (NT_STATUS_EQUAL(status, expected_error)) {
    1692          30 :                                 ret = True;
    1693             :                         } else {
    1694           0 :                                 printf("Returned unexpected error\n");
    1695           0 :                                 ret = False;
    1696             :                         }
    1697             :                 }
    1698             :         }
    1699          50 :         return ret;
    1700             : }
    1701             : 
    1702             : /*
    1703             :  checks for correct tconX support
    1704             :  */
    1705           5 : static bool run_tcon_devtype_test(int dummy)
    1706             : {
    1707           0 :         static struct cli_state *cli1 = NULL;
    1708           5 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
    1709           0 :         NTSTATUS status;
    1710           5 :         bool ret = True;
    1711             : 
    1712           5 :         status = cli_full_connection_creds(NULL,
    1713             :                                            &cli1,
    1714             :                                            myname,
    1715             :                                            host,
    1716             :                                            NULL, /* dest_ss */
    1717             :                                            port_to_use,
    1718             :                                            NULL, /* service */
    1719             :                                            NULL, /* service_type */
    1720             :                                            torture_creds,
    1721             :                                            flags);
    1722             : 
    1723           5 :         if (!NT_STATUS_IS_OK(status)) {
    1724           0 :                 printf("could not open connection\n");
    1725           0 :                 return False;
    1726             :         }
    1727             : 
    1728           5 :         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1729           0 :                 ret = False;
    1730             : 
    1731           5 :         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
    1732           0 :                 ret = False;
    1733             : 
    1734           5 :         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1735           0 :                 ret = False;
    1736             : 
    1737           5 :         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
    1738           0 :                 ret = False;
    1739             : 
    1740           5 :         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1741           0 :                 ret = False;
    1742             : 
    1743           5 :         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
    1744           0 :                 ret = False;
    1745             : 
    1746           5 :         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
    1747           0 :                 ret = False;
    1748             : 
    1749           5 :         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1750           0 :                 ret = False;
    1751             : 
    1752           5 :         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1753           0 :                 ret = False;
    1754             : 
    1755           5 :         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1756           0 :                 ret = False;
    1757             : 
    1758           5 :         cli_shutdown(cli1);
    1759             : 
    1760           5 :         if (ret)
    1761           5 :                 printf("Passed tcondevtest\n");
    1762             : 
    1763           5 :         return ret;
    1764             : }
    1765             : 
    1766             : 
    1767             : /*
    1768             :   This test checks that
    1769             : 
    1770             :   1) the server supports multiple locking contexts on the one SMB
    1771             :   connection, distinguished by PID.
    1772             : 
    1773             :   2) the server correctly fails overlapping locks made by the same PID (this
    1774             :      goes against POSIX behaviour, which is why it is tricky to implement)
    1775             : 
    1776             :   3) the server denies unlock requests by an incorrect client PID
    1777             : */
    1778           5 : static bool run_locktest2(int dummy)
    1779             : {
    1780           0 :         static struct cli_state *cli;
    1781           5 :         const char *fname = "\\lockt2.lck";
    1782           0 :         uint16_t fnum1, fnum2, fnum3;
    1783           5 :         bool correct = True;
    1784           0 :         NTSTATUS status;
    1785             : 
    1786           5 :         if (!torture_open_connection(&cli, 0)) {
    1787           0 :                 return False;
    1788             :         }
    1789             : 
    1790           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1791             : 
    1792           5 :         printf("starting locktest2\n");
    1793             : 
    1794           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1795             : 
    1796           5 :         cli_setpid(cli, 1);
    1797             : 
    1798           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1799           5 :         if (!NT_STATUS_IS_OK(status)) {
    1800           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1801           0 :                 return False;
    1802             :         }
    1803             : 
    1804           5 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
    1805           5 :         if (!NT_STATUS_IS_OK(status)) {
    1806           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1807           0 :                 return False;
    1808             :         }
    1809             : 
    1810           5 :         cli_setpid(cli, 2);
    1811             : 
    1812           5 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
    1813           5 :         if (!NT_STATUS_IS_OK(status)) {
    1814           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1815           0 :                 return False;
    1816             :         }
    1817             : 
    1818           5 :         cli_setpid(cli, 1);
    1819             : 
    1820           5 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1821           5 :         if (!NT_STATUS_IS_OK(status)) {
    1822           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1823           0 :                 return false;
    1824             :         }
    1825             : 
    1826           5 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1827           5 :         if (NT_STATUS_IS_OK(status)) {
    1828           0 :                 printf("WRITE lock1 succeeded! This is a locking bug\n");
    1829           0 :                 correct = false;
    1830             :         } else {
    1831           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1832           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1833           0 :                         return false;
    1834             :                 }
    1835             :         }
    1836             : 
    1837           5 :         status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
    1838           5 :         if (NT_STATUS_IS_OK(status)) {
    1839           0 :                 printf("WRITE lock2 succeeded! This is a locking bug\n");
    1840           0 :                 correct = false;
    1841             :         } else {
    1842           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1843           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1844           0 :                         return false;
    1845             :                 }
    1846             :         }
    1847             : 
    1848           5 :         status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
    1849           5 :         if (NT_STATUS_IS_OK(status)) {
    1850           0 :                 printf("READ lock2 succeeded! This is a locking bug\n");
    1851           0 :                 correct = false;
    1852             :         } else {
    1853           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1854           5 :                                  NT_STATUS_FILE_LOCK_CONFLICT)) {
    1855           0 :                         return false;
    1856             :                 }
    1857             :         }
    1858             : 
    1859           5 :         status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
    1860           5 :         if (!NT_STATUS_IS_OK(status)) {
    1861           0 :                 printf("lock at 100 failed (%s)\n", nt_errstr(status));
    1862             :         }
    1863           5 :         cli_setpid(cli, 2);
    1864           5 :         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
    1865           0 :                 printf("unlock at 100 succeeded! This is a locking bug\n");
    1866           0 :                 correct = False;
    1867             :         }
    1868             : 
    1869           5 :         status = cli_unlock(cli, fnum1, 0, 4);
    1870           5 :         if (NT_STATUS_IS_OK(status)) {
    1871           0 :                 printf("unlock1 succeeded! This is a locking bug\n");
    1872           0 :                 correct = false;
    1873             :         } else {
    1874           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1875           5 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1876           0 :                         return false;
    1877             :                 }
    1878             :         }
    1879             : 
    1880           5 :         status = cli_unlock(cli, fnum1, 0, 8);
    1881           5 :         if (NT_STATUS_IS_OK(status)) {
    1882           0 :                 printf("unlock2 succeeded! This is a locking bug\n");
    1883           0 :                 correct = false;
    1884             :         } else {
    1885           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1886           5 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1887           0 :                         return false;
    1888             :                 }
    1889             :         }
    1890             : 
    1891           5 :         status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
    1892           5 :         if (NT_STATUS_IS_OK(status)) {
    1893           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1894           0 :                 correct = false;
    1895             :         } else {
    1896           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1897           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1898           0 :                         return false;
    1899             :                 }
    1900             :         }
    1901             : 
    1902           5 :         cli_setpid(cli, 1);
    1903             : 
    1904           5 :         status = cli_close(cli, fnum1);
    1905           5 :         if (!NT_STATUS_IS_OK(status)) {
    1906           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1907           0 :                 return False;
    1908             :         }
    1909             : 
    1910           5 :         status = cli_close(cli, fnum2);
    1911           5 :         if (!NT_STATUS_IS_OK(status)) {
    1912           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1913           0 :                 return False;
    1914             :         }
    1915             : 
    1916           5 :         status = cli_close(cli, fnum3);
    1917           5 :         if (!NT_STATUS_IS_OK(status)) {
    1918           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1919           0 :                 return False;
    1920             :         }
    1921             : 
    1922           5 :         if (!torture_close_connection(cli)) {
    1923           0 :                 correct = False;
    1924             :         }
    1925             : 
    1926           5 :         printf("locktest2 finished\n");
    1927             : 
    1928           5 :         return correct;
    1929             : }
    1930             : 
    1931             : 
    1932             : /*
    1933             :   This test checks that
    1934             : 
    1935             :   1) the server supports the full offset range in lock requests
    1936             : */
    1937           5 : static bool run_locktest3(int dummy)
    1938             : {
    1939           0 :         static struct cli_state *cli1, *cli2;
    1940           5 :         const char *fname = "\\lockt3.lck";
    1941           0 :         uint16_t fnum1, fnum2;
    1942           0 :         int i;
    1943           0 :         uint32_t offset;
    1944           5 :         bool correct = True;
    1945           0 :         NTSTATUS status;
    1946             : 
    1947             : #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
    1948             : 
    1949           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1950           0 :                 return False;
    1951             :         }
    1952           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1953           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1954             : 
    1955           5 :         printf("starting locktest3\n");
    1956             : 
    1957           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1958             : 
    1959           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1960             :                          &fnum1);
    1961           5 :         if (!NT_STATUS_IS_OK(status)) {
    1962           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1963           0 :                 return False;
    1964             :         }
    1965             : 
    1966           5 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    1967           5 :         if (!NT_STATUS_IS_OK(status)) {
    1968           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1969           0 :                 return False;
    1970             :         }
    1971             : 
    1972         505 :         for (offset=i=0;i<torture_numops;i++) {
    1973         500 :                 NEXT_OFFSET;
    1974             : 
    1975         500 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    1976         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1977           0 :                         printf("lock1 %d failed (%s)\n",
    1978             :                                i,
    1979             :                                nt_errstr(status));
    1980           0 :                         return False;
    1981             :                 }
    1982             : 
    1983         500 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    1984         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1985           0 :                         printf("lock2 %d failed (%s)\n",
    1986             :                                i,
    1987             :                                nt_errstr(status));
    1988           0 :                         return False;
    1989             :                 }
    1990             :         }
    1991             : 
    1992         505 :         for (offset=i=0;i<torture_numops;i++) {
    1993         500 :                 NEXT_OFFSET;
    1994             : 
    1995         500 :                 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
    1996         500 :                 if (NT_STATUS_IS_OK(status)) {
    1997           0 :                         printf("error: lock1 %d succeeded!\n", i);
    1998           0 :                         return False;
    1999             :                 }
    2000             : 
    2001         500 :                 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
    2002         500 :                 if (NT_STATUS_IS_OK(status)) {
    2003           0 :                         printf("error: lock2 %d succeeded!\n", i);
    2004           0 :                         return False;
    2005             :                 }
    2006             : 
    2007         500 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    2008         500 :                 if (NT_STATUS_IS_OK(status)) {
    2009           0 :                         printf("error: lock3 %d succeeded!\n", i);
    2010           0 :                         return False;
    2011             :                 }
    2012             : 
    2013         500 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    2014         500 :                 if (NT_STATUS_IS_OK(status)) {
    2015           0 :                         printf("error: lock4 %d succeeded!\n", i);
    2016           0 :                         return False;
    2017             :                 }
    2018             :         }
    2019             : 
    2020         505 :         for (offset=i=0;i<torture_numops;i++) {
    2021         500 :                 NEXT_OFFSET;
    2022             : 
    2023         500 :                 status = cli_unlock(cli1, fnum1, offset-1, 1);
    2024         500 :                 if (!NT_STATUS_IS_OK(status)) {
    2025           0 :                         printf("unlock1 %d failed (%s)\n",
    2026             :                                i,
    2027             :                                nt_errstr(status));
    2028           0 :                         return False;
    2029             :                 }
    2030             : 
    2031         500 :                 status = cli_unlock(cli2, fnum2, offset-2, 1);
    2032         500 :                 if (!NT_STATUS_IS_OK(status)) {
    2033           0 :                         printf("unlock2 %d failed (%s)\n",
    2034             :                                i,
    2035             :                                nt_errstr(status));
    2036           0 :                         return False;
    2037             :                 }
    2038             :         }
    2039             : 
    2040           5 :         status = cli_close(cli1, fnum1);
    2041           5 :         if (!NT_STATUS_IS_OK(status)) {
    2042           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    2043           0 :                 return False;
    2044             :         }
    2045             : 
    2046           5 :         status = cli_close(cli2, fnum2);
    2047           5 :         if (!NT_STATUS_IS_OK(status)) {
    2048           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    2049           0 :                 return False;
    2050             :         }
    2051             : 
    2052           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2053           5 :         if (!NT_STATUS_IS_OK(status)) {
    2054           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    2055           0 :                 return False;
    2056             :         }
    2057             : 
    2058           5 :         if (!torture_close_connection(cli1)) {
    2059           0 :                 correct = False;
    2060             :         }
    2061             : 
    2062           5 :         if (!torture_close_connection(cli2)) {
    2063           0 :                 correct = False;
    2064             :         }
    2065             : 
    2066           5 :         printf("finished locktest3\n");
    2067             : 
    2068           5 :         return correct;
    2069             : }
    2070             : 
    2071          40 : static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
    2072             :                            char *buf, off_t offset, size_t size,
    2073             :                            size_t *nread, size_t expect)
    2074             : {
    2075           0 :         NTSTATUS status;
    2076           0 :         size_t l_nread;
    2077             : 
    2078          40 :         status = cli_read(cli, fnum, buf, offset, size, &l_nread);
    2079             : 
    2080          40 :         if(!NT_STATUS_IS_OK(status)) {
    2081          20 :                 return false;
    2082          20 :         } else if (l_nread != expect) {
    2083           0 :                 return false;
    2084             :         }
    2085             : 
    2086          20 :         if (nread) {
    2087           0 :                 *nread = l_nread;
    2088             :         }
    2089             : 
    2090          20 :         return true;
    2091             : }
    2092             : 
    2093             : #define EXPECTED(ret, v) if ((ret) != (v)) { \
    2094             :         printf("** "); correct = False; \
    2095             :         }
    2096             : 
    2097             : /*
    2098             :   looks at overlapping locks
    2099             : */
    2100           5 : static bool run_locktest4(int dummy)
    2101             : {
    2102           0 :         static struct cli_state *cli1, *cli2;
    2103           5 :         const char *fname = "\\lockt4.lck";
    2104           0 :         uint16_t fnum1, fnum2, f;
    2105           0 :         bool ret;
    2106           0 :         char buf[1000];
    2107           5 :         bool correct = True;
    2108           0 :         NTSTATUS status;
    2109             : 
    2110           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    2111           0 :                 return False;
    2112             :         }
    2113             : 
    2114           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2115           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2116             : 
    2117           5 :         printf("starting locktest4\n");
    2118             : 
    2119           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2120             : 
    2121           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2122           5 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    2123             : 
    2124           5 :         memset(buf, 0, sizeof(buf));
    2125             : 
    2126           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2127             :                               NULL);
    2128           5 :         if (!NT_STATUS_IS_OK(status)) {
    2129           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2130           0 :                 correct = False;
    2131           0 :                 goto fail;
    2132             :         }
    2133             : 
    2134          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    2135           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
    2136           5 :         EXPECTED(ret, False);
    2137           5 :         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
    2138             : 
    2139          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
    2140           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
    2141           5 :         EXPECTED(ret, True);
    2142           5 :         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
    2143             : 
    2144          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
    2145           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
    2146           5 :         EXPECTED(ret, False);
    2147           5 :         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
    2148             : 
    2149          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
    2150           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
    2151           5 :         EXPECTED(ret, True);
    2152           5 :         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
    2153             : 
    2154           5 :         ret = (cli_setpid(cli1, 1),
    2155          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
    2156           5 :               (cli_setpid(cli1, 2),
    2157           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
    2158           5 :         EXPECTED(ret, False);
    2159           5 :         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
    2160             : 
    2161           5 :         ret = (cli_setpid(cli1, 1),
    2162          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
    2163           5 :               (cli_setpid(cli1, 2),
    2164           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
    2165           5 :         EXPECTED(ret, True);
    2166           5 :         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
    2167             : 
    2168          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
    2169           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
    2170           5 :         EXPECTED(ret, True);
    2171           5 :         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
    2172             : 
    2173          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
    2174           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
    2175           5 :         EXPECTED(ret, False);
    2176           5 :         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
    2177             : 
    2178          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
    2179           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
    2180           5 :         EXPECTED(ret, False);
    2181           5 :         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
    2182             : 
    2183          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
    2184           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
    2185           5 :         EXPECTED(ret, True);
    2186           5 :         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2187             : 
    2188           5 :         ret = (cli_setpid(cli1, 1),
    2189          10 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
    2190           5 :              (cli_setpid(cli1, 2),
    2191           5 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
    2192           5 :         EXPECTED(ret, False);
    2193           5 :         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2194             : 
    2195           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
    2196          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
    2197           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
    2198           5 :         EXPECTED(ret, False);
    2199           5 :         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
    2200             : 
    2201             : 
    2202          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
    2203           5 :               test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
    2204           5 :         EXPECTED(ret, False);
    2205           5 :         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
    2206             : 
    2207           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2208           5 :         ret = NT_STATUS_IS_OK(status);
    2209           5 :         if (ret) {
    2210           5 :                 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
    2211             :                                       NULL);
    2212           5 :                 ret = NT_STATUS_IS_OK(status);
    2213             :         }
    2214           5 :         EXPECTED(ret, False);
    2215           5 :         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
    2216             : 
    2217             : 
    2218           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2219           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2220          15 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
    2221           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
    2222           5 :         EXPECTED(ret, True);
    2223           5 :         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
    2224             : 
    2225             : 
    2226           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
    2227           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
    2228          10 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
    2229           5 :               test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
    2230           5 :               !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2231          10 :                                              150, 4, NULL))) &&
    2232           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
    2233           5 :         EXPECTED(ret, True);
    2234           5 :         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
    2235             : 
    2236           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
    2237           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
    2238           5 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2239          10 :                                            160, 4, NULL)) &&
    2240           5 :               test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
    2241           5 :         EXPECTED(ret, True);
    2242           5 :         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
    2243             : 
    2244           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
    2245           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
    2246           5 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2247          10 :                                            170, 4, NULL)) &&
    2248           5 :               test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
    2249           5 :         EXPECTED(ret, True);
    2250           5 :         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
    2251             : 
    2252           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
    2253           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
    2254           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
    2255           5 :               !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2256          10 :                                             190, 4, NULL)) &&
    2257           5 :               test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
    2258           5 :         EXPECTED(ret, True);
    2259           5 :         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
    2260             : 
    2261           5 :         cli_close(cli1, fnum1);
    2262           5 :         cli_close(cli2, fnum2);
    2263           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2264           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
    2265           5 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2266           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
    2267           5 :               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
    2268          15 :               NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
    2269           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
    2270           5 :         cli_close(cli1, f);
    2271           5 :         cli_close(cli1, fnum1);
    2272           5 :         EXPECTED(ret, True);
    2273           5 :         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
    2274             : 
    2275           5 :  fail:
    2276           5 :         cli_close(cli1, fnum1);
    2277           5 :         cli_close(cli2, fnum2);
    2278           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2279           5 :         torture_close_connection(cli1);
    2280           5 :         torture_close_connection(cli2);
    2281             : 
    2282           5 :         printf("finished locktest4\n");
    2283           5 :         return correct;
    2284             : }
    2285             : 
    2286             : /*
    2287             :   looks at lock upgrade/downgrade.
    2288             : */
    2289           5 : static bool run_locktest5(int dummy)
    2290             : {
    2291           0 :         static struct cli_state *cli1, *cli2;
    2292           5 :         const char *fname = "\\lockt5.lck";
    2293           0 :         uint16_t fnum1, fnum2, fnum3;
    2294           0 :         bool ret;
    2295           0 :         char buf[1000];
    2296           5 :         bool correct = True;
    2297           0 :         NTSTATUS status;
    2298             : 
    2299           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    2300           0 :                 return False;
    2301             :         }
    2302             : 
    2303           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2304           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2305             : 
    2306           5 :         printf("starting locktest5\n");
    2307             : 
    2308           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2309             : 
    2310           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2311           5 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    2312           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
    2313             : 
    2314           5 :         memset(buf, 0, sizeof(buf));
    2315             : 
    2316           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2317             :                               NULL);
    2318           5 :         if (!NT_STATUS_IS_OK(status)) {
    2319           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2320           0 :                 correct = False;
    2321           0 :                 goto fail;
    2322             :         }
    2323             : 
    2324             :         /* Check for NT bug... */
    2325          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2326           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
    2327           5 :         cli_close(cli1, fnum1);
    2328           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2329           5 :         status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
    2330           5 :         ret = NT_STATUS_IS_OK(status);
    2331           5 :         EXPECTED(ret, True);
    2332           5 :         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
    2333           5 :         cli_close(cli1, fnum1);
    2334           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2335           5 :         cli_unlock(cli1, fnum3, 0, 1);
    2336             : 
    2337          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    2338           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
    2339           5 :         EXPECTED(ret, True);
    2340           5 :         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
    2341             : 
    2342           5 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
    2343           5 :         ret = NT_STATUS_IS_OK(status);
    2344           5 :         EXPECTED(ret, False);
    2345             : 
    2346           5 :         printf("a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
    2347             : 
    2348             :         /* Unlock the process 2 lock. */
    2349           5 :         cli_unlock(cli2, fnum2, 0, 4);
    2350             : 
    2351           5 :         status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
    2352           5 :         ret = NT_STATUS_IS_OK(status);
    2353           5 :         EXPECTED(ret, False);
    2354             : 
    2355           5 :         printf("the same process on a different fnum %s get a read lock\n", ret?"can":"cannot");
    2356             : 
    2357             :         /* Unlock the process 1 fnum3 lock. */
    2358           5 :         cli_unlock(cli1, fnum3, 0, 4);
    2359             : 
    2360             :         /* Stack 2 more locks here. */
    2361          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
    2362           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
    2363             : 
    2364           5 :         EXPECTED(ret, True);
    2365           5 :         printf("the same process %s stack read locks\n", ret?"can":"cannot");
    2366             : 
    2367             :         /* Unlock the first process lock, then check this was the WRITE lock that was
    2368             :                 removed. */
    2369             : 
    2370          10 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2371           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
    2372             : 
    2373           5 :         EXPECTED(ret, True);
    2374           5 :         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
    2375             : 
    2376             :         /* Unlock the process 2 lock. */
    2377           5 :         cli_unlock(cli2, fnum2, 0, 4);
    2378             : 
    2379             :         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
    2380             : 
    2381           5 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
    2382          10 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2383           5 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2384             : 
    2385           5 :         EXPECTED(ret, True);
    2386           5 :         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
    2387             : 
    2388             :         /* Ensure the next unlock fails. */
    2389           5 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2390           5 :         EXPECTED(ret, False);
    2391           5 :         printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
    2392             : 
    2393             :         /* Ensure connection 2 can get a write lock. */
    2394           5 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
    2395           5 :         ret = NT_STATUS_IS_OK(status);
    2396           5 :         EXPECTED(ret, True);
    2397             : 
    2398           5 :         printf("a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
    2399             : 
    2400             : 
    2401           5 :  fail:
    2402           5 :         cli_close(cli1, fnum1);
    2403           5 :         cli_close(cli2, fnum2);
    2404           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2405           5 :         if (!torture_close_connection(cli1)) {
    2406           0 :                 correct = False;
    2407             :         }
    2408           5 :         if (!torture_close_connection(cli2)) {
    2409           0 :                 correct = False;
    2410             :         }
    2411             : 
    2412           5 :         printf("finished locktest5\n");
    2413             : 
    2414           5 :         return correct;
    2415             : }
    2416             : 
    2417             : /*
    2418             :   tries the unusual lockingX locktype bits
    2419             : */
    2420           5 : static bool run_locktest6(int dummy)
    2421             : {
    2422           0 :         static struct cli_state *cli;
    2423           5 :         const char *fname[1] = { "\\lock6.txt" };
    2424           0 :         int i;
    2425           0 :         uint16_t fnum;
    2426           0 :         NTSTATUS status;
    2427             : 
    2428           5 :         if (!torture_open_connection(&cli, 0)) {
    2429           0 :                 return False;
    2430             :         }
    2431             : 
    2432           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    2433             : 
    2434           5 :         printf("starting locktest6\n");
    2435             : 
    2436          10 :         for (i=0;i<1;i++) {
    2437           5 :                 printf("Testing %s\n", fname[i]);
    2438             : 
    2439           5 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2440             : 
    2441           5 :                 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    2442           5 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
    2443           5 :                 cli_close(cli, fnum);
    2444           5 :                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
    2445             : 
    2446           5 :                 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
    2447           5 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
    2448           5 :                 cli_close(cli, fnum);
    2449           5 :                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
    2450             : 
    2451           5 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2452             :         }
    2453             : 
    2454           5 :         torture_close_connection(cli);
    2455             : 
    2456           5 :         printf("finished locktest6\n");
    2457           5 :         return True;
    2458             : }
    2459             : 
    2460           5 : static bool run_locktest7(int dummy)
    2461             : {
    2462           0 :         struct cli_state *cli1;
    2463           5 :         const char *fname = "\\lockt7.lck";
    2464           0 :         uint16_t fnum1;
    2465           0 :         char buf[200];
    2466           5 :         bool correct = False;
    2467           0 :         size_t nread;
    2468           0 :         NTSTATUS status;
    2469             : 
    2470           5 :         if (!torture_open_connection(&cli1, 0)) {
    2471           0 :                 return False;
    2472             :         }
    2473             : 
    2474           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2475             : 
    2476           5 :         printf("starting locktest7\n");
    2477             : 
    2478           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2479             : 
    2480           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2481             : 
    2482           5 :         memset(buf, 0, sizeof(buf));
    2483             : 
    2484           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2485             :                               NULL);
    2486           5 :         if (!NT_STATUS_IS_OK(status)) {
    2487           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2488           0 :                 goto fail;
    2489             :         }
    2490             : 
    2491           5 :         cli_setpid(cli1, 1);
    2492             : 
    2493           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2494           5 :         if (!NT_STATUS_IS_OK(status)) {
    2495           0 :                 printf("Unable to apply read lock on range 130:4, "
    2496             :                        "error was %s\n", nt_errstr(status));
    2497           0 :                 goto fail;
    2498             :         } else {
    2499           5 :                 printf("pid1 successfully locked range 130:4 for READ\n");
    2500             :         }
    2501             : 
    2502           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2503           5 :         if (!NT_STATUS_IS_OK(status)) {
    2504           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2505             :                       nt_errstr(status));
    2506           0 :                 goto fail;
    2507           5 :         } else if (nread != 4) {
    2508           0 :                 printf("pid1 unable to read the range 130:4, "
    2509             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2510           0 :                 goto fail;
    2511             :         } else {
    2512           5 :                 printf("pid1 successfully read the range 130:4\n");
    2513             :         }
    2514             : 
    2515           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2516           5 :         if (!NT_STATUS_IS_OK(status)) {
    2517           5 :                 printf("pid1 unable to write to the range 130:4, error was "
    2518             :                        "%s\n", nt_errstr(status));
    2519           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2520           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2521           0 :                         goto fail;
    2522             :                 }
    2523             :         } else {
    2524           0 :                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
    2525           0 :                 goto fail;
    2526             :         }
    2527             : 
    2528           5 :         cli_setpid(cli1, 2);
    2529             : 
    2530           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2531           5 :         if (!NT_STATUS_IS_OK(status)) {
    2532           0 :                 printf("pid2 unable to read the range 130:4, error was %s\n",
    2533             :                       nt_errstr(status));
    2534           0 :                 goto fail;
    2535           5 :         } else if (nread != 4) {
    2536           0 :                 printf("pid2 unable to read the range 130:4, "
    2537             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2538           0 :                 goto fail;
    2539             :         } else {
    2540           5 :                 printf("pid2 successfully read the range 130:4\n");
    2541             :         }
    2542             : 
    2543           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2544           5 :         if (!NT_STATUS_IS_OK(status)) {
    2545           5 :                 printf("pid2 unable to write to the range 130:4, error was "
    2546             :                        "%s\n", nt_errstr(status));
    2547           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2548           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2549           0 :                         goto fail;
    2550             :                 }
    2551             :         } else {
    2552           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2553           0 :                 goto fail;
    2554             :         }
    2555             : 
    2556           5 :         cli_setpid(cli1, 1);
    2557           5 :         cli_unlock(cli1, fnum1, 130, 4);
    2558             : 
    2559           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
    2560           5 :         if (!NT_STATUS_IS_OK(status)) {
    2561           0 :                 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
    2562           0 :                 goto fail;
    2563             :         } else {
    2564           5 :                 printf("pid1 successfully locked range 130:4 for WRITE\n");
    2565             :         }
    2566             : 
    2567           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2568           5 :         if (!NT_STATUS_IS_OK(status)) {
    2569           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2570             :                       nt_errstr(status));
    2571           0 :                 goto fail;
    2572           5 :         } else if (nread != 4) {
    2573           0 :                 printf("pid1 unable to read the range 130:4, "
    2574             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2575           0 :                 goto fail;
    2576             :         } else {
    2577           5 :                 printf("pid1 successfully read the range 130:4\n");
    2578             :         }
    2579             : 
    2580           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2581           5 :         if (!NT_STATUS_IS_OK(status)) {
    2582           0 :                 printf("pid1 unable to write to the range 130:4, error was "
    2583             :                        "%s\n", nt_errstr(status));
    2584           0 :                 goto fail;
    2585             :         } else {
    2586           5 :                 printf("pid1 successfully wrote to the range 130:4\n");
    2587             :         }
    2588             : 
    2589           5 :         cli_setpid(cli1, 2);
    2590             : 
    2591           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2592           5 :         if (!NT_STATUS_IS_OK(status)) {
    2593           5 :                 printf("pid2 unable to read the range 130:4, error was "
    2594             :                        "%s\n", nt_errstr(status));
    2595           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2596           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2597           0 :                         goto fail;
    2598             :                 }
    2599             :         } else {
    2600           0 :                 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
    2601             :                        (unsigned long)nread);
    2602           0 :                 goto fail;
    2603             :         }
    2604             : 
    2605           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2606           5 :         if (!NT_STATUS_IS_OK(status)) {
    2607           5 :                 printf("pid2 unable to write to the range 130:4, error was "
    2608             :                        "%s\n", nt_errstr(status));
    2609           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2610           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2611           0 :                         goto fail;
    2612             :                 }
    2613             :         } else {
    2614           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2615           0 :                 goto fail;
    2616             :         }
    2617             : 
    2618           5 :         cli_unlock(cli1, fnum1, 130, 0);
    2619           5 :         correct = True;
    2620             : 
    2621           5 : fail:
    2622           5 :         cli_close(cli1, fnum1);
    2623           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2624           5 :         torture_close_connection(cli1);
    2625             : 
    2626           5 :         printf("finished locktest7\n");
    2627           5 :         return correct;
    2628             : }
    2629             : 
    2630             : /*
    2631             :  * This demonstrates a problem with our use of GPFS share modes: A file
    2632             :  * descriptor sitting in the pending close queue holding a GPFS share mode
    2633             :  * blocks opening a file another time. Happens with Word 2007 temp files.
    2634             :  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
    2635             :  * open is denied with NT_STATUS_SHARING_VIOLATION.
    2636             :  */
    2637             : 
    2638           0 : static bool run_locktest8(int dummy)
    2639             : {
    2640           0 :         struct cli_state *cli1;
    2641           0 :         const char *fname = "\\lockt8.lck";
    2642           0 :         uint16_t fnum1, fnum2;
    2643           0 :         char buf[200];
    2644           0 :         bool correct = False;
    2645           0 :         NTSTATUS status;
    2646             : 
    2647           0 :         if (!torture_open_connection(&cli1, 0)) {
    2648           0 :                 return False;
    2649             :         }
    2650             : 
    2651           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2652             : 
    2653           0 :         printf("starting locktest8\n");
    2654             : 
    2655           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2656             : 
    2657           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
    2658             :                           &fnum1);
    2659           0 :         if (!NT_STATUS_IS_OK(status)) {
    2660           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2661           0 :                 return false;
    2662             :         }
    2663             : 
    2664           0 :         memset(buf, 0, sizeof(buf));
    2665             : 
    2666           0 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
    2667           0 :         if (!NT_STATUS_IS_OK(status)) {
    2668           0 :                 d_fprintf(stderr, "cli_openx second time returned %s\n",
    2669             :                           nt_errstr(status));
    2670           0 :                 goto fail;
    2671             :         }
    2672             : 
    2673           0 :         status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
    2674           0 :         if (!NT_STATUS_IS_OK(status)) {
    2675           0 :                 printf("Unable to apply read lock on range 1:1, error was "
    2676             :                        "%s\n", nt_errstr(status));
    2677           0 :                 goto fail;
    2678             :         }
    2679             : 
    2680           0 :         status = cli_close(cli1, fnum1);
    2681           0 :         if (!NT_STATUS_IS_OK(status)) {
    2682           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2683           0 :                 goto fail;
    2684             :         }
    2685             : 
    2686           0 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2687           0 :         if (!NT_STATUS_IS_OK(status)) {
    2688           0 :                 d_fprintf(stderr, "cli_openx third time returned %s\n",
    2689             :                           nt_errstr(status));
    2690           0 :                 goto fail;
    2691             :         }
    2692             : 
    2693           0 :         correct = true;
    2694             : 
    2695           0 : fail:
    2696           0 :         cli_close(cli1, fnum1);
    2697           0 :         cli_close(cli1, fnum2);
    2698           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2699           0 :         torture_close_connection(cli1);
    2700             : 
    2701           0 :         printf("finished locktest8\n");
    2702           0 :         return correct;
    2703             : }
    2704             : 
    2705             : /*
    2706             :  * This test is designed to be run in conjunction with
    2707             :  * external NFS or POSIX locks taken in the filesystem.
    2708             :  * It checks that the smbd server will block until the
    2709             :  * lock is released and then acquire it. JRA.
    2710             :  */
    2711             : 
    2712             : static bool got_alarm;
    2713             : static struct cli_state *alarm_cli;
    2714             : 
    2715           0 : static void alarm_handler(int dummy)
    2716             : {
    2717           0 :         got_alarm = True;
    2718           0 : }
    2719             : 
    2720           0 : static void alarm_handler_parent(int dummy)
    2721             : {
    2722           0 :         smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_LOCAL_DISCONNECT);
    2723           0 : }
    2724             : 
    2725           8 : static void do_local_lock(const char *fname, int read_fd, int write_fd)
    2726             : {
    2727           0 :         int fd;
    2728           8 :         char c = '\0';
    2729           0 :         struct flock lock;
    2730           8 :         const char *local_pathname = NULL;
    2731           0 :         int ret;
    2732             : 
    2733           8 :         local_pathname = talloc_asprintf(talloc_tos(),
    2734             :                         "%s/%s", local_path, fname);
    2735           8 :         if (!local_pathname) {
    2736           0 :                 printf("child: alloc fail\n");
    2737           0 :                 exit(1);
    2738             :         }
    2739             : 
    2740           8 :         unlink(local_pathname);
    2741           8 :         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
    2742           8 :         if (fd == -1) {
    2743           0 :                 printf("child: open of %s failed %s.\n",
    2744           0 :                         local_pathname, strerror(errno));
    2745           0 :                 exit(1);
    2746             :         }
    2747             : 
    2748             :         /* Now take a fcntl lock. */
    2749           8 :         lock.l_type = F_WRLCK;
    2750           8 :         lock.l_whence = SEEK_SET;
    2751           8 :         lock.l_start = 0;
    2752           8 :         lock.l_len = 4;
    2753           8 :         lock.l_pid = getpid();
    2754             : 
    2755           8 :         ret = fcntl(fd,F_SETLK,&lock);
    2756           8 :         if (ret == -1) {
    2757           0 :                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
    2758           0 :                         local_pathname, strerror(errno));
    2759           0 :                 exit(1);
    2760             :         } else {
    2761           8 :                 printf("child: got lock 0:4 on file %s.\n",
    2762             :                         local_pathname );
    2763           8 :                 fflush(stdout);
    2764             :         }
    2765             : 
    2766           8 :         CatchSignal(SIGALRM, alarm_handler);
    2767           8 :         alarm(5);
    2768             :         /* Signal the parent. */
    2769           8 :         if (write(write_fd, &c, 1) != 1) {
    2770           0 :                 printf("child: start signal fail %s.\n",
    2771           0 :                         strerror(errno));
    2772           0 :                 exit(1);
    2773             :         }
    2774           8 :         alarm(0);
    2775             : 
    2776           8 :         alarm(10);
    2777             :         /* Wait for the parent to be ready. */
    2778           8 :         if (read(read_fd, &c, 1) != 1) {
    2779           0 :                 printf("child: reply signal fail %s.\n",
    2780           0 :                         strerror(errno));
    2781           0 :                 exit(1);
    2782             :         }
    2783           8 :         alarm(0);
    2784             : 
    2785           8 :         sleep(5);
    2786           8 :         close(fd);
    2787           8 :         printf("child: released lock 0:4 on file %s.\n",
    2788             :                 local_pathname );
    2789           8 :         fflush(stdout);
    2790           8 :         exit(0);
    2791             : }
    2792             : 
    2793           8 : static bool _run_locktest9X(const char *fname, int timeout)
    2794             : {
    2795           0 :         struct cli_state *cli1;
    2796           8 :         char *fpath = talloc_asprintf(talloc_tos(), "\\%s", fname);
    2797           0 :         uint16_t fnum;
    2798           8 :         bool correct = False;
    2799           0 :         int pipe_in[2], pipe_out[2];
    2800           0 :         pid_t child_pid;
    2801           8 :         char c = '\0';
    2802           0 :         int ret;
    2803           0 :         struct timeval start;
    2804           0 :         double seconds;
    2805           0 :         NTSTATUS status;
    2806             : 
    2807           8 :         printf("starting locktest9X: %s\n", fname);
    2808             : 
    2809           8 :         if (local_path == NULL) {
    2810           0 :                 d_fprintf(stderr, "locktest9X must be given a local path via -l <localpath>\n");
    2811           0 :                 return false;
    2812             :         }
    2813             : 
    2814           8 :         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
    2815           0 :                 return false;
    2816             :         }
    2817             : 
    2818           8 :         child_pid = fork();
    2819          16 :         if (child_pid == -1) {
    2820           0 :                 return false;
    2821             :         }
    2822             : 
    2823          16 :         if (child_pid == 0) {
    2824             :                 /* Child. */
    2825           8 :                 do_local_lock(fname, pipe_out[0], pipe_in[1]);
    2826           0 :                 exit(0);
    2827             :         }
    2828             : 
    2829           8 :         close(pipe_out[0]);
    2830           8 :         close(pipe_in[1]);
    2831           8 :         pipe_out[0] = -1;
    2832           8 :         pipe_in[1] = -1;
    2833             : 
    2834             :         /* Parent. */
    2835           8 :         ret = read(pipe_in[0], &c, 1);
    2836           8 :         if (ret != 1) {
    2837           0 :                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
    2838           0 :                         strerror(errno));
    2839           0 :                 return false;
    2840             :         }
    2841             : 
    2842           8 :         if (!torture_open_connection(&cli1, 0)) {
    2843           0 :                 return false;
    2844             :         }
    2845             : 
    2846           8 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2847             : 
    2848           8 :         status = cli_openx(cli1, fpath, O_RDWR, DENY_NONE,
    2849             :                           &fnum);
    2850           8 :         if (!NT_STATUS_IS_OK(status)) {
    2851           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2852           0 :                 return false;
    2853             :         }
    2854             : 
    2855             :         /* Ensure the child has the lock. */
    2856           8 :         status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
    2857           8 :         if (NT_STATUS_IS_OK(status)) {
    2858           0 :                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
    2859           0 :                 goto fail;
    2860             :         } else {
    2861           8 :                 d_printf("Child has the lock.\n");
    2862             :         }
    2863             : 
    2864             :         /* Tell the child to wait 5 seconds then exit. */
    2865           8 :         ret = write(pipe_out[1], &c, 1);
    2866           8 :         if (ret != 1) {
    2867           0 :                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
    2868           0 :                         strerror(errno));
    2869           0 :                 goto fail;
    2870             :         }
    2871             : 
    2872             :         /* Wait 20 seconds for the lock. */
    2873           8 :         alarm_cli = cli1;
    2874           8 :         CatchSignal(SIGALRM, alarm_handler_parent);
    2875           8 :         alarm(20);
    2876             : 
    2877           8 :         start = timeval_current();
    2878             : 
    2879           8 :         status = cli_lock32(cli1, fnum, 0, 4, timeout, WRITE_LOCK);
    2880           8 :         if (!NT_STATUS_IS_OK(status)) {
    2881           0 :                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
    2882             :                        "%s\n", nt_errstr(status));
    2883           0 :                 goto fail_nofd;
    2884             :         }
    2885           8 :         alarm(0);
    2886             : 
    2887           8 :         seconds = timeval_elapsed(&start);
    2888             : 
    2889           8 :         printf("Parent got the lock after %.2f seconds.\n",
    2890             :                 seconds);
    2891             : 
    2892           8 :         status = cli_close(cli1, fnum);
    2893           8 :         if (!NT_STATUS_IS_OK(status)) {
    2894           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2895           0 :                 goto fail;
    2896             :         }
    2897             : 
    2898           8 :         correct = true;
    2899             : 
    2900           8 : fail:
    2901           8 :         cli_close(cli1, fnum);
    2902           8 :         torture_close_connection(cli1);
    2903             : 
    2904           8 : fail_nofd:
    2905             : 
    2906           8 :         printf("finished locktest9X: %s\n", fname);
    2907           8 :         return correct;
    2908             : }
    2909             : 
    2910           4 : static bool run_locktest9a(int dummy)
    2911             : {
    2912           4 :         return _run_locktest9X("lock9a.dat", -1);
    2913             : }
    2914             : 
    2915           4 : static bool run_locktest9b(int dummy)
    2916             : {
    2917           4 :         return _run_locktest9X("lock9b.dat", 10000);
    2918             : }
    2919             : 
    2920             : struct locktest10_state {
    2921             :         bool ok;
    2922             :         bool done;
    2923             : };
    2924             : 
    2925             : static void locktest10_lockingx_done(struct tevent_req *subreq);
    2926             : static void locktest10_read_andx_done(struct tevent_req *subreq);
    2927             : 
    2928           5 : static bool run_locktest10(int dummy)
    2929             : {
    2930           5 :         struct tevent_context *ev = NULL;
    2931           5 :         struct cli_state *cli1 = NULL;
    2932           5 :         struct cli_state *cli2 = NULL;
    2933           5 :         struct smb1_lock_element lck = { 0 };
    2934           5 :         struct tevent_req *reqs[2] = { NULL };
    2935           5 :         struct tevent_req *smbreqs[2] = { NULL };
    2936           5 :         const char fname[] = "\\lockt10.lck";
    2937           0 :         uint16_t fnum1, fnum2;
    2938           5 :         bool ret = false;
    2939           0 :         bool ok;
    2940           5 :         uint8_t data = 1;
    2941           5 :         struct locktest10_state state = { .ok = true };
    2942           0 :         NTSTATUS status;
    2943             : 
    2944           5 :         printf("starting locktest10\n");
    2945             : 
    2946           5 :         ev = samba_tevent_context_init(NULL);
    2947           5 :         if (ev == NULL) {
    2948           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    2949           0 :                 goto done;
    2950             :         }
    2951             : 
    2952           5 :         ok = torture_open_connection(&cli1, 0);
    2953           5 :         if (!ok) {
    2954           0 :                 goto done;
    2955             :         }
    2956           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2957             : 
    2958           5 :         ok = torture_open_connection(&cli2, 1);
    2959           5 :         if (!ok) {
    2960           0 :                 goto done;
    2961             :         }
    2962           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2963             : 
    2964           5 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    2965           5 :         if (!NT_STATUS_IS_OK(status)) {
    2966           0 :                 d_fprintf(stderr,
    2967             :                           "cli_openx failed: %s\n",
    2968             :                           nt_errstr(status));
    2969           0 :                 goto done;
    2970             :         }
    2971             : 
    2972           5 :         status = cli_writeall(cli1, fnum1, 0, &data, 0, sizeof(data), NULL);
    2973           5 :         if (!NT_STATUS_IS_OK(status)) {
    2974           0 :                 d_fprintf(stderr,
    2975             :                           "cli_writeall failed: %s\n",
    2976             :                           nt_errstr(status));
    2977           0 :                 goto done;
    2978             :         }
    2979             : 
    2980           5 :         status = cli_openx(cli2, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    2981           5 :         if (!NT_STATUS_IS_OK(status)) {
    2982           0 :                 d_fprintf(stderr,
    2983             :                           "cli_openx failed: %s\n",
    2984             :                           nt_errstr(status));
    2985           0 :                 goto done;
    2986             :         }
    2987             : 
    2988           5 :         status = cli_locktype(
    2989             :                 cli2, fnum2, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    2990           5 :         if (!NT_STATUS_IS_OK(status)) {
    2991           0 :                 d_fprintf(stderr,
    2992             :                           "cli_locktype failed: %s\n",
    2993             :                           nt_errstr(status));
    2994           0 :                 goto done;
    2995             :         }
    2996             : 
    2997           5 :         lck = (struct smb1_lock_element) {
    2998           5 :                 .pid = cli_getpid(cli1), .offset = 0, .length = 1,
    2999             :         };
    3000             : 
    3001           5 :         reqs[0] = cli_lockingx_create(
    3002             :                 ev,                             /* mem_ctx */
    3003             :                 ev,                             /* tevent_context */
    3004             :                 cli1,                           /* cli */
    3005             :                 fnum1,                          /* fnum */
    3006             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3007             :                 0,                              /* newoplocklevel */
    3008             :                 1,                              /* timeout */
    3009             :                 0,                              /* num_unlocks */
    3010             :                 NULL,                           /* unlocks */
    3011             :                 1,                              /* num_locks */
    3012             :                 &lck,                               /* locks */
    3013             :                 &smbreqs[0]);                       /* psmbreq */
    3014           5 :         if (reqs[0] == NULL) {
    3015           0 :                 d_fprintf(stderr, "cli_lockingx_create failed\n");
    3016           0 :                 goto done;
    3017             :         }
    3018           5 :         tevent_req_set_callback(reqs[0], locktest10_lockingx_done, &state);
    3019             : 
    3020           5 :         reqs[1] = cli_read_andx_create(
    3021             :                 ev,             /* mem_ctx */
    3022             :                 ev,             /* ev */
    3023             :                 cli1,           /* cli */
    3024             :                 fnum1,          /* fnum */
    3025             :                 0,              /* offset */
    3026             :                 1,              /* size */
    3027             :                 &smbreqs[1]);       /* psmbreq */
    3028           5 :         if (reqs[1] == NULL) {
    3029           0 :                 d_fprintf(stderr, "cli_read_andx_create failed\n");
    3030           0 :                 goto done;
    3031             :         }
    3032           5 :         tevent_req_set_callback(reqs[1], locktest10_read_andx_done, &state);
    3033             : 
    3034           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
    3035           5 :         if (!NT_STATUS_IS_OK(status)) {
    3036           0 :                 d_fprintf(stderr,
    3037             :                           "smb1cli_req_chain_submit failed: %s\n",
    3038             :                           nt_errstr(status));
    3039           0 :                 goto done;
    3040             :         }
    3041             : 
    3042          30 :         while (!state.done) {
    3043          25 :                 tevent_loop_once(ev);
    3044             :         }
    3045             : 
    3046           5 :         torture_close_connection(cli1);
    3047             : 
    3048           5 :         if (state.ok) {
    3049           5 :                 ret = true;
    3050             :         }
    3051           0 : done:
    3052           5 :         return ret;
    3053             : }
    3054             : 
    3055           5 : static void locktest10_lockingx_done(struct tevent_req *subreq)
    3056             : {
    3057           5 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    3058           0 :         NTSTATUS status;
    3059             : 
    3060           5 :         status = cli_lockingx_recv(subreq);
    3061           5 :         TALLOC_FREE(subreq);
    3062             : 
    3063           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    3064           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    3065           0 :                 state->ok = false;
    3066             :         }
    3067           5 : }
    3068             : 
    3069           5 : static void locktest10_read_andx_done(struct tevent_req *subreq)
    3070             : {
    3071           5 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    3072           5 :         ssize_t received = -1;
    3073           5 :         uint8_t *rcvbuf = NULL;
    3074           0 :         NTSTATUS status;
    3075             : 
    3076           5 :         status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    3077             : 
    3078           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_REQUEST_ABORTED)) {
    3079           0 :                 d_printf("cli_read_andx returned %s\n", nt_errstr(status));
    3080           0 :                 state->ok = false;
    3081             :         }
    3082             : 
    3083           5 :         state->done = true;
    3084           5 :         TALLOC_FREE(subreq);
    3085           5 : }
    3086             : 
    3087           5 : static bool run_locktest11(int dummy)
    3088             : {
    3089           0 :         struct cli_state *cli1;
    3090           5 :         const char *fname = "\\lockt11.lck";
    3091           0 :         NTSTATUS status;
    3092           0 :         uint16_t fnum;
    3093           5 :         bool ret = false;
    3094             : 
    3095           5 :         if (!torture_open_connection(&cli1, 0)) {
    3096           0 :                 return false;
    3097             :         }
    3098             : 
    3099           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    3100             : 
    3101           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3102             : 
    3103           5 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum);
    3104           5 :         if (!NT_STATUS_IS_OK(status)) {
    3105           0 :                 d_fprintf(stderr,
    3106             :                           "cli_openx returned %s\n",
    3107             :                           nt_errstr(status));
    3108           0 :                 return false;
    3109             :         }
    3110             : 
    3111             :         /*
    3112             :          * Test that LOCKING_ANDX_CANCEL_LOCK without any locks
    3113             :          * returns NT_STATUS_OK
    3114             :          */
    3115             : 
    3116           5 :         status = cli_lockingx(
    3117             :                 cli1,                           /* cli */
    3118             :                 fnum,                           /* fnum */
    3119             :                 LOCKING_ANDX_CANCEL_LOCK,       /* typeoflock */
    3120             :                 0,                              /* newoplocklevel */
    3121             :                 0,                              /* timeout */
    3122             :                 0,                              /* num_unlocks */
    3123             :                 NULL,                           /* unlocks */
    3124             :                 0,                              /* num_locks */
    3125             :                 NULL);                          /* locks */
    3126             : 
    3127           5 :         if (!NT_STATUS_IS_OK(status)) {
    3128           1 :                 d_printf("cli_lockingX returned %s\n", nt_errstr(status));
    3129           1 :                 goto fail;
    3130             :         }
    3131             : 
    3132           4 :         ret = true;
    3133           5 : fail:
    3134           5 :         cli_close(cli1, fnum);
    3135           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3136             : 
    3137           5 :         return ret;
    3138             : }
    3139             : 
    3140             : struct deferred_close_state {
    3141             :         struct tevent_context *ev;
    3142             :         struct cli_state *cli;
    3143             :         uint16_t fnum;
    3144             : };
    3145             : 
    3146             : static void deferred_close_waited(struct tevent_req *subreq);
    3147             : static void deferred_close_done(struct tevent_req *subreq);
    3148             : 
    3149           5 : static struct tevent_req *deferred_close_send(
    3150             :         TALLOC_CTX *mem_ctx,
    3151             :         struct tevent_context *ev,
    3152             :         int wait_secs,
    3153             :         struct cli_state *cli,
    3154             :         uint16_t fnum)
    3155             : {
    3156           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3157           5 :         struct deferred_close_state *state = NULL;
    3158           5 :         struct timeval wakeup_time = timeval_current_ofs(wait_secs, 0);
    3159             : 
    3160           5 :         req = tevent_req_create(
    3161             :                 mem_ctx, &state, struct deferred_close_state);
    3162           5 :         if (req == NULL) {
    3163           0 :                 return NULL;
    3164             :         }
    3165           5 :         state->ev = ev;
    3166           5 :         state->cli = cli;
    3167           5 :         state->fnum = fnum;
    3168             : 
    3169           5 :         subreq = tevent_wakeup_send(state, state->ev, wakeup_time);
    3170           5 :         if (tevent_req_nomem(subreq, req)) {
    3171           0 :                 return tevent_req_post(req, ev);
    3172             :         }
    3173           5 :         tevent_req_set_callback(subreq, deferred_close_waited, req);
    3174           5 :         return req;
    3175             : }
    3176             : 
    3177           5 : static void deferred_close_waited(struct tevent_req *subreq)
    3178             : {
    3179           5 :         struct tevent_req *req = tevent_req_callback_data(
    3180             :                 subreq, struct tevent_req);
    3181           5 :         struct deferred_close_state *state = tevent_req_data(
    3182             :                 req, struct deferred_close_state);
    3183           0 :         bool ok;
    3184             : 
    3185           5 :         ok = tevent_wakeup_recv(subreq);
    3186           5 :         TALLOC_FREE(subreq);
    3187           5 :         if (!ok) {
    3188           0 :                 tevent_req_oom(req);
    3189           0 :                 return;
    3190             :         }
    3191             : 
    3192           5 :         subreq = cli_close_send(state, state->ev, state->cli, state->fnum, 0);
    3193           5 :         if (tevent_req_nomem(subreq, req)) {
    3194           0 :                 return;
    3195             :         }
    3196           5 :         tevent_req_set_callback(subreq, deferred_close_done, req);
    3197             : }
    3198             : 
    3199           5 : static void deferred_close_done(struct tevent_req *subreq)
    3200             : {
    3201           5 :         NTSTATUS status = cli_close_recv(subreq);
    3202           5 :         tevent_req_simple_finish_ntstatus(subreq, status);
    3203           5 : }
    3204             : 
    3205           5 : static NTSTATUS deferred_close_recv(struct tevent_req *req)
    3206             : {
    3207           5 :         return tevent_req_simple_recv_ntstatus(req);
    3208             : }
    3209             : 
    3210             : struct lockread_state {
    3211             :         struct smb1_lock_element lck;
    3212             :         struct tevent_req *reqs[2];
    3213             :         struct tevent_req *smbreqs[2];
    3214             :         NTSTATUS lock_status;
    3215             :         NTSTATUS read_status;
    3216             :         uint8_t *readbuf;
    3217             : };
    3218             : 
    3219             : static void lockread_lockingx_done(struct tevent_req *subreq);
    3220             : static void lockread_read_andx_done(struct tevent_req *subreq);
    3221             : 
    3222           5 : static struct tevent_req *lockread_send(
    3223             :         TALLOC_CTX *mem_ctx,
    3224             :         struct tevent_context *ev,
    3225             :         struct cli_state *cli,
    3226             :         uint16_t fnum)
    3227             : {
    3228           5 :         struct tevent_req *req = NULL;
    3229           5 :         struct lockread_state *state = NULL;
    3230           0 :         NTSTATUS status;
    3231             : 
    3232           5 :         req = tevent_req_create(mem_ctx, &state, struct lockread_state);
    3233           5 :         if (req == NULL) {
    3234           0 :                 return NULL;
    3235             :         }
    3236             : 
    3237          10 :         state->lck = (struct smb1_lock_element) {
    3238           5 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3239             :         };
    3240             : 
    3241          10 :         state->reqs[0] = cli_lockingx_create(
    3242             :                 ev,                             /* mem_ctx */
    3243             :                 ev,                             /* tevent_context */
    3244             :                 cli,                            /* cli */
    3245             :                 fnum,                           /* fnum */
    3246             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3247             :                 0,                              /* newoplocklevel */
    3248             :                 10000,                          /* timeout */
    3249             :                 0,                              /* num_unlocks */
    3250             :                 NULL,                           /* unlocks */
    3251             :                 1,                              /* num_locks */
    3252           5 :                 &state->lck,                     /* locks */
    3253           5 :                 &state->smbreqs[0]);             /* psmbreq */
    3254           5 :         if (tevent_req_nomem(state->reqs[0], req)) {
    3255           0 :                 return tevent_req_post(req, ev);
    3256             :         }
    3257           5 :         tevent_req_set_callback(
    3258             :                 state->reqs[0], lockread_lockingx_done, req);
    3259             : 
    3260          10 :         state->reqs[1] = cli_read_andx_create(
    3261             :                 ev,             /* mem_ctx */
    3262             :                 ev,             /* ev */
    3263             :                 cli,            /* cli */
    3264             :                 fnum,           /* fnum */
    3265             :                 0,              /* offset */
    3266             :                 1,              /* size */
    3267           5 :                 &state->smbreqs[1]);     /* psmbreq */
    3268           5 :         if (tevent_req_nomem(state->reqs[1], req)) {
    3269           0 :                 return tevent_req_post(req, ev);
    3270             :         }
    3271           5 :         tevent_req_set_callback(
    3272             :                 state->reqs[1], lockread_read_andx_done, req);
    3273             : 
    3274           5 :         status = smb1cli_req_chain_submit(state->smbreqs, 2);
    3275           5 :         if (tevent_req_nterror(req, status)) {
    3276           0 :                 return tevent_req_post(req, ev);
    3277             :         }
    3278           5 :         return req;
    3279             : }
    3280             : 
    3281           5 : static void lockread_lockingx_done(struct tevent_req *subreq)
    3282             : {
    3283           5 :         struct tevent_req *req = tevent_req_callback_data(
    3284             :                 subreq, struct tevent_req);
    3285           5 :         struct lockread_state *state = tevent_req_data(
    3286             :                 req, struct lockread_state);
    3287           5 :         state->lock_status = cli_lockingx_recv(subreq);
    3288           5 :         TALLOC_FREE(subreq);
    3289           5 :         d_fprintf(stderr,
    3290             :                   "lockingx returned %s\n",
    3291             :                   nt_errstr(state->lock_status));
    3292           5 : }
    3293             : 
    3294           5 : static void lockread_read_andx_done(struct tevent_req *subreq)
    3295             : {
    3296           5 :         struct tevent_req *req = tevent_req_callback_data(
    3297             :                 subreq, struct tevent_req);
    3298           5 :         struct lockread_state *state = tevent_req_data(
    3299             :                 req, struct lockread_state);
    3300           5 :         ssize_t received = -1;
    3301           5 :         uint8_t *rcvbuf = NULL;
    3302             : 
    3303           5 :         state->read_status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    3304             : 
    3305           5 :         d_fprintf(stderr,
    3306             :                   "read returned %s\n",
    3307             :                   nt_errstr(state->read_status));
    3308             : 
    3309           5 :         if (!NT_STATUS_IS_OK(state->read_status)) {
    3310           4 :                 TALLOC_FREE(subreq);
    3311           4 :                 tevent_req_done(req);
    3312           4 :                 return;
    3313             :         }
    3314             : 
    3315           1 :         if (received > 0) {
    3316           1 :                 state->readbuf = talloc_memdup(state, rcvbuf, received);
    3317           1 :                 TALLOC_FREE(subreq);
    3318           1 :                 if (tevent_req_nomem(state->readbuf, req)) {
    3319           0 :                         return;
    3320             :                 }
    3321             :         }
    3322           1 :         TALLOC_FREE(subreq);
    3323           1 :         tevent_req_done(req);
    3324             : }
    3325             : 
    3326           5 : static NTSTATUS lockread_recv(
    3327             :         struct tevent_req *req,
    3328             :         NTSTATUS *lock_status,
    3329             :         NTSTATUS *read_status,
    3330             :         TALLOC_CTX *mem_ctx,
    3331             :         uint8_t **read_buf)
    3332             : {
    3333           5 :         struct lockread_state *state = tevent_req_data(
    3334             :                 req, struct lockread_state);
    3335           0 :         NTSTATUS status;
    3336             : 
    3337           5 :         if (tevent_req_is_nterror(req, &status)) {
    3338           0 :                 return status;
    3339             :         }
    3340             : 
    3341           5 :         *lock_status = state->lock_status;
    3342           5 :         *read_status = state->read_status;
    3343           5 :         if (state->readbuf != NULL) {
    3344           1 :                 *read_buf = talloc_move(mem_ctx, &state->readbuf);
    3345             :         } else {
    3346           4 :                 *read_buf = NULL;
    3347             :         }
    3348             : 
    3349           5 :         return NT_STATUS_OK;
    3350             : }
    3351             : 
    3352             : struct lock12_state {
    3353             :         uint8_t dummy;
    3354             : };
    3355             : 
    3356             : static void lock12_closed(struct tevent_req *subreq);
    3357             : static void lock12_read(struct tevent_req *subreq);
    3358             : 
    3359           5 : static struct tevent_req *lock12_send(
    3360             :         TALLOC_CTX *mem_ctx,
    3361             :         struct tevent_context *ev,
    3362             :         struct cli_state *cli,
    3363             :         uint16_t fnum1,
    3364             :         uint16_t fnum2)
    3365             : {
    3366           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3367           5 :         struct lock12_state *state = NULL;
    3368             : 
    3369           5 :         req = tevent_req_create(mem_ctx, &state, struct lock12_state);
    3370           5 :         if (req == NULL) {
    3371           0 :                 return NULL;
    3372             :         }
    3373             : 
    3374           5 :         subreq = deferred_close_send(state, ev, 1, cli, fnum1);
    3375           5 :         if (tevent_req_nomem(subreq, req)) {
    3376           0 :                 return tevent_req_post(req, ev);
    3377             :         }
    3378           5 :         tevent_req_set_callback(subreq, lock12_closed, req);
    3379             : 
    3380           5 :         subreq = lockread_send(state, ev, cli, fnum2);
    3381           5 :         if (tevent_req_nomem(subreq, req)) {
    3382           0 :                 return tevent_req_post(req, ev);
    3383             :         }
    3384           5 :         tevent_req_set_callback(subreq, lock12_read, req);
    3385             : 
    3386           5 :         return req;
    3387             : }
    3388             : 
    3389           5 : static void lock12_closed(struct tevent_req *subreq)
    3390             : {
    3391           5 :         struct tevent_req *req = tevent_req_callback_data(
    3392             :                 subreq, struct tevent_req);
    3393           0 :         NTSTATUS status;
    3394             : 
    3395           5 :         status = deferred_close_recv(subreq);
    3396           5 :         TALLOC_FREE(subreq);
    3397           5 :         DBG_DEBUG("close returned %s\n", nt_errstr(status));
    3398           5 :         if (tevent_req_nterror(req, status)) {
    3399           0 :                 return;
    3400             :         }
    3401             : }
    3402             : 
    3403           5 : static void lock12_read(struct tevent_req *subreq)
    3404             : {
    3405           5 :         struct tevent_req *req = tevent_req_callback_data(
    3406             :                 subreq, struct tevent_req);
    3407           5 :         struct lock12_state *state = tevent_req_data(
    3408             :                 req, struct lock12_state);
    3409           0 :         NTSTATUS status, lock_status, read_status;
    3410           5 :         uint8_t *buf = NULL;
    3411             : 
    3412           5 :         status = lockread_recv(
    3413             :                 subreq, &lock_status, &read_status, state, &buf);
    3414           5 :         TALLOC_FREE(subreq);
    3415          10 :         if (tevent_req_nterror(req, status) ||
    3416          10 :             tevent_req_nterror(req, lock_status) ||
    3417           5 :             tevent_req_nterror(req, read_status)) {
    3418           4 :                 return;
    3419             :         }
    3420           1 :         tevent_req_done(req);
    3421             : }
    3422             : 
    3423           5 : static NTSTATUS lock12_recv(struct tevent_req *req)
    3424             : 
    3425             : {
    3426           0 :         NTSTATUS status;
    3427             : 
    3428           5 :         if (tevent_req_is_nterror(req, &status)) {
    3429           4 :                 return status;
    3430             :         }
    3431           1 :         return NT_STATUS_OK;
    3432             : }
    3433             : 
    3434           5 : static bool run_locktest12(int dummy)
    3435             : {
    3436           5 :         struct tevent_context *ev = NULL;
    3437           5 :         struct tevent_req *req = NULL;
    3438           5 :         struct cli_state *cli = NULL;
    3439           5 :         const char fname[] = "\\lockt12.lck";
    3440           0 :         uint16_t fnum1, fnum2;
    3441           5 :         bool ret = false;
    3442           0 :         bool ok;
    3443           5 :         uint8_t data = 1;
    3444           0 :         NTSTATUS status;
    3445             : 
    3446           5 :         printf("starting locktest12\n");
    3447             : 
    3448           5 :         ev = samba_tevent_context_init(NULL);
    3449           5 :         if (ev == NULL) {
    3450           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3451           0 :                 goto done;
    3452             :         }
    3453             : 
    3454           5 :         ok = torture_open_connection(&cli, 0);
    3455           5 :         if (!ok) {
    3456           0 :                 goto done;
    3457             :         }
    3458           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3459             : 
    3460           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3461           5 :         if (!NT_STATUS_IS_OK(status)) {
    3462           0 :                 d_fprintf(stderr,
    3463             :                           "cli_openx failed: %s\n",
    3464             :                           nt_errstr(status));
    3465           0 :                 goto done;
    3466             :         }
    3467             : 
    3468           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3469           5 :         if (!NT_STATUS_IS_OK(status)) {
    3470           0 :                 d_fprintf(stderr,
    3471             :                           "cli_openx failed: %s\n",
    3472             :                           nt_errstr(status));
    3473           0 :                 goto done;
    3474             :         }
    3475             : 
    3476           5 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3477           5 :         if (!NT_STATUS_IS_OK(status)) {
    3478           0 :                 d_fprintf(stderr,
    3479             :                           "cli_writeall failed: %s\n",
    3480             :                           nt_errstr(status));
    3481           0 :                 goto done;
    3482             :         }
    3483             : 
    3484           5 :         status = cli_locktype(
    3485             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3486           5 :         if (!NT_STATUS_IS_OK(status)) {
    3487           0 :                 d_fprintf(stderr,
    3488             :                           "cli_locktype failed: %s\n",
    3489             :                           nt_errstr(status));
    3490           0 :                 goto done;
    3491             :         }
    3492             : 
    3493           5 :         req = lock12_send(ev, ev, cli, fnum1, fnum2);
    3494           5 :         if (req == NULL) {
    3495           0 :                 d_fprintf(stderr, "lock12_send failed\n");
    3496           0 :                 goto done;
    3497             :         }
    3498             : 
    3499           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3500           5 :         if (!ok) {
    3501           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3502           0 :                 goto done;
    3503             :         }
    3504             : 
    3505           5 :         if (!NT_STATUS_IS_OK(status)) {
    3506           0 :                 d_fprintf(stderr,
    3507             :                           "tevent_req_poll_ntstatus returned %s\n",
    3508             :                           nt_errstr(status));
    3509           0 :                 goto done;
    3510             :         }
    3511             : 
    3512           5 :         status = lock12_recv(req);
    3513           5 :         if (!NT_STATUS_IS_OK(status)) {
    3514           4 :                 d_fprintf(stderr, "lock12 returned %s\n", nt_errstr(status));
    3515           4 :                 goto done;
    3516             :         }
    3517             : 
    3518           1 :         ret = true;
    3519           5 : done:
    3520           5 :         if (cli != NULL) {
    3521           5 :                 torture_close_connection(cli);
    3522             :         }
    3523           5 :         return ret;
    3524             : }
    3525             : 
    3526             : struct lock_ntcancel_state {
    3527             :         struct timeval start;
    3528             :         struct smb1_lock_element lck;
    3529             :         struct tevent_req *subreq;
    3530             : };
    3531             : 
    3532             : static void lock_ntcancel_waited(struct tevent_req *subreq);
    3533             : static void lock_ntcancel_done(struct tevent_req *subreq);
    3534             : 
    3535           5 : static struct tevent_req *lock_ntcancel_send(
    3536             :         TALLOC_CTX *mem_ctx,
    3537             :         struct tevent_context *ev,
    3538             :         struct cli_state *cli,
    3539             :         uint16_t fnum)
    3540             : {
    3541           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3542           5 :         struct lock_ntcancel_state *state = NULL;
    3543             : 
    3544           5 :         req = tevent_req_create(mem_ctx, &state, struct lock_ntcancel_state);
    3545           5 :         if (req == NULL) {
    3546           0 :                 return NULL;
    3547             :         }
    3548          10 :         state->lck = (struct smb1_lock_element) {
    3549           5 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3550             :         };
    3551           5 :         state->start = timeval_current();
    3552             : 
    3553          10 :         state->subreq = cli_lockingx_send(
    3554             :                 state,                          /* mem_ctx */
    3555             :                 ev,                             /* tevent_context */
    3556             :                 cli,                            /* cli */
    3557             :                 fnum,                           /* fnum */
    3558             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3559             :                 0,                              /* newoplocklevel */
    3560             :                 10000,                          /* timeout */
    3561             :                 0,                              /* num_unlocks */
    3562             :                 NULL,                           /* unlocks */
    3563             :                 1,                              /* num_locks */
    3564           5 :                 &state->lck);                    /* locks */
    3565           5 :         if (tevent_req_nomem(state->subreq, req)) {
    3566           0 :                 return tevent_req_post(req, ev);
    3567             :         }
    3568           5 :         tevent_req_set_callback(state->subreq, lock_ntcancel_done, req);
    3569             : 
    3570           5 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(1, 0));
    3571           5 :         if (tevent_req_nomem(subreq, req)) {
    3572           0 :                 return tevent_req_post(req, ev);
    3573             :         }
    3574           5 :         tevent_req_set_callback(subreq, lock_ntcancel_waited, req);
    3575           5 :         return req;
    3576             : }
    3577             : 
    3578           5 : static void lock_ntcancel_waited(struct tevent_req *subreq)
    3579             : {
    3580           5 :         struct tevent_req *req = tevent_req_callback_data(
    3581             :                 subreq, struct tevent_req);
    3582           5 :         struct lock_ntcancel_state *state = tevent_req_data(
    3583             :                 req, struct lock_ntcancel_state);
    3584           0 :         bool ok;
    3585             : 
    3586           5 :         ok = tevent_wakeup_recv(subreq);
    3587           5 :         TALLOC_FREE(subreq);
    3588           5 :         if (!ok) {
    3589           0 :                 tevent_req_oom(req);
    3590           0 :                 return;
    3591             :         }
    3592             : 
    3593           5 :         ok = tevent_req_cancel(state->subreq);
    3594           5 :         if (!ok) {
    3595           0 :                 d_fprintf(stderr, "Could not cancel subreq\n");
    3596           0 :                 tevent_req_oom(req);
    3597           0 :                 return;
    3598             :         }
    3599             : }
    3600             : 
    3601           5 : static void lock_ntcancel_done(struct tevent_req *subreq)
    3602             : {
    3603           5 :         struct tevent_req *req = tevent_req_callback_data(
    3604             :                 subreq, struct tevent_req);
    3605           5 :         struct lock_ntcancel_state *state = tevent_req_data(
    3606             :                 req, struct lock_ntcancel_state);
    3607           0 :         NTSTATUS status;
    3608           0 :         double elapsed;
    3609             : 
    3610           5 :         status = cli_lockingx_recv(subreq);
    3611           5 :         TALLOC_FREE(subreq);
    3612             : 
    3613           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    3614           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    3615           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3616           0 :                 return;
    3617             :         }
    3618             : 
    3619           5 :         elapsed = timeval_elapsed(&state->start);
    3620             : 
    3621           5 :         if (elapsed > 3) {
    3622           0 :                 d_printf("cli_lockingx was too slow, cancel did not work\n");
    3623           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3624           0 :                 return;
    3625             :         }
    3626             : 
    3627           5 :         tevent_req_done(req);
    3628             : }
    3629             : 
    3630           5 : static NTSTATUS lock_ntcancel_recv(struct tevent_req *req)
    3631             : {
    3632           5 :         return tevent_req_simple_recv_ntstatus(req);
    3633             : }
    3634             : 
    3635           5 : static bool run_locktest13(int dummy)
    3636             : {
    3637           5 :         struct tevent_context *ev = NULL;
    3638           5 :         struct tevent_req *req = NULL;
    3639           5 :         struct cli_state *cli = NULL;
    3640           5 :         const char fname[] = "\\lockt13.lck";
    3641           0 :         uint16_t fnum1, fnum2;
    3642           5 :         bool ret = false;
    3643           0 :         bool ok;
    3644           5 :         uint8_t data = 1;
    3645           0 :         NTSTATUS status;
    3646             : 
    3647           5 :         printf("starting locktest13\n");
    3648             : 
    3649           5 :         ev = samba_tevent_context_init(NULL);
    3650           5 :         if (ev == NULL) {
    3651           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3652           0 :                 goto done;
    3653             :         }
    3654             : 
    3655           5 :         ok = torture_open_connection(&cli, 0);
    3656           5 :         if (!ok) {
    3657           0 :                 goto done;
    3658             :         }
    3659           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3660             : 
    3661           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3662           5 :         if (!NT_STATUS_IS_OK(status)) {
    3663           0 :                 d_fprintf(stderr,
    3664             :                           "cli_openx failed: %s\n",
    3665             :                           nt_errstr(status));
    3666           0 :                 goto done;
    3667             :         }
    3668             : 
    3669           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3670           5 :         if (!NT_STATUS_IS_OK(status)) {
    3671           0 :                 d_fprintf(stderr,
    3672             :                           "cli_openx failed: %s\n",
    3673             :                           nt_errstr(status));
    3674           0 :                 goto done;
    3675             :         }
    3676             : 
    3677           5 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3678           5 :         if (!NT_STATUS_IS_OK(status)) {
    3679           0 :                 d_fprintf(stderr,
    3680             :                           "cli_writeall failed: %s\n",
    3681             :                           nt_errstr(status));
    3682           0 :                 goto done;
    3683             :         }
    3684             : 
    3685           5 :         status = cli_locktype(
    3686             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3687           5 :         if (!NT_STATUS_IS_OK(status)) {
    3688           0 :                 d_fprintf(stderr,
    3689             :                           "cli_locktype failed: %s\n",
    3690             :                           nt_errstr(status));
    3691           0 :                 goto done;
    3692             :         }
    3693             : 
    3694           5 :         req = lock_ntcancel_send(ev, ev, cli, fnum2);
    3695           5 :         if (req == NULL) {
    3696           0 :                 d_fprintf(stderr, "lock_ntcancel_send failed\n");
    3697           0 :                 goto done;
    3698             :         }
    3699             : 
    3700           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3701           5 :         if (!ok) {
    3702           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3703           0 :                 goto done;
    3704             :         }
    3705             : 
    3706           5 :         if (!NT_STATUS_IS_OK(status)) {
    3707           0 :                 d_fprintf(stderr,
    3708             :                           "tevent_req_poll_ntstatus returned %s\n",
    3709             :                           nt_errstr(status));
    3710           0 :                 goto done;
    3711             :         }
    3712             : 
    3713           5 :         status = lock_ntcancel_recv(req);
    3714           5 :         if (!NT_STATUS_IS_OK(status)) {
    3715           0 :                 d_fprintf(stderr,
    3716             :                           "lock_ntcancel returned %s\n",
    3717             :                           nt_errstr(status));
    3718           0 :                 goto done;
    3719             :         }
    3720             : 
    3721           5 :         ret = true;
    3722           5 : done:
    3723           5 :         if (cli != NULL) {
    3724           5 :                 torture_close_connection(cli);
    3725             :         }
    3726           5 :         return ret;
    3727             : }
    3728             : 
    3729             : /*
    3730             : test whether fnums and tids open on one VC are available on another (a major
    3731             : security hole)
    3732             : */
    3733           5 : static bool run_fdpasstest(int dummy)
    3734             : {
    3735           0 :         struct cli_state *cli1, *cli2;
    3736           5 :         const char *fname = "\\fdpass.tst";
    3737           0 :         uint16_t fnum1;
    3738           0 :         char buf[1024];
    3739           0 :         NTSTATUS status;
    3740             : 
    3741           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    3742           0 :                 return False;
    3743             :         }
    3744           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    3745           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    3746             : 
    3747           5 :         printf("starting fdpasstest\n");
    3748             : 
    3749           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3750             : 
    3751           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    3752             :                           &fnum1);
    3753           5 :         if (!NT_STATUS_IS_OK(status)) {
    3754           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3755           0 :                 return False;
    3756             :         }
    3757             : 
    3758           5 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
    3759             :                               13, NULL);
    3760           5 :         if (!NT_STATUS_IS_OK(status)) {
    3761           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3762           0 :                 return False;
    3763             :         }
    3764             : 
    3765           5 :         cli_state_set_uid(cli2, cli_state_get_uid(cli1));
    3766           5 :         cli_state_set_tid(cli2, cli_state_get_tid(cli1));
    3767           5 :         cli_setpid(cli2, cli_getpid(cli1));
    3768             : 
    3769           5 :         if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
    3770           0 :                 printf("read succeeded! nasty security hole [%s]\n", buf);
    3771           0 :                 return false;
    3772             :         }
    3773             : 
    3774           5 :         cli_close(cli1, fnum1);
    3775           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3776             : 
    3777           5 :         torture_close_connection(cli1);
    3778           5 :         torture_close_connection(cli2);
    3779             : 
    3780           5 :         printf("finished fdpasstest\n");
    3781           5 :         return True;
    3782             : }
    3783             : 
    3784           5 : static bool run_fdsesstest(int dummy)
    3785             : {
    3786           0 :         struct cli_state *cli;
    3787           0 :         uint16_t new_vuid;
    3788           0 :         uint16_t saved_vuid;
    3789           0 :         uint32_t new_cnum;
    3790           0 :         uint32_t saved_cnum;
    3791           5 :         const char *fname = "\\fdsess.tst";
    3792           5 :         const char *fname1 = "\\fdsess1.tst";
    3793           0 :         uint16_t fnum1;
    3794           0 :         uint16_t fnum2;
    3795           0 :         char buf[1024];
    3796           5 :         bool ret = True;
    3797           0 :         NTSTATUS status;
    3798             : 
    3799           5 :         if (!torture_open_connection(&cli, 0))
    3800           0 :                 return False;
    3801           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3802             : 
    3803           5 :         if (!torture_cli_session_setup2(cli, &new_vuid))
    3804           0 :                 return False;
    3805             : 
    3806           5 :         saved_cnum = cli_state_get_tid(cli);
    3807           5 :         if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
    3808           0 :                 return False;
    3809           5 :         new_cnum = cli_state_get_tid(cli);
    3810           5 :         cli_state_set_tid(cli, saved_cnum);
    3811             : 
    3812           5 :         printf("starting fdsesstest\n");
    3813             : 
    3814           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3815           5 :         cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3816             : 
    3817           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    3818           5 :         if (!NT_STATUS_IS_OK(status)) {
    3819           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3820           0 :                 return False;
    3821             :         }
    3822             : 
    3823           5 :         status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
    3824             :                               NULL);
    3825           5 :         if (!NT_STATUS_IS_OK(status)) {
    3826           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3827           0 :                 return False;
    3828             :         }
    3829             : 
    3830           5 :         saved_vuid = cli_state_get_uid(cli);
    3831           5 :         cli_state_set_uid(cli, new_vuid);
    3832             : 
    3833           5 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3834           0 :                 printf("read succeeded with different vuid! "
    3835             :                        "nasty security hole [%s]\n", buf);
    3836           0 :                 ret = false;
    3837             :         }
    3838             :         /* Try to open a file with different vuid, samba cnum. */
    3839           5 :         if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
    3840           5 :                 printf("create with different vuid, same cnum succeeded.\n");
    3841           5 :                 cli_close(cli, fnum2);
    3842           5 :                 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3843             :         } else {
    3844           0 :                 printf("create with different vuid, same cnum failed.\n");
    3845           0 :                 printf("This will cause problems with service clients.\n");
    3846           0 :                 ret = False;
    3847             :         }
    3848             : 
    3849           5 :         cli_state_set_uid(cli, saved_vuid);
    3850             : 
    3851             :         /* Try with same vuid, different cnum. */
    3852           5 :         cli_state_set_tid(cli, new_cnum);
    3853             : 
    3854           5 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3855           0 :                 printf("read succeeded with different cnum![%s]\n", buf);
    3856           0 :                 ret = false;
    3857             :         }
    3858             : 
    3859           5 :         cli_state_set_tid(cli, saved_cnum);
    3860           5 :         cli_close(cli, fnum1);
    3861           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3862             : 
    3863           5 :         torture_close_connection(cli);
    3864             : 
    3865           5 :         printf("finished fdsesstest\n");
    3866           5 :         return ret;
    3867             : }
    3868             : 
    3869             : /*
    3870             :   This test checks that
    3871             : 
    3872             :   1) the server does not allow an unlink on a file that is open
    3873             : */
    3874           5 : static bool run_unlinktest(int dummy)
    3875             : {
    3876           0 :         struct cli_state *cli;
    3877           5 :         const char *fname = "\\unlink.tst";
    3878           0 :         uint16_t fnum;
    3879           5 :         bool correct = True;
    3880           0 :         NTSTATUS status;
    3881             : 
    3882           5 :         if (!torture_open_connection(&cli, 0)) {
    3883           0 :                 return False;
    3884             :         }
    3885             : 
    3886           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3887             : 
    3888           5 :         printf("starting unlink test\n");
    3889             : 
    3890           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3891             : 
    3892           5 :         cli_setpid(cli, 1);
    3893             : 
    3894           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    3895           5 :         if (!NT_STATUS_IS_OK(status)) {
    3896           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3897           0 :                 return False;
    3898             :         }
    3899             : 
    3900           5 :         status = cli_unlink(cli, fname,
    3901             :                             FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3902           5 :         if (NT_STATUS_IS_OK(status)) {
    3903           0 :                 printf("error: server allowed unlink on an open file\n");
    3904           0 :                 correct = False;
    3905             :         } else {
    3906           5 :                 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
    3907           5 :                                       NT_STATUS_SHARING_VIOLATION);
    3908             :         }
    3909             : 
    3910           5 :         cli_close(cli, fnum);
    3911           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3912             : 
    3913           5 :         if (!torture_close_connection(cli)) {
    3914           0 :                 correct = False;
    3915             :         }
    3916             : 
    3917           5 :         printf("unlink test finished\n");
    3918             : 
    3919           5 :         return correct;
    3920             : }
    3921             : 
    3922             : 
    3923             : /*
    3924             : test how many open files this server supports on the one socket
    3925             : */
    3926           0 : static bool run_maxfidtest(int dummy)
    3927             : {
    3928           0 :         struct cli_state *cli;
    3929           0 :         fstring fname;
    3930           0 :         uint16_t fnums[0x11000];
    3931           0 :         int i;
    3932           0 :         int retries=4;
    3933           0 :         bool correct = True;
    3934           0 :         NTSTATUS status;
    3935             : 
    3936           0 :         cli = current_cli;
    3937             : 
    3938           0 :         if (retries <= 0) {
    3939           0 :                 printf("failed to connect\n");
    3940           0 :                 return False;
    3941             :         }
    3942             : 
    3943           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3944             : 
    3945           0 :         for (i=0; i<0x11000; i++) {
    3946           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3947           0 :                 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
    3948             :                                   &fnums[i]);
    3949           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3950           0 :                         printf("open of %s failed (%s)\n",
    3951             :                                fname, nt_errstr(status));
    3952           0 :                         printf("maximum fnum is %d\n", i);
    3953           0 :                         break;
    3954             :                 }
    3955           0 :                 printf("%6d\r", i);
    3956             :         }
    3957           0 :         printf("%6d\n", i);
    3958           0 :         i--;
    3959             : 
    3960           0 :         printf("cleaning up\n");
    3961           0 :         for (;i>=0;i--) {
    3962           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3963           0 :                 cli_close(cli, fnums[i]);
    3964             : 
    3965           0 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3966           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3967           0 :                         printf("unlink of %s failed (%s)\n",
    3968             :                                fname, nt_errstr(status));
    3969           0 :                         correct = False;
    3970             :                 }
    3971           0 :                 printf("%6d\r", i);
    3972             :         }
    3973           0 :         printf("%6d\n", 0);
    3974             : 
    3975           0 :         printf("maxfid test finished\n");
    3976           0 :         if (!torture_close_connection(cli)) {
    3977           0 :                 correct = False;
    3978             :         }
    3979           0 :         return correct;
    3980             : }
    3981             : 
    3982             : /* generate a random buffer */
    3983           0 : static void rand_buf(char *buf, int len)
    3984             : {
    3985           0 :         while (len--) {
    3986           0 :                 *buf = (char)sys_random();
    3987           0 :                 buf++;
    3988             :         }
    3989           0 : }
    3990             : 
    3991             : /* send smb negprot commands, not reading the response */
    3992           0 : static bool run_negprot_nowait(int dummy)
    3993             : {
    3994           0 :         struct tevent_context *ev;
    3995           0 :         int i;
    3996           0 :         struct cli_state *cli;
    3997           0 :         bool correct = True;
    3998             : 
    3999           0 :         printf("starting negprot nowait test\n");
    4000             : 
    4001           0 :         ev = samba_tevent_context_init(talloc_tos());
    4002           0 :         if (ev == NULL) {
    4003           0 :                 return false;
    4004             :         }
    4005             : 
    4006           0 :         if (!(cli = open_nbt_connection())) {
    4007           0 :                 TALLOC_FREE(ev);
    4008           0 :                 return False;
    4009             :         }
    4010             : 
    4011           0 :         for (i=0;i<50000;i++) {
    4012           0 :                 struct tevent_req *req;
    4013             : 
    4014           0 :                 req = smbXcli_negprot_send(
    4015             :                         ev,
    4016             :                         ev,
    4017             :                         cli->conn,
    4018           0 :                         cli->timeout,
    4019             :                         PROTOCOL_CORE,
    4020             :                         PROTOCOL_NT1,
    4021             :                         0,
    4022             :                         NULL);
    4023           0 :                 if (req == NULL) {
    4024           0 :                         TALLOC_FREE(ev);
    4025           0 :                         return false;
    4026             :                 }
    4027           0 :                 if (!tevent_req_poll(req, ev)) {
    4028           0 :                         d_fprintf(stderr, "tevent_req_poll failed: %s\n",
    4029           0 :                                   strerror(errno));
    4030           0 :                         TALLOC_FREE(ev);
    4031           0 :                         return false;
    4032             :                 }
    4033           0 :                 TALLOC_FREE(req);
    4034             :         }
    4035             : 
    4036           0 :         if (torture_close_connection(cli)) {
    4037           0 :                 correct = False;
    4038             :         }
    4039             : 
    4040           0 :         printf("finished negprot nowait test\n");
    4041             : 
    4042           0 :         return correct;
    4043             : }
    4044             : 
    4045             : /* send smb negprot commands, not reading the response */
    4046           4 : static bool run_bad_nbt_session(int dummy)
    4047             : {
    4048           0 :         struct nmb_name called, calling;
    4049           0 :         struct sockaddr_storage ss;
    4050           0 :         NTSTATUS status;
    4051           0 :         int fd;
    4052           0 :         bool ret;
    4053             : 
    4054           4 :         printf("starting bad nbt session test\n");
    4055             : 
    4056           4 :         make_nmb_name(&calling, myname, 0x0);
    4057           4 :         make_nmb_name(&called , host, 0x20);
    4058             : 
    4059           4 :         if (!resolve_name(host, &ss, 0x20, true)) {
    4060           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
    4061           0 :                 return false;
    4062             :         }
    4063             : 
    4064           4 :         status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
    4065           4 :         if (!NT_STATUS_IS_OK(status)) {
    4066           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    4067             :                           nt_errstr(status));
    4068           0 :                 return false;
    4069             :         }
    4070             : 
    4071           4 :         ret = cli_bad_session_request(fd, &calling, &called);
    4072           4 :         close(fd);
    4073           4 :         if (!ret) {
    4074           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    4075             :                           nt_errstr(status));
    4076           0 :                 return false;
    4077             :         }
    4078             : 
    4079           4 :         printf("finished bad nbt session test\n");
    4080           4 :         return true;
    4081             : }
    4082             : 
    4083             : /* send random IPC commands */
    4084           0 : static bool run_randomipc(int dummy)
    4085             : {
    4086           0 :         char *rparam = NULL;
    4087           0 :         char *rdata = NULL;
    4088           0 :         unsigned int rdrcnt,rprcnt;
    4089           0 :         char param[1024];
    4090           0 :         int api, param_len, i;
    4091           0 :         struct cli_state *cli;
    4092           0 :         bool correct = True;
    4093           0 :         int count = 50000;
    4094             : 
    4095           0 :         printf("starting random ipc test\n");
    4096             : 
    4097           0 :         if (!torture_open_connection(&cli, 0)) {
    4098           0 :                 return False;
    4099             :         }
    4100             : 
    4101           0 :         for (i=0;i<count;i++) {
    4102           0 :                 api = sys_random() % 500;
    4103           0 :                 param_len = (sys_random() % 64);
    4104             : 
    4105           0 :                 rand_buf(param, param_len);
    4106             : 
    4107           0 :                 SSVAL(param,0,api);
    4108             : 
    4109           0 :                 cli_api(cli,
    4110             :                         param, param_len, 8,
    4111             :                         NULL, 0, CLI_BUFFER_SIZE,
    4112             :                         &rparam, &rprcnt,
    4113             :                         &rdata, &rdrcnt);
    4114           0 :                 if (i % 100 == 0) {
    4115           0 :                         printf("%d/%d\r", i,count);
    4116             :                 }
    4117             :         }
    4118           0 :         printf("%d/%d\n", i, count);
    4119             : 
    4120           0 :         if (!torture_close_connection(cli)) {
    4121           0 :                 correct = False;
    4122             :         }
    4123             : 
    4124           0 :         SAFE_FREE(rparam);
    4125           0 :         SAFE_FREE(rdata);
    4126             : 
    4127           0 :         printf("finished random ipc test\n");
    4128             : 
    4129           0 :         return correct;
    4130             : }
    4131             : 
    4132             : 
    4133             : 
    4134           8 : static void browse_callback(const char *sname, uint32_t stype,
    4135             :                             const char *comment, void *state)
    4136             : {
    4137           8 :         printf("\t%20.20s %08x %s\n", sname, stype, comment);
    4138           8 : }
    4139             : 
    4140             : 
    4141             : 
    4142             : /*
    4143             :   This test checks the browse list code
    4144             : 
    4145             : */
    4146           5 : static bool run_browsetest(int dummy)
    4147             : {
    4148           0 :         static struct cli_state *cli;
    4149           5 :         bool correct = True;
    4150             : 
    4151           5 :         printf("starting browse test\n");
    4152             : 
    4153           5 :         if (!torture_open_connection(&cli, 0)) {
    4154           0 :                 return False;
    4155             :         }
    4156             : 
    4157           5 :         printf("domain list:\n");
    4158           5 :         cli_NetServerEnum(cli, cli->server_domain,
    4159             :                           SV_TYPE_DOMAIN_ENUM,
    4160             :                           browse_callback, NULL);
    4161             : 
    4162           5 :         printf("machine list:\n");
    4163           5 :         cli_NetServerEnum(cli, cli->server_domain,
    4164             :                           SV_TYPE_ALL,
    4165             :                           browse_callback, NULL);
    4166             : 
    4167           5 :         if (!torture_close_connection(cli)) {
    4168           0 :                 correct = False;
    4169             :         }
    4170             : 
    4171           5 :         printf("browse test finished\n");
    4172             : 
    4173           5 :         return correct;
    4174             : 
    4175             : }
    4176             : 
    4177          20 : static bool check_attributes(struct cli_state *cli,
    4178             :                                 const char *fname,
    4179             :                                 uint32_t expected_attrs)
    4180             : {
    4181          20 :         uint32_t attrs = 0;
    4182          20 :         NTSTATUS status = cli_getatr(cli,
    4183             :                                 fname,
    4184             :                                 &attrs,
    4185             :                                 NULL,
    4186             :                                 NULL);
    4187          20 :         if (!NT_STATUS_IS_OK(status)) {
    4188           0 :                 printf("cli_getatr failed with %s\n",
    4189             :                         nt_errstr(status));
    4190           0 :                 return false;
    4191             :         }
    4192          20 :         if (attrs != expected_attrs) {
    4193           0 :                 printf("Attributes incorrect 0x%x, should be 0x%x\n",
    4194             :                         (unsigned int)attrs,
    4195             :                         (unsigned int)expected_attrs);
    4196           0 :                 return false;
    4197             :         }
    4198          20 :         return true;
    4199             : }
    4200             : 
    4201             : /*
    4202             :   This checks how the getatr calls works
    4203             : */
    4204           5 : static bool run_attrtest(int dummy)
    4205             : {
    4206           0 :         struct cli_state *cli;
    4207           0 :         uint16_t fnum;
    4208           0 :         time_t t, t2;
    4209           5 :         const char *fname = "\\attrib123456789.tst";
    4210           5 :         bool correct = True;
    4211           0 :         NTSTATUS status;
    4212             : 
    4213           5 :         printf("starting attrib test\n");
    4214             : 
    4215           5 :         if (!torture_open_connection(&cli, 0)) {
    4216           0 :                 return False;
    4217             :         }
    4218             : 
    4219             :         /* Ensure we can't unlink with out-of-range (unknown) attribute. */
    4220           5 :         status = cli_unlink(cli, fname, 0x20000);
    4221           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4222           0 :                 correct = false;
    4223           0 :                 goto out;
    4224             :         }
    4225             : 
    4226           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4227           5 :         cli_openx(cli, fname,
    4228             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4229           5 :         cli_close(cli, fnum);
    4230             : 
    4231           5 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4232           5 :         if (!NT_STATUS_IS_OK(status)) {
    4233           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4234           0 :                 correct = False;
    4235             :         }
    4236             : 
    4237           5 :         if (labs(t - time(NULL)) > 60*60*24*10) {
    4238           0 :                 printf("ERROR: SMBgetatr bug. time is %s",
    4239             :                        ctime(&t));
    4240           0 :                 t = time(NULL);
    4241           0 :                 correct = True;
    4242             :         }
    4243             : 
    4244           5 :         t2 = t-60*60*24; /* 1 day ago */
    4245             : 
    4246             :         /* Ensure we can't set with out-of-range (unknown) attribute. */
    4247           5 :         status = cli_setatr(cli, fname, 0x20000, t2);
    4248           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4249           0 :                 correct = false;
    4250           0 :                 goto out;
    4251             :         }
    4252             : 
    4253           5 :         status = cli_setatr(cli, fname, 0, t2);
    4254           5 :         if (!NT_STATUS_IS_OK(status)) {
    4255           0 :                 printf("setatr failed (%s)\n", nt_errstr(status));
    4256           0 :                 correct = True;
    4257             :         }
    4258             : 
    4259           5 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4260           5 :         if (!NT_STATUS_IS_OK(status)) {
    4261           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4262           0 :                 correct = True;
    4263             :         }
    4264             : 
    4265           5 :         if (t != t2) {
    4266           0 :                 printf("ERROR: getatr/setatr bug. times are\n%s",
    4267             :                        ctime(&t));
    4268           0 :                 printf("%s", ctime(&t2));
    4269           0 :                 correct = True;
    4270             :         }
    4271             : 
    4272           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4273             : 
    4274             :         /* Check cli_setpathinfo_ext() */
    4275             :         /* Re-create the file. */
    4276           5 :         status = cli_openx(cli, fname,
    4277             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4278           5 :         if (!NT_STATUS_IS_OK(status)) {
    4279           0 :                 printf("Failed to recreate %s (%s)\n",
    4280             :                         fname, nt_errstr(status));
    4281           0 :                 correct = false;
    4282             :         }
    4283           5 :         cli_close(cli, fnum);
    4284             : 
    4285           5 :         status = cli_setpathinfo_ext(
    4286             :                 cli,
    4287             :                 fname,
    4288           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4289           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4290           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4291           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4292             :                 FILE_ATTRIBUTE_SYSTEM |
    4293             :                 FILE_ATTRIBUTE_HIDDEN |
    4294             :                 FILE_ATTRIBUTE_READONLY);
    4295           5 :         if (!NT_STATUS_IS_OK(status)) {
    4296           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4297             :                         nt_errstr(status));
    4298           0 :                 correct = false;
    4299             :         }
    4300             : 
    4301             :         /* Check attributes are correct. */
    4302           5 :         correct = check_attributes(cli,
    4303             :                         fname,
    4304             :                         FILE_ATTRIBUTE_SYSTEM |
    4305             :                         FILE_ATTRIBUTE_HIDDEN |
    4306             :                         FILE_ATTRIBUTE_READONLY);
    4307           5 :         if (correct == false) {
    4308           0 :                 goto out;
    4309             :         }
    4310             : 
    4311             :         /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
    4312           5 :         status = cli_setpathinfo_ext(
    4313             :                 cli,
    4314             :                 fname,
    4315           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4316           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4317           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4318           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4319             :                 FILE_ATTRIBUTE_NORMAL);
    4320           5 :         if (!NT_STATUS_IS_OK(status)) {
    4321           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4322             :                         nt_errstr(status));
    4323           0 :                 correct = false;
    4324             :         }
    4325             : 
    4326             :         /* Check attributes are correct. */
    4327           5 :         correct = check_attributes(cli,
    4328             :                         fname,
    4329             :                         FILE_ATTRIBUTE_SYSTEM |
    4330             :                         FILE_ATTRIBUTE_HIDDEN |
    4331             :                         FILE_ATTRIBUTE_READONLY);
    4332           5 :         if (correct == false) {
    4333           0 :                 goto out;
    4334             :         }
    4335             : 
    4336             :         /* Setting to (uint16_t)-1 should also be ignored. */
    4337           5 :         status = cli_setpathinfo_ext(
    4338             :                 cli,
    4339             :                 fname,
    4340           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4341           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4342           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4343           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4344             :                 (uint32_t)-1);
    4345           5 :         if (!NT_STATUS_IS_OK(status)) {
    4346           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4347             :                         nt_errstr(status));
    4348           0 :                 correct = false;
    4349             :         }
    4350             : 
    4351             :         /* Check attributes are correct. */
    4352           5 :         correct = check_attributes(cli,
    4353             :                         fname,
    4354             :                         FILE_ATTRIBUTE_SYSTEM |
    4355             :                         FILE_ATTRIBUTE_HIDDEN |
    4356             :                         FILE_ATTRIBUTE_READONLY);
    4357           5 :         if (correct == false) {
    4358           0 :                 goto out;
    4359             :         }
    4360             : 
    4361             :         /* Setting to 0 should clear them all. */
    4362           5 :         status = cli_setpathinfo_ext(
    4363             :                 cli,
    4364             :                 fname,
    4365           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4366           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4367           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4368           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4369             :                 0);
    4370           5 :         if (!NT_STATUS_IS_OK(status)) {
    4371           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4372             :                         nt_errstr(status));
    4373           0 :                 correct = false;
    4374             :         }
    4375             : 
    4376             :         /* Check attributes are correct. */
    4377           5 :         correct = check_attributes(cli,
    4378             :                         fname,
    4379             :                         FILE_ATTRIBUTE_NORMAL);
    4380           5 :         if (correct == false) {
    4381           0 :                 goto out;
    4382             :         }
    4383             : 
    4384           5 :   out:
    4385             : 
    4386           5 :         cli_unlink(cli,
    4387             :                 fname,
    4388             :                 FILE_ATTRIBUTE_SYSTEM |
    4389             :                 FILE_ATTRIBUTE_HIDDEN|
    4390             :                 FILE_ATTRIBUTE_READONLY);
    4391             : 
    4392           5 :         if (!torture_close_connection(cli)) {
    4393           0 :                 correct = False;
    4394             :         }
    4395             : 
    4396           5 :         printf("attrib test finished\n");
    4397             : 
    4398           5 :         return correct;
    4399             : }
    4400             : 
    4401           5 : static NTSTATUS cli_qfilename(
    4402             :         struct cli_state *cli,
    4403             :         uint16_t fnum,
    4404             :         TALLOC_CTX *mem_ctx,
    4405             :         char **_name)
    4406             : {
    4407           0 :         uint16_t recv_flags2;
    4408           0 :         uint8_t *rdata;
    4409           0 :         uint32_t num_rdata;
    4410           0 :         NTSTATUS status;
    4411           5 :         char *name = NULL;
    4412           0 :         uint32_t namelen;
    4413             : 
    4414           5 :         status = cli_qfileinfo(talloc_tos(),
    4415             :                                cli,
    4416             :                                fnum,
    4417             :                                FSCC_FILE_NAME_INFORMATION,
    4418             :                                4,
    4419             :                                CLI_BUFFER_SIZE,
    4420             :                                &recv_flags2,
    4421             :                                &rdata,
    4422             :                                &num_rdata);
    4423           5 :         if (!NT_STATUS_IS_OK(status)) {
    4424           0 :                 return status;
    4425             :         }
    4426             : 
    4427           5 :         namelen = IVAL(rdata, 0);
    4428           5 :         if (namelen > (num_rdata - 4)) {
    4429           0 :                 TALLOC_FREE(rdata);
    4430           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
    4431             :         }
    4432             : 
    4433           5 :         pull_string_talloc(mem_ctx,
    4434             :                            (const char *)rdata,
    4435             :                            recv_flags2,
    4436             :                            &name,
    4437           5 :                            rdata + 4,
    4438             :                            namelen,
    4439             :                            STR_UNICODE);
    4440           5 :         if (name == NULL) {
    4441           0 :                 status = map_nt_error_from_unix(errno);
    4442           0 :                 TALLOC_FREE(rdata);
    4443           0 :                 return status;
    4444             :         }
    4445             : 
    4446           5 :         *_name = name;
    4447           5 :         TALLOC_FREE(rdata);
    4448           5 :         return NT_STATUS_OK;
    4449             : }
    4450             : 
    4451             : /*
    4452             :   This checks a couple of trans2 calls
    4453             : */
    4454           5 : static bool run_trans2test(int dummy)
    4455             : {
    4456           0 :         struct cli_state *cli;
    4457           0 :         uint16_t fnum;
    4458           0 :         off_t size;
    4459           0 :         time_t c_time, a_time, m_time;
    4460           0 :         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
    4461           5 :         const char *fname = "\\trans2.tst";
    4462           5 :         const char *dname = "\\trans2";
    4463           5 :         const char *fname2 = "\\trans2\\trans2.tst";
    4464           5 :         char *pname = NULL;
    4465           5 :         bool correct = True;
    4466           0 :         NTSTATUS status;
    4467           0 :         uint32_t fs_attr;
    4468           0 :         uint64_t ino;
    4469             : 
    4470           5 :         printf("starting trans2 test\n");
    4471             : 
    4472           5 :         if (!torture_open_connection(&cli, 0)) {
    4473           0 :                 return False;
    4474             :         }
    4475             : 
    4476           5 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4477             :                 /* Ensure ino is zero, SMB2 gets a real one. */
    4478           0 :                 ino = 0;
    4479             :         } else {
    4480             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
    4481           5 :                 ino = (uint64_t)-1;
    4482             :         }
    4483             : 
    4484           5 :         status = cli_get_fs_attr_info(cli, &fs_attr);
    4485           5 :         if (!NT_STATUS_IS_OK(status)) {
    4486           0 :                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
    4487             :                        nt_errstr(status));
    4488           0 :                 correct = false;
    4489             :         }
    4490             : 
    4491           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4492           5 :         cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4493           5 :         status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
    4494             :                                      &a_time_ts, &w_time_ts, &m_time_ts, NULL);
    4495           5 :         if (!NT_STATUS_IS_OK(status)) {
    4496           0 :                 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
    4497           0 :                 correct = False;
    4498             :         }
    4499             : 
    4500           5 :         status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
    4501           5 :         if (!NT_STATUS_IS_OK(status)) {
    4502           0 :                 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
    4503           0 :                 correct = False;
    4504             :         }
    4505           5 :         else if (strcmp(pname, fname)) {
    4506           0 :                 printf("qfilename gave different name? [%s] [%s]\n",
    4507             :                        fname, pname);
    4508           0 :                 correct = False;
    4509             :         }
    4510             : 
    4511           5 :         cli_close(cli, fnum);
    4512             : 
    4513           5 :         sleep(2);
    4514             : 
    4515           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4516           5 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
    4517             :                           &fnum);
    4518           5 :         if (!NT_STATUS_IS_OK(status)) {
    4519           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4520           0 :                 return False;
    4521             :         }
    4522           5 :         cli_close(cli, fnum);
    4523             : 
    4524           5 :         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
    4525             :                                 NULL);
    4526           5 :         if (!NT_STATUS_IS_OK(status)) {
    4527           0 :                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
    4528           0 :                 correct = False;
    4529             :         } else {
    4530           5 :                 time_t t = time(NULL);
    4531             : 
    4532           5 :                 if (c_time != m_time) {
    4533           0 :                         printf("create time=%s", ctime(&c_time));
    4534           0 :                         printf("modify time=%s", ctime(&m_time));
    4535           0 :                         printf("This system appears to have sticky create times\n");
    4536             :                 }
    4537           5 :                 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
    4538           0 :                         printf("access time=%s", ctime(&a_time));
    4539           0 :                         printf("This system appears to set a midnight access time\n");
    4540           0 :                         correct = False;
    4541             :                 }
    4542             : 
    4543           5 :                 if (labs(m_time - t) > 60*60*24*7) {
    4544           0 :                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
    4545           0 :                         correct = False;
    4546             :                 }
    4547             :         }
    4548             : 
    4549             : 
    4550           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4551           5 :         cli_openx(cli, fname,
    4552             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4553           5 :         cli_close(cli, fnum);
    4554           5 :         status = cli_qpathinfo2(cli,
    4555             :                                 fname,
    4556             :                                 &c_time_ts,
    4557             :                                 &a_time_ts,
    4558             :                                 &w_time_ts,
    4559             :                                 &m_time_ts,
    4560             :                                 &size,
    4561             :                                 NULL,
    4562             :                                 &ino,
    4563             :                                 NULL);
    4564           5 :         if (!NT_STATUS_IS_OK(status)) {
    4565           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4566           0 :                 correct = False;
    4567             :         } else {
    4568           5 :                 if (w_time_ts.tv_sec < 60*60*24*2) {
    4569           0 :                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
    4570           0 :                         printf("This system appears to set a initial 0 write time\n");
    4571           0 :                         correct = False;
    4572             :                 }
    4573           5 :                 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4574             :                         /* SMB2 should always return an inode. */
    4575           0 :                         if (ino == 0) {
    4576           0 :                                 printf("SMB2 bad inode (0)\n");
    4577           0 :                                 correct = false;
    4578             :                         }
    4579             :                 } else {
    4580             :                         /* SMB1 must always return zero here. */
    4581           5 :                         if (ino != 0) {
    4582           0 :                                 printf("SMB1 bad inode (!0)\n");
    4583           0 :                                 correct = false;
    4584             :                         }
    4585             :                 }
    4586             :         }
    4587             : 
    4588           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4589             : 
    4590             : 
    4591             :         /* check if the server updates the directory modification time
    4592             :            when creating a new file */
    4593           5 :         status = cli_mkdir(cli, dname);
    4594           5 :         if (!NT_STATUS_IS_OK(status)) {
    4595           0 :                 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
    4596           0 :                 correct = False;
    4597             :         }
    4598           5 :         sleep(3);
    4599           5 :         status = cli_qpathinfo2(cli,
    4600             :                                 "\\trans2\\",
    4601             :                                 &c_time_ts,
    4602             :                                 &a_time_ts,
    4603             :                                 &w_time_ts,
    4604             :                                 &m_time_ts,
    4605             :                                 &size,
    4606             :                                 NULL,
    4607             :                                 NULL,
    4608             :                                 NULL);
    4609           5 :         if (!NT_STATUS_IS_OK(status)) {
    4610           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4611           0 :                 correct = False;
    4612             :         }
    4613             : 
    4614           5 :         cli_openx(cli, fname2,
    4615             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4616           5 :         cli_writeall(cli, fnum,  0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
    4617           5 :         cli_close(cli, fnum);
    4618           5 :         status = cli_qpathinfo2(cli,
    4619             :                                 "\\trans2\\",
    4620             :                                 &c_time_ts,
    4621             :                                 &a_time_ts,
    4622             :                                 &w_time_ts,
    4623             :                                 &m_time2_ts,
    4624             :                                 &size,
    4625             :                                 NULL,
    4626             :                                 NULL,
    4627             :                                 NULL);
    4628           5 :         if (!NT_STATUS_IS_OK(status)) {
    4629           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4630           0 :                 correct = False;
    4631             :         } else {
    4632           5 :                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
    4633             :                     == 0) {
    4634           0 :                         printf("This system does not update directory modification times\n");
    4635           0 :                         correct = False;
    4636             :                 }
    4637             :         }
    4638           5 :         cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4639           5 :         cli_rmdir(cli, dname);
    4640             : 
    4641           5 :         if (!torture_close_connection(cli)) {
    4642           0 :                 correct = False;
    4643             :         }
    4644             : 
    4645           5 :         printf("trans2 test finished\n");
    4646             : 
    4647           5 :         return correct;
    4648             : }
    4649             : 
    4650             : /*
    4651             :   This checks new W2K calls.
    4652             : */
    4653             : 
    4654         180 : static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
    4655             : {
    4656         180 :         uint8_t *buf = NULL;
    4657           0 :         uint32_t len;
    4658           0 :         NTSTATUS status;
    4659             : 
    4660         180 :         status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
    4661             :                                CLI_BUFFER_SIZE, NULL, &buf, &len);
    4662         180 :         if (!NT_STATUS_IS_OK(status)) {
    4663         180 :                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
    4664             :                        nt_errstr(status));
    4665             :         } else {
    4666           0 :                 printf("qfileinfo: level %d, len = %u\n", level, len);
    4667           0 :                 dump_data(0, (uint8_t *)buf, len);
    4668           0 :                 printf("\n");
    4669             :         }
    4670         180 :         TALLOC_FREE(buf);
    4671         180 :         return status;
    4672             : }
    4673             : 
    4674           5 : static bool run_w2ktest(int dummy)
    4675             : {
    4676           0 :         struct cli_state *cli;
    4677           0 :         uint16_t fnum;
    4678           5 :         const char *fname = "\\w2ktest\\w2k.tst";
    4679           0 :         int level;
    4680           5 :         bool correct = True;
    4681             : 
    4682           5 :         printf("starting w2k test\n");
    4683             : 
    4684           5 :         if (!torture_open_connection(&cli, 0)) {
    4685           0 :                 return False;
    4686             :         }
    4687             : 
    4688           5 :         cli_openx(cli, fname,
    4689             :                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
    4690             : 
    4691         185 :         for (level = 1004; level < 1040; level++) {
    4692         180 :                 new_trans(cli, fnum, level);
    4693             :         }
    4694             : 
    4695           5 :         cli_close(cli, fnum);
    4696             : 
    4697           5 :         if (!torture_close_connection(cli)) {
    4698           0 :                 correct = False;
    4699             :         }
    4700             : 
    4701           5 :         printf("w2k test finished\n");
    4702             : 
    4703           5 :         return correct;
    4704             : }
    4705             : 
    4706             : 
    4707             : /*
    4708             :   this is a harness for some oplock tests
    4709             :  */
    4710           5 : static bool run_oplock1(int dummy)
    4711             : {
    4712           0 :         struct cli_state *cli1;
    4713           5 :         const char *fname = "\\lockt1.lck";
    4714           0 :         uint16_t fnum1;
    4715           5 :         bool correct = True;
    4716           0 :         NTSTATUS status;
    4717             : 
    4718           5 :         printf("starting oplock test 1\n");
    4719             : 
    4720           5 :         if (!torture_open_connection(&cli1, 0)) {
    4721           0 :                 return False;
    4722             :         }
    4723             : 
    4724           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4725             : 
    4726           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4727             : 
    4728           5 :         cli1->use_oplocks = True;
    4729             : 
    4730           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4731             :                           &fnum1);
    4732           5 :         if (!NT_STATUS_IS_OK(status)) {
    4733           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4734           0 :                 return False;
    4735             :         }
    4736             : 
    4737           5 :         cli1->use_oplocks = False;
    4738             : 
    4739           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4740           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4741             : 
    4742           5 :         status = cli_close(cli1, fnum1);
    4743           5 :         if (!NT_STATUS_IS_OK(status)) {
    4744           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    4745           0 :                 return False;
    4746             :         }
    4747             : 
    4748           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4749           5 :         if (!NT_STATUS_IS_OK(status)) {
    4750           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4751           0 :                 return False;
    4752             :         }
    4753             : 
    4754           5 :         if (!torture_close_connection(cli1)) {
    4755           0 :                 correct = False;
    4756             :         }
    4757             : 
    4758           5 :         printf("finished oplock test 1\n");
    4759             : 
    4760           5 :         return correct;
    4761             : }
    4762             : 
    4763           4 : static bool run_oplock2(int dummy)
    4764             : {
    4765           0 :         struct cli_state *cli1, *cli2;
    4766           4 :         const char *fname = "\\lockt2.lck";
    4767           0 :         uint16_t fnum1, fnum2;
    4768           4 :         int saved_use_oplocks = use_oplocks;
    4769           0 :         char buf[4];
    4770           4 :         bool correct = True;
    4771           0 :         volatile bool *shared_correct;
    4772           0 :         size_t nread;
    4773           0 :         NTSTATUS status;
    4774             : 
    4775           4 :         shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
    4776           4 :         *shared_correct = True;
    4777             : 
    4778           4 :         use_level_II_oplocks = True;
    4779           4 :         use_oplocks = True;
    4780             : 
    4781           4 :         printf("starting oplock test 2\n");
    4782             : 
    4783           4 :         if (!torture_open_connection(&cli1, 0)) {
    4784           0 :                 use_level_II_oplocks = False;
    4785           0 :                 use_oplocks = saved_use_oplocks;
    4786           0 :                 return False;
    4787             :         }
    4788             : 
    4789           4 :         if (!torture_open_connection(&cli2, 1)) {
    4790           0 :                 use_level_II_oplocks = False;
    4791           0 :                 use_oplocks = saved_use_oplocks;
    4792           0 :                 return False;
    4793             :         }
    4794             : 
    4795           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4796             : 
    4797           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4798           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4799             : 
    4800           4 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4801             :                           &fnum1);
    4802           4 :         if (!NT_STATUS_IS_OK(status)) {
    4803           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4804           0 :                 return False;
    4805             :         }
    4806             : 
    4807             :         /* Don't need the globals any more. */
    4808           4 :         use_level_II_oplocks = False;
    4809           4 :         use_oplocks = saved_use_oplocks;
    4810             : 
    4811           4 :         if (fork() == 0) {
    4812             :                 /* Child code */
    4813           4 :                 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    4814           4 :                 if (!NT_STATUS_IS_OK(status)) {
    4815           0 :                         printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
    4816           0 :                         *shared_correct = False;
    4817           0 :                         exit(0);
    4818             :                 }
    4819             : 
    4820           4 :                 sleep(2);
    4821             : 
    4822           4 :                 status = cli_close(cli2, fnum2);
    4823           4 :                 if (!NT_STATUS_IS_OK(status)) {
    4824           0 :                         printf("close2 failed (%s)\n", nt_errstr(status));
    4825           0 :                         *shared_correct = False;
    4826             :                 }
    4827             : 
    4828           4 :                 exit(0);
    4829             :         }
    4830             : 
    4831           4 :         sleep(2);
    4832             : 
    4833             :         /* Ensure cli1 processes the break. Empty file should always return 0
    4834             :          * bytes.  */
    4835           4 :         status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
    4836           4 :         if (!NT_STATUS_IS_OK(status)) {
    4837           0 :                 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
    4838           0 :                 correct = false;
    4839           4 :         } else if (nread != 0) {
    4840           0 :                 printf("read on empty fnum1 failed. recv %ld expected %d\n",
    4841             :                       (unsigned long)nread, 0);
    4842           0 :                 correct = false;
    4843             :         }
    4844             : 
    4845             :         /* Should now be at level II. */
    4846             :         /* Test if sending a write locks causes a break to none. */
    4847           4 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
    4848           4 :         if (!NT_STATUS_IS_OK(status)) {
    4849           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4850           0 :                 correct = False;
    4851             :         }
    4852             : 
    4853           4 :         cli_unlock(cli1, fnum1, 0, 4);
    4854             : 
    4855           4 :         sleep(2);
    4856             : 
    4857           4 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    4858           4 :         if (!NT_STATUS_IS_OK(status)) {
    4859           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4860           0 :                 correct = False;
    4861             :         }
    4862             : 
    4863           4 :         cli_unlock(cli1, fnum1, 0, 4);
    4864             : 
    4865           4 :         sleep(2);
    4866             : 
    4867           4 :         cli_read(cli1, fnum1, buf, 0, 4, NULL);
    4868             : 
    4869           4 :         status = cli_close(cli1, fnum1);
    4870           4 :         if (!NT_STATUS_IS_OK(status)) {
    4871           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4872           0 :                 correct = False;
    4873             :         }
    4874             : 
    4875           4 :         sleep(4);
    4876             : 
    4877           4 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4878           4 :         if (!NT_STATUS_IS_OK(status)) {
    4879           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4880           0 :                 correct = False;
    4881             :         }
    4882             : 
    4883           4 :         if (!torture_close_connection(cli1)) {
    4884           0 :                 correct = False;
    4885             :         }
    4886             : 
    4887           4 :         if (!*shared_correct) {
    4888           0 :                 correct = False;
    4889             :         }
    4890             : 
    4891           4 :         printf("finished oplock test 2\n");
    4892             : 
    4893           4 :         return correct;
    4894             : }
    4895             : 
    4896             : struct oplock4_state {
    4897             :         struct tevent_context *ev;
    4898             :         struct cli_state *cli;
    4899             :         bool *got_break;
    4900             :         uint16_t *fnum2;
    4901             : };
    4902             : 
    4903             : static void oplock4_got_break(struct tevent_req *req);
    4904             : static void oplock4_got_open(struct tevent_req *req);
    4905             : 
    4906           5 : static bool run_oplock4(int dummy)
    4907             : {
    4908           0 :         struct tevent_context *ev;
    4909           0 :         struct cli_state *cli1, *cli2;
    4910           0 :         struct tevent_req *oplock_req, *open_req;
    4911           5 :         const char *fname = "\\lockt4.lck";
    4912           5 :         const char *fname_ln = "\\lockt4_ln.lck";
    4913           0 :         uint16_t fnum1, fnum2;
    4914           5 :         int saved_use_oplocks = use_oplocks;
    4915           0 :         NTSTATUS status;
    4916           5 :         bool correct = true;
    4917             : 
    4918           0 :         bool got_break;
    4919             : 
    4920           0 :         struct oplock4_state *state;
    4921             : 
    4922           5 :         printf("starting oplock test 4\n");
    4923             : 
    4924           5 :         if (!torture_open_connection(&cli1, 0)) {
    4925           0 :                 use_level_II_oplocks = false;
    4926           0 :                 use_oplocks = saved_use_oplocks;
    4927           0 :                 return false;
    4928             :         }
    4929             : 
    4930           5 :         if (!torture_open_connection(&cli2, 1)) {
    4931           0 :                 use_level_II_oplocks = false;
    4932           0 :                 use_oplocks = saved_use_oplocks;
    4933           0 :                 return false;
    4934             :         }
    4935             : 
    4936           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4937           5 :         cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4938             : 
    4939           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4940           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4941             : 
    4942             :         /* Create the file. */
    4943           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4944             :                           &fnum1);
    4945           5 :         if (!NT_STATUS_IS_OK(status)) {
    4946           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4947           0 :                 return false;
    4948             :         }
    4949             : 
    4950           5 :         status = cli_close(cli1, fnum1);
    4951           5 :         if (!NT_STATUS_IS_OK(status)) {
    4952           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4953           0 :                 return false;
    4954             :         }
    4955             : 
    4956             :         /* Now create a hardlink. */
    4957           5 :         status = cli_hardlink(cli1, fname, fname_ln);
    4958           5 :         if (!NT_STATUS_IS_OK(status)) {
    4959           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    4960           0 :                 return false;
    4961             :         }
    4962             : 
    4963             :         /* Prove that opening hardlinks cause deny modes to conflict. */
    4964           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
    4965           5 :         if (!NT_STATUS_IS_OK(status)) {
    4966           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4967           0 :                 return false;
    4968             :         }
    4969             : 
    4970           5 :         status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
    4971           5 :         if (NT_STATUS_IS_OK(status)) {
    4972           0 :                 printf("open of %s succeeded - should fail with sharing violation.\n",
    4973             :                         fname_ln);
    4974           0 :                 return false;
    4975             :         }
    4976             : 
    4977           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    4978           0 :                 printf("open of %s should fail with sharing violation. Got %s\n",
    4979             :                         fname_ln, nt_errstr(status));
    4980           0 :                 return false;
    4981             :         }
    4982             : 
    4983           5 :         status = cli_close(cli1, fnum1);
    4984           5 :         if (!NT_STATUS_IS_OK(status)) {
    4985           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4986           0 :                 return false;
    4987             :         }
    4988             : 
    4989           5 :         cli1->use_oplocks = true;
    4990           5 :         cli2->use_oplocks = true;
    4991             : 
    4992           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    4993           5 :         if (!NT_STATUS_IS_OK(status)) {
    4994           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4995           0 :                 return false;
    4996             :         }
    4997             : 
    4998           5 :         ev = samba_tevent_context_init(talloc_tos());
    4999           5 :         if (ev == NULL) {
    5000           0 :                 printf("tevent_context_init failed\n");
    5001           0 :                 return false;
    5002             :         }
    5003             : 
    5004           5 :         state = talloc(ev, struct oplock4_state);
    5005           5 :         if (state == NULL) {
    5006           0 :                 printf("talloc failed\n");
    5007           0 :                 return false;
    5008             :         }
    5009           5 :         state->ev = ev;
    5010           5 :         state->cli = cli1;
    5011           5 :         state->got_break = &got_break;
    5012           5 :         state->fnum2 = &fnum2;
    5013             : 
    5014           5 :         oplock_req = cli_smb_oplock_break_waiter_send(
    5015             :                 talloc_tos(), ev, cli1);
    5016           5 :         if (oplock_req == NULL) {
    5017           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    5018           0 :                 return false;
    5019             :         }
    5020           5 :         tevent_req_set_callback(oplock_req, oplock4_got_break, state);
    5021             : 
    5022           5 :         open_req = cli_openx_send(
    5023             :                 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
    5024           5 :         if (open_req == NULL) {
    5025           0 :                 printf("cli_openx_send failed\n");
    5026           0 :                 return false;
    5027             :         }
    5028           5 :         tevent_req_set_callback(open_req, oplock4_got_open, state);
    5029             : 
    5030           5 :         got_break = false;
    5031           5 :         fnum2 = 0xffff;
    5032             : 
    5033          40 :         while (!got_break || fnum2 == 0xffff) {
    5034           0 :                 int ret;
    5035          35 :                 ret = tevent_loop_once(ev);
    5036          35 :                 if (ret == -1) {
    5037           0 :                         printf("tevent_loop_once failed: %s\n",
    5038           0 :                                strerror(errno));
    5039           0 :                         return false;
    5040             :                 }
    5041             :         }
    5042             : 
    5043           5 :         status = cli_close(cli2, fnum2);
    5044           5 :         if (!NT_STATUS_IS_OK(status)) {
    5045           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    5046           0 :                 correct = false;
    5047             :         }
    5048             : 
    5049           5 :         status = cli_close(cli1, fnum1);
    5050           5 :         if (!NT_STATUS_IS_OK(status)) {
    5051           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    5052           0 :                 correct = false;
    5053             :         }
    5054             : 
    5055           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5056           5 :         if (!NT_STATUS_IS_OK(status)) {
    5057           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    5058           0 :                 correct = false;
    5059             :         }
    5060             : 
    5061           5 :         status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5062           5 :         if (!NT_STATUS_IS_OK(status)) {
    5063           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    5064           0 :                 correct = false;
    5065             :         }
    5066             : 
    5067           5 :         if (!torture_close_connection(cli1)) {
    5068           0 :                 correct = false;
    5069             :         }
    5070             : 
    5071           5 :         if (!got_break) {
    5072           0 :                 correct = false;
    5073             :         }
    5074             : 
    5075           5 :         printf("finished oplock test 4\n");
    5076             : 
    5077           5 :         return correct;
    5078             : }
    5079             : 
    5080           5 : static void oplock4_got_break(struct tevent_req *req)
    5081             : {
    5082           5 :         struct oplock4_state *state = tevent_req_callback_data(
    5083             :                 req, struct oplock4_state);
    5084           0 :         uint16_t fnum;
    5085           0 :         uint8_t level;
    5086           0 :         NTSTATUS status;
    5087             : 
    5088           5 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    5089           5 :         TALLOC_FREE(req);
    5090           5 :         if (!NT_STATUS_IS_OK(status)) {
    5091           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    5092             :                        nt_errstr(status));
    5093           0 :                 return;
    5094             :         }
    5095           5 :         *state->got_break = true;
    5096             : 
    5097           5 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    5098             :                                   NO_OPLOCK);
    5099           5 :         if (req == NULL) {
    5100           0 :                 printf("cli_oplock_ack_send failed\n");
    5101           0 :                 return;
    5102             :         }
    5103             : }
    5104             : 
    5105           5 : static void oplock4_got_open(struct tevent_req *req)
    5106             : {
    5107           5 :         struct oplock4_state *state = tevent_req_callback_data(
    5108             :                 req, struct oplock4_state);
    5109           0 :         NTSTATUS status;
    5110             : 
    5111           5 :         status = cli_openx_recv(req, state->fnum2);
    5112           5 :         if (!NT_STATUS_IS_OK(status)) {
    5113           0 :                 printf("cli_openx_recv returned %s\n", nt_errstr(status));
    5114           0 :                 *state->fnum2 = 0xffff;
    5115             :         }
    5116           5 : }
    5117             : 
    5118             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
    5119             : 
    5120             : struct oplock5_state {
    5121             :         int pipe_down_fd;
    5122             : };
    5123             : 
    5124             : /*
    5125             :  * Async open the file that has a kernel oplock, do an echo to get
    5126             :  * that 100% across, close the file to signal to the child fd that the
    5127             :  * oplock can be dropped, wait for the open reply.
    5128             :  */
    5129             : 
    5130             : static void oplock5_opened(struct tevent_req *subreq);
    5131             : static void oplock5_pong(struct tevent_req *subreq);
    5132             : static void oplock5_timedout(struct tevent_req *subreq);
    5133             : 
    5134           1 : static struct tevent_req *oplock5_send(
    5135             :         TALLOC_CTX *mem_ctx,
    5136             :         struct tevent_context *ev,
    5137             :         struct cli_state *cli,
    5138             :         const char *fname,
    5139             :         int pipe_down_fd)
    5140             : {
    5141           1 :         struct tevent_req *req = NULL, *subreq = NULL;
    5142           1 :         struct oplock5_state *state = NULL;
    5143           0 :         static uint8_t data = 0;
    5144             : 
    5145           1 :         req = tevent_req_create(mem_ctx, &state, struct oplock5_state);
    5146           1 :         if (req == NULL) {
    5147           0 :                 return NULL;
    5148             :         }
    5149           1 :         state->pipe_down_fd = pipe_down_fd;
    5150             : 
    5151           1 :         subreq = cli_ntcreate_send(
    5152             :                 state,
    5153             :                 ev,
    5154             :                 cli,
    5155             :                 fname,
    5156             :                 0,                      /* CreatFlags */
    5157             :                 SEC_FILE_READ_DATA,    /* DesiredAccess */
    5158             :                 FILE_ATTRIBUTE_NORMAL,  /* FileAttributes */
    5159             :                 FILE_SHARE_WRITE|FILE_SHARE_READ, /* ShareAccess */
    5160             :                 FILE_OPEN,               /* CreateDisposition */
    5161             :                 FILE_NON_DIRECTORY_FILE, /* CreateOptions */
    5162             :                 0,                       /* Impersonation */
    5163             :                 0);                      /* SecurityFlags */
    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_opened, req);
    5168             : 
    5169           1 :         subreq = cli_echo_send(
    5170             :                 state,
    5171             :                 ev,
    5172             :                 cli,
    5173             :                 1,
    5174           1 :                 (DATA_BLOB) { .data = &data, .length = sizeof(data) });
    5175           1 :         if (tevent_req_nomem(subreq, req)) {
    5176           0 :                 return tevent_req_post(req, ev);
    5177             :         }
    5178           1 :         tevent_req_set_callback(subreq, oplock5_pong, req);
    5179             : 
    5180           1 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(20, 0));
    5181           1 :         if (tevent_req_nomem(subreq, req)) {
    5182           0 :                 return tevent_req_post(req, ev);
    5183             :         }
    5184           1 :         tevent_req_set_callback(subreq, oplock5_timedout, req);
    5185             : 
    5186           1 :         return req;
    5187             : }
    5188             : 
    5189           1 : static void oplock5_opened(struct tevent_req *subreq)
    5190             : {
    5191           1 :         struct tevent_req *req = tevent_req_callback_data(
    5192             :                 subreq, struct tevent_req);
    5193           0 :         NTSTATUS status;
    5194           0 :         uint16_t fnum;
    5195             : 
    5196           1 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
    5197           1 :         TALLOC_FREE(subreq);
    5198           1 :         if (tevent_req_nterror(req, status)) {
    5199           0 :                 return;
    5200             :         }
    5201           1 :         tevent_req_done(req);
    5202             : }
    5203             : 
    5204           1 : static void oplock5_pong(struct tevent_req *subreq)
    5205             : {
    5206           1 :         struct tevent_req *req = tevent_req_callback_data(
    5207             :                 subreq, struct tevent_req);
    5208           1 :         struct oplock5_state *state = tevent_req_data(
    5209             :                 req, struct oplock5_state);
    5210           0 :         NTSTATUS status;
    5211             : 
    5212           1 :         status = cli_echo_recv(subreq);
    5213           1 :         TALLOC_FREE(subreq);
    5214           1 :         if (tevent_req_nterror(req, status)) {
    5215           0 :                 return;
    5216             :         }
    5217             : 
    5218           1 :         close(state->pipe_down_fd);
    5219             : }
    5220             : 
    5221           0 : static void oplock5_timedout(struct tevent_req *subreq)
    5222             : {
    5223           0 :         struct tevent_req *req = tevent_req_callback_data(
    5224             :                 subreq, struct tevent_req);
    5225           0 :         bool ok;
    5226             : 
    5227           0 :         ok = tevent_wakeup_recv(subreq);
    5228           0 :         TALLOC_FREE(subreq);
    5229           0 :         if (!ok) {
    5230           0 :                 tevent_req_oom(req);
    5231           0 :                 return;
    5232             :         }
    5233           0 :         tevent_req_nterror(req, NT_STATUS_TIMEOUT);
    5234             : }
    5235             : 
    5236           1 : static NTSTATUS oplock5_recv(struct tevent_req *req)
    5237             : {
    5238           1 :         return tevent_req_simple_recv_ntstatus(req);
    5239             : }
    5240             : 
    5241           1 : static bool run_oplock5(int dummy)
    5242             : {
    5243           1 :         struct tevent_context *ev = NULL;
    5244           1 :         struct tevent_req *req = NULL;
    5245           1 :         struct cli_state *cli = NULL;
    5246           1 :         const char *fname = "oplock5.txt";
    5247           0 :         int pipe_down[2], pipe_up[2];
    5248           0 :         pid_t child_pid;
    5249           1 :         uint8_t c = '\0';
    5250           0 :         NTSTATUS status;
    5251           0 :         int ret;
    5252           0 :         bool ok;
    5253             : 
    5254           1 :         printf("starting oplock5\n");
    5255             : 
    5256           1 :         if (local_path == NULL) {
    5257           0 :                 d_fprintf(stderr, "oplock5 must be given a local path via "
    5258             :                           "-l <localpath>\n");
    5259           0 :                 return false;
    5260             :         }
    5261             : 
    5262           1 :         ret = pipe(pipe_down);
    5263           1 :         if (ret == -1) {
    5264           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    5265           0 :                 return false;
    5266             :         }
    5267           1 :         ret = pipe(pipe_up);
    5268           1 :         if (ret == -1) {
    5269           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    5270           0 :                 return false;
    5271             :         }
    5272             : 
    5273           1 :         child_pid = fork();
    5274           2 :         if (child_pid == -1) {
    5275           0 :                 d_fprintf(stderr, "fork() failed: %s\n", strerror(errno));
    5276           0 :                 return false;
    5277             :         }
    5278             : 
    5279           2 :         if (child_pid == 0) {
    5280           1 :                 char *local_file = NULL;
    5281           0 :                 int fd;
    5282             : 
    5283           1 :                 close(pipe_down[1]);
    5284           1 :                 close(pipe_up[0]);
    5285             : 
    5286           1 :                 local_file = talloc_asprintf(
    5287           1 :                         talloc_tos(), "%s/%s", local_path, fname);
    5288           1 :                 if (local_file == 0) {
    5289           0 :                         c = 1;
    5290           0 :                         goto do_write;
    5291             :                 }
    5292           1 :                 fd = open(local_file, O_RDWR|O_CREAT, 0644);
    5293           1 :                 if (fd == -1) {
    5294           0 :                         d_fprintf(stderr,
    5295             :                                   "open(%s) in child failed: %s\n",
    5296             :                                   local_file,
    5297           0 :                                   strerror(errno));
    5298           0 :                         c = 2;
    5299           0 :                         goto do_write;
    5300             :                 }
    5301             : 
    5302           1 :                 signal(SIGIO, SIG_IGN);
    5303             : 
    5304           1 :                 ret = fcntl(fd, F_SETLEASE, F_WRLCK);
    5305           1 :                 if (ret == -1) {
    5306           0 :                         d_fprintf(stderr,
    5307             :                                   "SETLEASE in child failed: %s\n",
    5308           0 :                                   strerror(errno));
    5309           0 :                         c = 3;
    5310           0 :                         goto do_write;
    5311             :                 }
    5312             : 
    5313           1 :         do_write:
    5314           1 :                 ret = sys_write(pipe_up[1], &c, sizeof(c));
    5315           1 :                 if (ret == -1) {
    5316           0 :                         d_fprintf(stderr,
    5317             :                                   "sys_write failed: %s\n",
    5318           0 :                                   strerror(errno));
    5319           0 :                         exit(4);
    5320             :                 }
    5321           1 :                 ret = sys_read(pipe_down[0], &c, sizeof(c));
    5322           1 :                 if (ret == -1) {
    5323           0 :                         d_fprintf(stderr,
    5324             :                                   "sys_read failed: %s\n",
    5325           0 :                                   strerror(errno));
    5326           0 :                         exit(5);
    5327             :                 }
    5328           1 :                 exit(0);
    5329             :         }
    5330             : 
    5331           1 :         close(pipe_up[1]);
    5332           1 :         close(pipe_down[0]);
    5333             : 
    5334           1 :         ret = sys_read(pipe_up[0], &c, sizeof(c));
    5335           1 :         if (ret != 1) {
    5336           0 :                 d_fprintf(stderr,
    5337             :                           "sys_read failed: %s\n",
    5338           0 :                           strerror(errno));
    5339           0 :                 return false;
    5340             :         }
    5341           1 :         if (c != 0) {
    5342           0 :                 d_fprintf(stderr, "got error code %"PRIu8"\n", c);
    5343           0 :                 return false;
    5344             :         }
    5345             : 
    5346           1 :         ok = torture_open_connection(&cli, 0);
    5347           1 :         if (!ok) {
    5348           0 :                 d_fprintf(stderr, "torture_open_connection failed\n");
    5349           0 :                 return false;
    5350             :         }
    5351             : 
    5352           1 :         ev = samba_tevent_context_init(talloc_tos());
    5353           1 :         if (ev == NULL) {
    5354           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    5355           0 :                 return false;
    5356             :         }
    5357             : 
    5358           1 :         req = oplock5_send(ev, ev, cli, fname, pipe_down[1]);
    5359           1 :         if (req == NULL) {
    5360           0 :                 d_fprintf(stderr, "oplock5_send failed\n");
    5361           0 :                 return false;
    5362             :         }
    5363             : 
    5364           1 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    5365           1 :         if (!ok) {
    5366           0 :                 d_fprintf(stderr,
    5367             :                           "tevent_req_poll_ntstatus failed: %s\n",
    5368             :                           nt_errstr(status));
    5369           0 :                 return false;
    5370             :         }
    5371             : 
    5372           1 :         status = oplock5_recv(req);
    5373           1 :         TALLOC_FREE(req);
    5374           1 :         if (!NT_STATUS_IS_OK(status)) {
    5375           0 :                 d_fprintf(stderr,
    5376             :                           "oplock5 failed: %s\n",
    5377             :                           nt_errstr(status));
    5378           0 :                 return false;
    5379             :         }
    5380             : 
    5381           1 :         return true;
    5382             : }
    5383             : 
    5384             : #endif /* HAVE_KERNEL_OPLOCKS_LINUX */
    5385             : 
    5386             : /*
    5387             :   Test delete on close semantics.
    5388             :  */
    5389           5 : static bool run_deletetest(int dummy)
    5390             : {
    5391           5 :         struct cli_state *cli1 = NULL;
    5392           5 :         struct cli_state *cli2 = NULL;
    5393           5 :         const char *fname = "\\delete.file";
    5394           5 :         uint16_t fnum1 = (uint16_t)-1;
    5395           5 :         uint16_t fnum2 = (uint16_t)-1;
    5396           5 :         bool correct = false;
    5397           0 :         NTSTATUS status;
    5398             : 
    5399           5 :         printf("starting delete test\n");
    5400             : 
    5401           5 :         if (!torture_open_connection(&cli1, 0)) {
    5402           0 :                 return False;
    5403             :         }
    5404             : 
    5405           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5406             : 
    5407             :         /* Test 1 - this should delete the file on close. */
    5408             : 
    5409           5 :         cli_setatr(cli1, fname, 0, 0);
    5410           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5411             : 
    5412           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    5413             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5414             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5415           5 :         if (!NT_STATUS_IS_OK(status)) {
    5416           0 :                 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
    5417           0 :                 goto fail;
    5418             :         }
    5419             : 
    5420           5 :         status = cli_close(cli1, fnum1);
    5421           5 :         if (!NT_STATUS_IS_OK(status)) {
    5422           0 :                 printf("[1] close failed (%s)\n", nt_errstr(status));
    5423           0 :                 goto fail;
    5424             :         }
    5425             : 
    5426           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    5427           5 :         if (NT_STATUS_IS_OK(status)) {
    5428           0 :                 printf("[1] open of %s succeeded (should fail)\n", fname);
    5429           0 :                 goto fail;
    5430             :         }
    5431             : 
    5432           5 :         printf("first delete on close test succeeded.\n");
    5433             : 
    5434             :         /* Test 2 - this should delete the file on close. */
    5435             : 
    5436           5 :         cli_setatr(cli1, fname, 0, 0);
    5437           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5438             : 
    5439           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5440             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5441             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5442           5 :         if (!NT_STATUS_IS_OK(status)) {
    5443           0 :                 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
    5444           0 :                 goto fail;
    5445             :         }
    5446             : 
    5447           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5448           5 :         if (!NT_STATUS_IS_OK(status)) {
    5449           0 :                 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5450           0 :                 goto fail;
    5451             :         }
    5452             : 
    5453           5 :         status = cli_close(cli1, fnum1);
    5454           5 :         if (!NT_STATUS_IS_OK(status)) {
    5455           0 :                 printf("[2] close failed (%s)\n", nt_errstr(status));
    5456           0 :                 goto fail;
    5457             :         }
    5458             : 
    5459           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5460           5 :         if (NT_STATUS_IS_OK(status)) {
    5461           0 :                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
    5462           0 :                 status = cli_close(cli1, fnum1);
    5463           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5464           0 :                         printf("[2] close failed (%s)\n", nt_errstr(status));
    5465             :                 }
    5466           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5467           0 :                 goto fail;
    5468             :         }
    5469             : 
    5470           5 :         printf("second delete on close test succeeded.\n");
    5471             : 
    5472             :         /* Test 3 - ... */
    5473           5 :         cli_setatr(cli1, fname, 0, 0);
    5474           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5475             : 
    5476           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5477             :                               FILE_ATTRIBUTE_NORMAL,
    5478             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5479             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5480           5 :         if (!NT_STATUS_IS_OK(status)) {
    5481           0 :                 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5482           0 :                 goto fail;
    5483             :         }
    5484             : 
    5485             :         /* This should fail with a sharing violation - open for delete is only compatible
    5486             :            with SHARE_DELETE. */
    5487             : 
    5488           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5489             :                               FILE_ATTRIBUTE_NORMAL,
    5490             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5491             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5492           5 :         if (NT_STATUS_IS_OK(status)) {
    5493           0 :                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
    5494           0 :                 goto fail;
    5495             :         }
    5496             : 
    5497             :         /* This should succeed. */
    5498           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5499             :                              FILE_ATTRIBUTE_NORMAL,
    5500             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5501             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5502           5 :         if (!NT_STATUS_IS_OK(status)) {
    5503           0 :                 printf("[3] open  - 3 of %s failed (%s)\n", fname, nt_errstr(status));
    5504           0 :                 goto fail;
    5505             :         }
    5506             : 
    5507           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5508           5 :         if (!NT_STATUS_IS_OK(status)) {
    5509           0 :                 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5510           0 :                 goto fail;
    5511             :         }
    5512             : 
    5513           5 :         status = cli_close(cli1, fnum1);
    5514           5 :         if (!NT_STATUS_IS_OK(status)) {
    5515           0 :                 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
    5516           0 :                 goto fail;
    5517             :         }
    5518             : 
    5519           5 :         status = cli_close(cli1, fnum2);
    5520           5 :         if (!NT_STATUS_IS_OK(status)) {
    5521           0 :                 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
    5522           0 :                 goto fail;
    5523             :         }
    5524             : 
    5525             :         /* This should fail - file should no longer be there. */
    5526             : 
    5527           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5528           5 :         if (NT_STATUS_IS_OK(status)) {
    5529           0 :                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
    5530           0 :                 status = cli_close(cli1, fnum1);
    5531           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5532           0 :                         printf("[3] close failed (%s)\n", nt_errstr(status));
    5533             :                 }
    5534           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5535           0 :                 goto fail;
    5536             :         }
    5537             : 
    5538           5 :         printf("third delete on close test succeeded.\n");
    5539             : 
    5540             :         /* Test 4 ... */
    5541           5 :         cli_setatr(cli1, fname, 0, 0);
    5542           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5543             : 
    5544           5 :         status = cli_ntcreate(cli1, fname, 0,
    5545             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5546             :                               FILE_ATTRIBUTE_NORMAL,
    5547             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5548             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5549           5 :         if (!NT_STATUS_IS_OK(status)) {
    5550           0 :                 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
    5551           0 :                 goto fail;
    5552             :         }
    5553             : 
    5554             :         /* This should succeed. */
    5555           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5556             :                              FILE_ATTRIBUTE_NORMAL,
    5557             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5558             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5559           5 :         if (!NT_STATUS_IS_OK(status)) {
    5560           0 :                 printf("[4] open  - 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5561           0 :                 goto fail;
    5562             :         }
    5563             : 
    5564           5 :         status = cli_close(cli1, fnum2);
    5565           5 :         if (!NT_STATUS_IS_OK(status)) {
    5566           0 :                 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
    5567           0 :                 goto fail;
    5568             :         }
    5569             : 
    5570           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5571           5 :         if (!NT_STATUS_IS_OK(status)) {
    5572           0 :                 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5573           0 :                 goto fail;
    5574             :         }
    5575             : 
    5576             :         /* This should fail - no more opens once delete on close set. */
    5577           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5578             :                               FILE_ATTRIBUTE_NORMAL,
    5579             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5580             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5581           5 :         if (NT_STATUS_IS_OK(status)) {
    5582           0 :                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
    5583           0 :                 goto fail;
    5584             :         }
    5585             : 
    5586           5 :         status = cli_close(cli1, fnum1);
    5587           5 :         if (!NT_STATUS_IS_OK(status)) {
    5588           0 :                 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
    5589           0 :                 goto fail;
    5590             :         }
    5591             : 
    5592           5 :         printf("fourth delete on close test succeeded.\n");
    5593             : 
    5594             :         /* Test 5 ... */
    5595           5 :         cli_setatr(cli1, fname, 0, 0);
    5596           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5597             : 
    5598           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
    5599           5 :         if (!NT_STATUS_IS_OK(status)) {
    5600           0 :                 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
    5601           0 :                 goto fail;
    5602             :         }
    5603             : 
    5604             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5605             : 
    5606           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5607           5 :         if (NT_STATUS_IS_OK(status)) {
    5608           0 :                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
    5609           0 :                 goto fail;
    5610             :         }
    5611             : 
    5612           5 :         status = cli_close(cli1, fnum1);
    5613           5 :         if (!NT_STATUS_IS_OK(status)) {
    5614           0 :                 printf("[5] close failed (%s)\n", nt_errstr(status));
    5615           0 :                 goto fail;
    5616             :         }
    5617             : 
    5618           5 :         printf("fifth delete on close test succeeded.\n");
    5619             : 
    5620             :         /* Test 6 ... */
    5621           5 :         cli_setatr(cli1, fname, 0, 0);
    5622           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5623             : 
    5624           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5625             :                              FILE_ATTRIBUTE_NORMAL,
    5626             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5627             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5628           5 :         if (!NT_STATUS_IS_OK(status)) {
    5629           0 :                 printf("[6] open of %s failed (%s)\n", fname,
    5630             :                        nt_errstr(status));
    5631           0 :                 goto fail;
    5632             :         }
    5633             : 
    5634             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5635             : 
    5636           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5637           5 :         if (NT_STATUS_IS_OK(status)) {
    5638           0 :                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
    5639           0 :                 goto fail;
    5640             :         }
    5641             : 
    5642           5 :         status = cli_close(cli1, fnum1);
    5643           5 :         if (!NT_STATUS_IS_OK(status)) {
    5644           0 :                 printf("[6] close failed (%s)\n", nt_errstr(status));
    5645           0 :                 goto fail;
    5646             :         }
    5647             : 
    5648           5 :         printf("sixth delete on close test succeeded.\n");
    5649             : 
    5650             :         /* Test 7 ... */
    5651           5 :         cli_setatr(cli1, fname, 0, 0);
    5652           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5653             : 
    5654           5 :         status = cli_ntcreate(cli1, fname, 0,
    5655             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5656             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5657             :                               0, 0, &fnum1, NULL);
    5658           5 :         if (!NT_STATUS_IS_OK(status)) {
    5659           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5660           0 :                 goto fail;
    5661             :         }
    5662             : 
    5663           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5664           5 :         if (!NT_STATUS_IS_OK(status)) {
    5665           0 :                 printf("[7] setting delete_on_close on file failed !\n");
    5666           0 :                 goto fail;
    5667             :         }
    5668             : 
    5669           5 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5670           5 :         if (!NT_STATUS_IS_OK(status)) {
    5671           0 :                 printf("[7] unsetting delete_on_close on file failed !\n");
    5672           0 :                 goto fail;
    5673             :         }
    5674             : 
    5675           5 :         status = cli_close(cli1, fnum1);
    5676           5 :         if (!NT_STATUS_IS_OK(status)) {
    5677           0 :                 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
    5678           0 :                 goto fail;
    5679             :         }
    5680             : 
    5681             :         /* This next open should succeed - we reset the flag. */
    5682           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5683           5 :         if (!NT_STATUS_IS_OK(status)) {
    5684           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5685           0 :                 goto fail;
    5686             :         }
    5687             : 
    5688           5 :         status = cli_close(cli1, fnum1);
    5689           5 :         if (!NT_STATUS_IS_OK(status)) {
    5690           0 :                 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
    5691           0 :                 goto fail;
    5692             :         }
    5693             : 
    5694           5 :         printf("seventh delete on close test succeeded.\n");
    5695             : 
    5696             :         /* Test 8 ... */
    5697           5 :         cli_setatr(cli1, fname, 0, 0);
    5698           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5699             : 
    5700           5 :         if (!torture_open_connection(&cli2, 1)) {
    5701           0 :                 printf("[8] failed to open second connection.\n");
    5702           0 :                 goto fail;
    5703             :         }
    5704             : 
    5705           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5706             : 
    5707           5 :         status = cli_ntcreate(cli1, fname, 0,
    5708             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5709             :                              FILE_ATTRIBUTE_NORMAL,
    5710             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5711             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5712           5 :         if (!NT_STATUS_IS_OK(status)) {
    5713           0 :                 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5714           0 :                 goto fail;
    5715             :         }
    5716             : 
    5717           5 :         status = cli_ntcreate(cli2, fname, 0,
    5718             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5719             :                              FILE_ATTRIBUTE_NORMAL,
    5720             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5721             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5722           5 :         if (!NT_STATUS_IS_OK(status)) {
    5723           0 :                 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5724           0 :                 goto fail;
    5725             :         }
    5726             : 
    5727           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5728           5 :         if (!NT_STATUS_IS_OK(status)) {
    5729           0 :                 printf("[8] setting delete_on_close on file failed !\n");
    5730           0 :                 goto fail;
    5731             :         }
    5732             : 
    5733           5 :         status = cli_close(cli1, fnum1);
    5734           5 :         if (!NT_STATUS_IS_OK(status)) {
    5735           0 :                 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
    5736           0 :                 goto fail;
    5737             :         }
    5738             : 
    5739           5 :         status = cli_close(cli2, fnum2);
    5740           5 :         if (!NT_STATUS_IS_OK(status)) {
    5741           0 :                 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
    5742           0 :                 goto fail;
    5743             :         }
    5744             : 
    5745             :         /* This should fail.. */
    5746           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5747           5 :         if (NT_STATUS_IS_OK(status)) {
    5748           0 :                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
    5749           0 :                 goto fail;
    5750             :         }
    5751             : 
    5752           5 :         printf("eighth delete on close test succeeded.\n");
    5753             : 
    5754             :         /* Test 9 ... */
    5755             : 
    5756             :         /* This should fail - we need to set DELETE_ACCESS. */
    5757           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5758             :                               FILE_ATTRIBUTE_NORMAL,
    5759             :                               FILE_SHARE_NONE,
    5760             :                               FILE_OVERWRITE_IF,
    5761             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5762           5 :         if (NT_STATUS_IS_OK(status)) {
    5763           0 :                 printf("[9] open of %s succeeded should have failed!\n", fname);
    5764           0 :                 goto fail;
    5765             :         }
    5766             : 
    5767           5 :         printf("ninth delete on close test succeeded.\n");
    5768             : 
    5769             :         /* Test 10 ... */
    5770             : 
    5771           5 :         status = cli_ntcreate(cli1, fname, 0,
    5772             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5773             :                              FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5774             :                              FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
    5775             :                              0, &fnum1, NULL);
    5776           5 :         if (!NT_STATUS_IS_OK(status)) {
    5777           0 :                 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
    5778           0 :                 goto fail;
    5779             :         }
    5780             : 
    5781             :         /* This should delete the file. */
    5782           5 :         status = cli_close(cli1, fnum1);
    5783           5 :         if (!NT_STATUS_IS_OK(status)) {
    5784           0 :                 printf("[10] close failed (%s)\n", nt_errstr(status));
    5785           0 :                 goto fail;
    5786             :         }
    5787             : 
    5788             :         /* This should fail.. */
    5789           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5790           5 :         if (NT_STATUS_IS_OK(status)) {
    5791           0 :                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
    5792           0 :                 goto fail;
    5793             :         }
    5794             : 
    5795           5 :         printf("tenth delete on close test succeeded.\n");
    5796             : 
    5797             :         /* Test 11 ... */
    5798             : 
    5799           5 :         cli_setatr(cli1, fname, 0, 0);
    5800           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5801             : 
    5802             :         /* Can we open a read-only file with delete access? */
    5803             : 
    5804             :         /* Create a readonly file. */
    5805           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5806             :                               FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
    5807             :                               FILE_OVERWRITE_IF, 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 :         status = cli_close(cli1, fnum1);
    5814           5 :         if (!NT_STATUS_IS_OK(status)) {
    5815           0 :                 printf("[11] close failed (%s)\n", nt_errstr(status));
    5816           0 :                 goto fail;
    5817             :         }
    5818             : 
    5819             :         /* Now try open for delete access. */
    5820           5 :         status = cli_ntcreate(cli1, fname, 0,
    5821             :                              FILE_READ_ATTRIBUTES|DELETE_ACCESS,
    5822             :                              0,
    5823             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5824             :                              FILE_OPEN, 0, 0, &fnum1, NULL);
    5825           5 :         if (!NT_STATUS_IS_OK(status)) {
    5826           0 :                 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
    5827           0 :                 goto fail;
    5828             :         }
    5829             : 
    5830           5 :         cli_close(cli1, fnum1);
    5831             : 
    5832           5 :         printf("eleventh delete on close test succeeded.\n");
    5833             : 
    5834             :         /*
    5835             :          * Test 12
    5836             :          * like test 4 but with initial delete on close
    5837             :          */
    5838             : 
    5839           5 :         cli_setatr(cli1, fname, 0, 0);
    5840           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5841             : 
    5842           5 :         status = cli_ntcreate(cli1, fname, 0,
    5843             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5844             :                               FILE_ATTRIBUTE_NORMAL,
    5845             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5846             :                               FILE_OVERWRITE_IF,
    5847             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5848           5 :         if (!NT_STATUS_IS_OK(status)) {
    5849           0 :                 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5850           0 :                 goto fail;
    5851             :         }
    5852             : 
    5853           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5854             :                               FILE_ATTRIBUTE_NORMAL,
    5855             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5856             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5857           5 :         if (!NT_STATUS_IS_OK(status)) {
    5858           0 :                 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
    5859           0 :                 goto fail;
    5860             :         }
    5861             : 
    5862           5 :         status = cli_close(cli1, fnum2);
    5863           5 :         if (!NT_STATUS_IS_OK(status)) {
    5864           0 :                 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
    5865           0 :                 goto fail;
    5866             :         }
    5867             : 
    5868           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5869           5 :         if (!NT_STATUS_IS_OK(status)) {
    5870           0 :                 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5871           0 :                 goto fail;
    5872             :         }
    5873             : 
    5874             :         /* This should fail - no more opens once delete on close set. */
    5875           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5876             :                               FILE_ATTRIBUTE_NORMAL,
    5877             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5878             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5879           5 :         if (NT_STATUS_IS_OK(status)) {
    5880           0 :                 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
    5881           0 :                 goto fail;
    5882             :         }
    5883             : 
    5884           5 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5885           5 :         if (!NT_STATUS_IS_OK(status)) {
    5886           0 :                 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
    5887           0 :                 goto fail;
    5888             :         }
    5889             : 
    5890           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5891             :                               FILE_ATTRIBUTE_NORMAL,
    5892             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5893             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5894           5 :         if (!NT_STATUS_IS_OK(status)) {
    5895           0 :                 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
    5896           0 :                 goto fail;
    5897             :         }
    5898             : 
    5899           5 :         status = cli_close(cli1, fnum2);
    5900           5 :         if (!NT_STATUS_IS_OK(status)) {
    5901           0 :                 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
    5902           0 :                 goto fail;
    5903             :         }
    5904             : 
    5905           5 :         status = cli_close(cli1, fnum1);
    5906           5 :         if (!NT_STATUS_IS_OK(status)) {
    5907           0 :                 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
    5908           0 :                 goto fail;
    5909             :         }
    5910             : 
    5911             :         /*
    5912             :          * setting delete on close on the handle does
    5913             :          * not unset the initial delete on close...
    5914             :          */
    5915           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5916             :                               FILE_ATTRIBUTE_NORMAL,
    5917             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5918             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5919           5 :         if (NT_STATUS_IS_OK(status)) {
    5920           0 :                 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
    5921           0 :                 goto fail;
    5922           5 :         } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5923           0 :                 printf("ntcreate returned %s, expected "
    5924             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
    5925             :                        nt_errstr(status));
    5926           0 :                 goto fail;
    5927             :         }
    5928             : 
    5929           5 :         printf("twelfth delete on close test succeeded.\n");
    5930             : 
    5931             : 
    5932           5 :         printf("finished delete test\n");
    5933             : 
    5934           5 :         correct = true;
    5935             : 
    5936           5 :   fail:
    5937             :         /* FIXME: This will crash if we aborted before cli2 got
    5938             :          * initialized, because these functions don't handle
    5939             :          * uninitialized connections. */
    5940             : 
    5941           5 :         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
    5942           5 :         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
    5943           5 :         cli_setatr(cli1, fname, 0, 0);
    5944           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5945             : 
    5946           5 :         if (cli1 && !torture_close_connection(cli1)) {
    5947           0 :                 correct = False;
    5948             :         }
    5949           5 :         if (cli2 && !torture_close_connection(cli2)) {
    5950           0 :                 correct = False;
    5951             :         }
    5952           5 :         return correct;
    5953             : }
    5954             : 
    5955             : struct delete_stream_state {
    5956             :         bool closed;
    5957             : };
    5958             : 
    5959             : static void delete_stream_unlinked(struct tevent_req *subreq);
    5960             : static void delete_stream_closed(struct tevent_req *subreq);
    5961             : 
    5962           5 : static struct tevent_req *delete_stream_send(
    5963             :         TALLOC_CTX *mem_ctx,
    5964             :         struct tevent_context *ev,
    5965             :         struct cli_state *cli,
    5966             :         const char *base_fname,
    5967             :         uint16_t stream_fnum)
    5968             : {
    5969           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    5970           5 :         struct delete_stream_state *state = NULL;
    5971             : 
    5972           5 :         req = tevent_req_create(
    5973             :                 mem_ctx, &state, struct delete_stream_state);
    5974           5 :         if (req == NULL) {
    5975           0 :                 return NULL;
    5976             :         }
    5977             : 
    5978           5 :         subreq = cli_unlink_send(
    5979             :                 state,
    5980             :                 ev,
    5981             :                 cli,
    5982             :                 base_fname,
    5983             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5984           5 :         if (tevent_req_nomem(subreq, req)) {
    5985           0 :                 return tevent_req_post(req, ev);
    5986             :         }
    5987           5 :         tevent_req_set_callback(subreq, delete_stream_unlinked, req);
    5988             : 
    5989           5 :         subreq = cli_close_send(state, ev, cli, stream_fnum, 0);
    5990           5 :         if (tevent_req_nomem(subreq, req)) {
    5991           0 :                 return tevent_req_post(req, ev);
    5992             :         }
    5993           5 :         tevent_req_set_callback(subreq, delete_stream_closed, req);
    5994             : 
    5995           5 :         return req;
    5996             : }
    5997             : 
    5998           5 : static void delete_stream_unlinked(struct tevent_req *subreq)
    5999             : {
    6000           5 :         struct tevent_req *req = tevent_req_callback_data(
    6001             :                 subreq, struct tevent_req);
    6002           5 :         struct delete_stream_state *state = tevent_req_data(
    6003             :                 req, struct delete_stream_state);
    6004           0 :         NTSTATUS status;
    6005             : 
    6006           5 :         status = cli_unlink_recv(subreq);
    6007           5 :         TALLOC_FREE(subreq);
    6008           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    6009           0 :                 printf("cli_unlink returned %s\n",
    6010             :                        nt_errstr(status));
    6011           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    6012           0 :                 return;
    6013             :         }
    6014           5 :         if (!state->closed) {
    6015             :                 /* close reply should have come in first */
    6016           0 :                 printf("Not closed\n");
    6017           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    6018           0 :                 return;
    6019             :         }
    6020           5 :         tevent_req_done(req);
    6021             : }
    6022             : 
    6023           5 : static void delete_stream_closed(struct tevent_req *subreq)
    6024             : {
    6025           5 :         struct tevent_req *req = tevent_req_callback_data(
    6026             :                 subreq, struct tevent_req);
    6027           5 :         struct delete_stream_state *state = tevent_req_data(
    6028             :                 req, struct delete_stream_state);
    6029           0 :         NTSTATUS status;
    6030             : 
    6031           5 :         status = cli_close_recv(subreq);
    6032           5 :         TALLOC_FREE(subreq);
    6033           5 :         if (tevent_req_nterror(req, status)) {
    6034           0 :                 return;
    6035             :         }
    6036             :         /* also waiting for the unlink to come back */
    6037           5 :         state->closed = true;
    6038             : }
    6039             : 
    6040           5 : static NTSTATUS delete_stream_recv(struct tevent_req *req)
    6041             : {
    6042           5 :         return tevent_req_simple_recv_ntstatus(req);
    6043             : }
    6044             : 
    6045           5 : static bool run_delete_stream(int dummy)
    6046             : {
    6047           5 :         struct tevent_context *ev = NULL;
    6048           5 :         struct tevent_req *req = NULL;
    6049           5 :         struct cli_state *cli = NULL;
    6050           5 :         const char fname[] = "delete_stream";
    6051           5 :         const char fname_stream[] = "delete_stream:Zone.Identifier:$DATA";
    6052           0 :         uint16_t fnum1, fnum2;
    6053           0 :         NTSTATUS status;
    6054           0 :         bool ok;
    6055             : 
    6056           5 :         printf("Starting stream delete test\n");
    6057             : 
    6058           5 :         ok = torture_open_connection(&cli, 0);
    6059           5 :         if (!ok) {
    6060           0 :                 return false;
    6061             :         }
    6062             : 
    6063           5 :         cli_setatr(cli, fname, 0, 0);
    6064           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6065             : 
    6066             :         /* Create the file. */
    6067           5 :         status = cli_ntcreate(
    6068             :                 cli,
    6069             :                 fname,
    6070             :                 0,
    6071             :                 READ_CONTROL_ACCESS,
    6072             :                 0,
    6073             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6074             :                 FILE_CREATE,
    6075             :                 0x0,
    6076             :                 0x0,
    6077             :                 &fnum1,
    6078             :                 NULL);
    6079           5 :         if (!NT_STATUS_IS_OK(status)) {
    6080           0 :                 d_fprintf(stderr,
    6081             :                           "cli_ntcreate of %s failed (%s)\n",
    6082             :                           fname,
    6083             :                           nt_errstr(status));
    6084           0 :                 return false;
    6085             :         }
    6086           5 :         status = cli_close(cli, fnum1);
    6087           5 :         if (!NT_STATUS_IS_OK(status)) {
    6088           0 :                 d_fprintf(stderr,
    6089             :                           "cli_close of %s failed (%s)\n",
    6090             :                           fname,
    6091             :                           nt_errstr(status));
    6092           0 :                 return false;
    6093             :         }
    6094             : 
    6095             :         /* Now create the stream. */
    6096           5 :         status = cli_ntcreate(
    6097             :                 cli,
    6098             :                 fname_stream,
    6099             :                 0,
    6100             :                 FILE_WRITE_DATA,
    6101             :                 0,
    6102             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6103             :                 FILE_CREATE,
    6104             :                 0x0,
    6105             :                 0x0,
    6106             :                 &fnum1,
    6107             :                 NULL);
    6108             : 
    6109           5 :         if (!NT_STATUS_IS_OK(status)) {
    6110           0 :                 d_fprintf(stderr,
    6111             :                           "cli_ntcreate of %s failed (%s)\n",
    6112             :                           fname_stream,
    6113             :                           nt_errstr(status));
    6114           0 :                 return false;
    6115             :         }
    6116             : 
    6117             :         /* open it a second time */
    6118             : 
    6119           5 :         status = cli_ntcreate(
    6120             :                 cli,
    6121             :                 fname_stream,
    6122             :                 0,
    6123             :                 FILE_WRITE_DATA,
    6124             :                 0,
    6125             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6126             :                 FILE_OPEN,
    6127             :                 0x0,
    6128             :                 0x0,
    6129             :                 &fnum2,
    6130             :                 NULL);
    6131             : 
    6132           5 :         if (!NT_STATUS_IS_OK(status)) {
    6133           0 :                 d_fprintf(stderr,
    6134             :                           "2nd cli_ntcreate of %s failed (%s)\n",
    6135             :                           fname_stream,
    6136             :                           nt_errstr(status));
    6137           0 :                 return false;
    6138             :         }
    6139             : 
    6140           5 :         ev = samba_tevent_context_init(talloc_tos());
    6141           5 :         if (ev == NULL) {
    6142           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    6143           0 :                 return false;
    6144             :         }
    6145             : 
    6146           5 :         req = delete_stream_send(ev, ev, cli, fname, fnum1);
    6147           5 :         if (req == NULL) {
    6148           0 :                 d_fprintf(stderr, "delete_stream_send failed\n");
    6149           0 :                 return false;
    6150             :         }
    6151             : 
    6152           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    6153           5 :         if (!ok) {
    6154           0 :                 d_fprintf(stderr,
    6155             :                           "tevent_req_poll_ntstatus failed: %s\n",
    6156             :                           nt_errstr(status));
    6157           0 :                 return false;
    6158             :         }
    6159             : 
    6160           5 :         status = delete_stream_recv(req);
    6161           5 :         TALLOC_FREE(req);
    6162           5 :         if (!NT_STATUS_IS_OK(status)) {
    6163           0 :                 d_fprintf(stderr,
    6164             :                           "delete_stream failed: %s\n",
    6165             :                           nt_errstr(status));
    6166           0 :                 return false;
    6167             :         }
    6168             : 
    6169           5 :         status = cli_close(cli, fnum2);
    6170           5 :         if (!NT_STATUS_IS_OK(status)) {
    6171           0 :                 d_fprintf(stderr,
    6172             :                           "close failed: %s\n",
    6173             :                           nt_errstr(status));
    6174           0 :                 return false;
    6175             :         }
    6176             : 
    6177           5 :         status = cli_unlink(
    6178             :                 cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6179           5 :         if (!NT_STATUS_IS_OK(status)) {
    6180           0 :                 d_fprintf(stderr,
    6181             :                           "unlink failed: %s\n",
    6182             :                           nt_errstr(status));
    6183           0 :                 return false;
    6184             :         }
    6185             : 
    6186           5 :         return true;
    6187             : }
    6188             : 
    6189             : /*
    6190             :   Exercise delete on close semantics - use on the PRINT1 share in torture
    6191             :   testing.
    6192             :  */
    6193           2 : static bool run_delete_print_test(int dummy)
    6194             : {
    6195           2 :         struct cli_state *cli1 = NULL;
    6196           2 :         const char *fname = "print_delete.file";
    6197           2 :         uint16_t fnum1 = (uint16_t)-1;
    6198           2 :         bool correct = false;
    6199           2 :         const char *buf = "print file data\n";
    6200           0 :         NTSTATUS status;
    6201             : 
    6202           2 :         printf("starting print delete test\n");
    6203             : 
    6204           2 :         if (!torture_open_connection(&cli1, 0)) {
    6205           0 :                 return false;
    6206             :         }
    6207             : 
    6208           2 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    6209             : 
    6210           2 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    6211             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    6212             :                               0, 0, &fnum1, NULL);
    6213           2 :         if (!NT_STATUS_IS_OK(status)) {
    6214           0 :                 printf("open of %s failed (%s)\n",
    6215             :                         fname,
    6216             :                         nt_errstr(status));
    6217           0 :                 goto fail;
    6218             :         }
    6219             : 
    6220           2 :         status = cli_writeall(cli1,
    6221             :                         fnum1,
    6222             :                         0,
    6223             :                         (const uint8_t *)buf,
    6224             :                         0, /* offset */
    6225             :                         strlen(buf), /* size */
    6226             :                         NULL);
    6227           2 :         if (!NT_STATUS_IS_OK(status)) {
    6228           0 :                 printf("writing print file data failed (%s)\n",
    6229             :                         nt_errstr(status));
    6230           0 :                 goto fail;
    6231             :         }
    6232             : 
    6233           2 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    6234           2 :         if (!NT_STATUS_IS_OK(status)) {
    6235           0 :                 printf("setting delete_on_close failed (%s)\n",
    6236             :                         nt_errstr(status));
    6237           0 :                 goto fail;
    6238             :         }
    6239             : 
    6240           2 :         status = cli_close(cli1, fnum1);
    6241           2 :         if (!NT_STATUS_IS_OK(status)) {
    6242           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    6243           0 :                 goto fail;
    6244             :         }
    6245             : 
    6246           2 :         printf("finished print delete test\n");
    6247             : 
    6248           2 :         correct = true;
    6249             : 
    6250           2 :   fail:
    6251             : 
    6252           2 :         if (fnum1 != (uint16_t)-1) {
    6253           2 :                 cli_close(cli1, fnum1);
    6254             :         }
    6255             : 
    6256           2 :         if (cli1 && !torture_close_connection(cli1)) {
    6257           0 :                 correct = false;
    6258             :         }
    6259           2 :         return correct;
    6260             : }
    6261             : 
    6262           4 : static bool run_deletetest_ln(int dummy)
    6263             : {
    6264           0 :         struct cli_state *cli;
    6265           4 :         const char *fname = "\\delete1";
    6266           4 :         const char *fname_ln = "\\delete1_ln";
    6267           0 :         uint16_t fnum;
    6268           0 :         uint16_t fnum1;
    6269           0 :         NTSTATUS status;
    6270           4 :         bool correct = true;
    6271           0 :         time_t t;
    6272             : 
    6273           4 :         printf("starting deletetest-ln\n");
    6274             : 
    6275           4 :         if (!torture_open_connection(&cli, 0)) {
    6276           0 :                 return false;
    6277             :         }
    6278             : 
    6279           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6280           4 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6281             : 
    6282           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6283             : 
    6284             :         /* Create the file. */
    6285           4 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6286           4 :         if (!NT_STATUS_IS_OK(status)) {
    6287           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    6288           0 :                 return false;
    6289             :         }
    6290             : 
    6291           4 :         status = cli_close(cli, fnum);
    6292           4 :         if (!NT_STATUS_IS_OK(status)) {
    6293           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    6294           0 :                 return false;
    6295             :         }
    6296             : 
    6297             :         /* Now create a hardlink. */
    6298           4 :         status = cli_hardlink(cli, fname, fname_ln);
    6299           4 :         if (!NT_STATUS_IS_OK(status)) {
    6300           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    6301           0 :                 return false;
    6302             :         }
    6303             : 
    6304             :         /* Open the original file. */
    6305           4 :         status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
    6306             :                         FILE_ATTRIBUTE_NORMAL,
    6307             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6308             :                         FILE_OPEN_IF, 0, 0, &fnum, NULL);
    6309           4 :         if (!NT_STATUS_IS_OK(status)) {
    6310           0 :                 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
    6311           0 :                 return false;
    6312             :         }
    6313             : 
    6314             :         /* Unlink the hard link path. */
    6315           4 :         status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
    6316             :                         FILE_ATTRIBUTE_NORMAL,
    6317             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6318             :                         FILE_OPEN_IF, 0, 0, &fnum1, NULL);
    6319           4 :         if (!NT_STATUS_IS_OK(status)) {
    6320           0 :                 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
    6321           0 :                 return false;
    6322             :         }
    6323           4 :         status = cli_nt_delete_on_close(cli, fnum1, true);
    6324           4 :         if (!NT_STATUS_IS_OK(status)) {
    6325           0 :                 d_printf("(%s) failed to set delete_on_close %s: %s\n",
    6326             :                         __location__, fname_ln, nt_errstr(status));
    6327           0 :                 return false;
    6328             :         }
    6329             : 
    6330           4 :         status = cli_close(cli, fnum1);
    6331           4 :         if (!NT_STATUS_IS_OK(status)) {
    6332           0 :                 printf("close %s failed (%s)\n",
    6333             :                         fname_ln, nt_errstr(status));
    6334           0 :                 return false;
    6335             :         }
    6336             : 
    6337           4 :         status = cli_close(cli, fnum);
    6338           4 :         if (!NT_STATUS_IS_OK(status)) {
    6339           0 :                 printf("close %s failed (%s)\n",
    6340             :                         fname, nt_errstr(status));
    6341           0 :                 return false;
    6342             :         }
    6343             : 
    6344             :         /* Ensure the original file is still there. */
    6345           4 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    6346           4 :         if (!NT_STATUS_IS_OK(status)) {
    6347           0 :                 printf("%s getatr on file %s failed (%s)\n",
    6348             :                         __location__,
    6349             :                         fname,
    6350             :                         nt_errstr(status));
    6351           0 :                 correct = False;
    6352             :         }
    6353             : 
    6354             :         /* Ensure the link path is gone. */
    6355           4 :         status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
    6356           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    6357           0 :                 printf("%s, getatr for file %s returned wrong error code %s "
    6358             :                         "- should have been deleted\n",
    6359             :                         __location__,
    6360             :                         fname_ln, nt_errstr(status));
    6361           0 :                 correct = False;
    6362             :         }
    6363             : 
    6364           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6365           4 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6366             : 
    6367           4 :         if (!torture_close_connection(cli)) {
    6368           0 :                 correct = false;
    6369             :         }
    6370             : 
    6371           4 :         printf("finished deletetest-ln\n");
    6372             : 
    6373           4 :         return correct;
    6374             : }
    6375             : 
    6376             : /*
    6377             :   print out server properties
    6378             :  */
    6379           5 : static bool run_properties(int dummy)
    6380             : {
    6381           0 :         struct cli_state *cli;
    6382           5 :         bool correct = True;
    6383             : 
    6384           5 :         printf("starting properties test\n");
    6385             : 
    6386           5 :         ZERO_STRUCT(cli);
    6387             : 
    6388           5 :         if (!torture_open_connection(&cli, 0)) {
    6389           0 :                 return False;
    6390             :         }
    6391             : 
    6392           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6393             : 
    6394           5 :         d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
    6395             : 
    6396           5 :         if (!torture_close_connection(cli)) {
    6397           0 :                 correct = False;
    6398             :         }
    6399             : 
    6400           5 :         return correct;
    6401             : }
    6402             : 
    6403             : 
    6404             : 
    6405             : /* FIRST_DESIRED_ACCESS   0xf019f */
    6406             : #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
    6407             :                                FILE_READ_EA|                           /* 0xf */ \
    6408             :                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
    6409             :                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
    6410             :                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
    6411             :                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
    6412             : /* SECOND_DESIRED_ACCESS  0xe0080 */
    6413             : #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6414             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6415             :                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
    6416             : 
    6417             : #if 0
    6418             : #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6419             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6420             :                                FILE_READ_DATA|\
    6421             :                                WRITE_OWNER_ACCESS                      /* */
    6422             : #endif
    6423             : 
    6424             : /*
    6425             :   Test ntcreate calls made by xcopy
    6426             :  */
    6427           5 : static bool run_xcopy(int dummy)
    6428             : {
    6429           0 :         static struct cli_state *cli1;
    6430           5 :         const char *fname = "\\test.txt";
    6431           5 :         bool correct = True;
    6432           0 :         uint16_t fnum1, fnum2;
    6433           0 :         NTSTATUS status;
    6434             : 
    6435           5 :         printf("starting xcopy test\n");
    6436             : 
    6437           5 :         if (!torture_open_connection(&cli1, 0)) {
    6438           0 :                 return False;
    6439             :         }
    6440             : 
    6441           5 :         status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
    6442             :                               FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
    6443             :                               FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
    6444           5 :         if (!NT_STATUS_IS_OK(status)) {
    6445           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6446           0 :                 return False;
    6447             :         }
    6448             : 
    6449           5 :         status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
    6450             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6451             :                              FILE_OPEN, 0x200000, 0, &fnum2, NULL);
    6452           5 :         if (!NT_STATUS_IS_OK(status)) {
    6453           0 :                 printf("second open failed - %s\n", nt_errstr(status));
    6454           0 :                 return False;
    6455             :         }
    6456             : 
    6457           5 :         if (!torture_close_connection(cli1)) {
    6458           0 :                 correct = False;
    6459             :         }
    6460             : 
    6461           5 :         return correct;
    6462             : }
    6463             : 
    6464             : /*
    6465             :   Test rename on files open with share delete and no share delete.
    6466             :  */
    6467           5 : static bool run_rename(int dummy)
    6468             : {
    6469           0 :         static struct cli_state *cli1;
    6470           5 :         const char *fname = "\\test.txt";
    6471           5 :         const char *fname1 = "\\test1.txt";
    6472           5 :         bool correct = True;
    6473           0 :         uint16_t fnum1;
    6474           0 :         uint32_t attr;
    6475           0 :         NTSTATUS status;
    6476             : 
    6477           5 :         printf("starting rename test\n");
    6478             : 
    6479           5 :         if (!torture_open_connection(&cli1, 0)) {
    6480           0 :                 return False;
    6481             :         }
    6482             : 
    6483           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6484           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6485             : 
    6486           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6487             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    6488             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6489           5 :         if (!NT_STATUS_IS_OK(status)) {
    6490           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6491           0 :                 return False;
    6492             :         }
    6493             : 
    6494           5 :         status = cli_rename(cli1, fname, fname1, false);
    6495           5 :         if (!NT_STATUS_IS_OK(status)) {
    6496           5 :                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
    6497             :         } else {
    6498           0 :                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
    6499           0 :                 correct = False;
    6500             :         }
    6501             : 
    6502           5 :         status = cli_close(cli1, fnum1);
    6503           5 :         if (!NT_STATUS_IS_OK(status)) {
    6504           0 :                 printf("close - 1 failed (%s)\n", nt_errstr(status));
    6505           0 :                 return False;
    6506             :         }
    6507             : 
    6508           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6509           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6510           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
    6511             : #if 0
    6512             :                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
    6513             : #else
    6514             :                               FILE_SHARE_DELETE|FILE_SHARE_READ,
    6515             : #endif
    6516             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6517           5 :         if (!NT_STATUS_IS_OK(status)) {
    6518           0 :                 printf("Second open failed - %s\n", nt_errstr(status));
    6519           0 :                 return False;
    6520             :         }
    6521             : 
    6522           5 :         status = cli_rename(cli1, fname, fname1, false);
    6523           5 :         if (!NT_STATUS_IS_OK(status)) {
    6524           0 :                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
    6525           0 :                 correct = False;
    6526             :         } else {
    6527           5 :                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
    6528             :         }
    6529             : 
    6530           5 :         status = cli_close(cli1, fnum1);
    6531           5 :         if (!NT_STATUS_IS_OK(status)) {
    6532           0 :                 printf("close - 2 failed (%s)\n", nt_errstr(status));
    6533           0 :                 return False;
    6534             :         }
    6535             : 
    6536           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6537           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6538             : 
    6539           5 :         status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
    6540             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    6541             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6542           5 :         if (!NT_STATUS_IS_OK(status)) {
    6543           0 :                 printf("Third open failed - %s\n", nt_errstr(status));
    6544           0 :                 return False;
    6545             :         }
    6546             : 
    6547             : 
    6548           5 :         status = cli_rename(cli1, fname, fname1, false);
    6549           5 :         if (!NT_STATUS_IS_OK(status)) {
    6550           0 :                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
    6551           0 :                 correct = False;
    6552             :         } else {
    6553           5 :                 printf("Third rename succeeded (SHARE_NONE)\n");
    6554             :         }
    6555             : 
    6556           5 :         status = cli_close(cli1, fnum1);
    6557           5 :         if (!NT_STATUS_IS_OK(status)) {
    6558           0 :                 printf("close - 3 failed (%s)\n", nt_errstr(status));
    6559           0 :                 return False;
    6560             :         }
    6561             : 
    6562           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6563           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6564             : 
    6565             :         /*----*/
    6566             : 
    6567           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6568             :                               FILE_ATTRIBUTE_NORMAL,
    6569             :                               FILE_SHARE_READ | FILE_SHARE_WRITE,
    6570             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6571           5 :         if (!NT_STATUS_IS_OK(status)) {
    6572           0 :                 printf("Fourth open failed - %s\n", nt_errstr(status));
    6573           0 :                 return False;
    6574             :         }
    6575             : 
    6576           5 :         status = cli_rename(cli1, fname, fname1, false);
    6577           5 :         if (!NT_STATUS_IS_OK(status)) {
    6578           5 :                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
    6579             :         } else {
    6580           0 :                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
    6581           0 :                 correct = False;
    6582             :         }
    6583             : 
    6584           5 :         status = cli_close(cli1, fnum1);
    6585           5 :         if (!NT_STATUS_IS_OK(status)) {
    6586           0 :                 printf("close - 4 failed (%s)\n", nt_errstr(status));
    6587           0 :                 return False;
    6588             :         }
    6589             : 
    6590           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6591           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6592             : 
    6593             :         /*--*/
    6594             : 
    6595           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6596             :                          FILE_ATTRIBUTE_NORMAL,
    6597             :                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    6598             :                          FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6599           5 :         if (!NT_STATUS_IS_OK(status)) {
    6600           0 :                 printf("Fifth open failed - %s\n", nt_errstr(status));
    6601           0 :                 return False;
    6602             :         }
    6603             : 
    6604           5 :         status = cli_rename(cli1, fname, fname1, false);
    6605           5 :         if (!NT_STATUS_IS_OK(status)) {
    6606           0 :                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
    6607           0 :                 correct = False;
    6608             :         } else {
    6609           5 :                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
    6610             :         }
    6611             : 
    6612             :         /*--*/
    6613           5 :         status = cli_close(cli1, fnum1);
    6614           5 :         if (!NT_STATUS_IS_OK(status)) {
    6615           0 :                 printf("close - 5 failed (%s)\n", nt_errstr(status));
    6616           0 :                 return False;
    6617             :         }
    6618             : 
    6619             :         /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
    6620           5 :         status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
    6621           5 :         if (!NT_STATUS_IS_OK(status)) {
    6622           0 :                 printf("getatr on file %s failed - %s ! \n",
    6623             :                         fname1, nt_errstr(status));
    6624           0 :                 correct = False;
    6625             :         } else {
    6626           5 :                 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
    6627           0 :                         printf("Renamed file %s has wrong attr 0x%x "
    6628             :                                 "(should be 0x%x)\n",
    6629             :                                 fname1,
    6630             :                                 attr,
    6631             :                                 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
    6632           0 :                         correct = False;
    6633             :                 } else {
    6634           5 :                         printf("Renamed file %s has archive bit set\n", fname1);
    6635             :                 }
    6636             :         }
    6637             : 
    6638           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6639           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6640             : 
    6641           5 :         if (!torture_close_connection(cli1)) {
    6642           0 :                 correct = False;
    6643             :         }
    6644             : 
    6645           5 :         return correct;
    6646             : }
    6647             : 
    6648             : /*
    6649             :   Test rename into a directory with an ACL denying it.
    6650             :  */
    6651           4 : static bool run_rename_access(int dummy)
    6652             : {
    6653           0 :         static struct cli_state *cli = NULL;
    6654           0 :         static struct cli_state *posix_cli = NULL;
    6655           4 :         const char *src = "test.txt";
    6656           4 :         const char *dname = "dir";
    6657           4 :         const char *dst = "dir\\test.txt";
    6658           4 :         const char *dsrc = "test.dir";
    6659           4 :         const char *ddst = "dir\\test.dir";
    6660           4 :         uint16_t fnum = (uint16_t)-1;
    6661           4 :         struct security_descriptor *sd = NULL;
    6662           4 :         struct security_descriptor *newsd = NULL;
    6663           0 :         NTSTATUS status;
    6664           4 :         TALLOC_CTX *frame = NULL;
    6665             : 
    6666           4 :         frame = talloc_stackframe();
    6667           4 :         printf("starting rename access test\n");
    6668             : 
    6669             :         /* Windows connection. */
    6670           4 :         if (!torture_open_connection(&cli, 0)) {
    6671           0 :                 goto fail;
    6672             :         }
    6673             : 
    6674           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6675             : 
    6676             :         /* Posix connection. */
    6677           4 :         if (!torture_open_connection(&posix_cli, 0)) {
    6678           0 :                 goto fail;
    6679             :         }
    6680             : 
    6681           4 :         smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
    6682             : 
    6683           4 :         status = torture_setup_unix_extensions(posix_cli);
    6684           4 :         if (!NT_STATUS_IS_OK(status)) {
    6685           0 :                 goto fail;
    6686             :         }
    6687             : 
    6688             :         /* Start with a clean slate. */
    6689           4 :         cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6690           4 :         cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6691           4 :         cli_rmdir(cli, dsrc);
    6692           4 :         cli_rmdir(cli, ddst);
    6693           4 :         cli_rmdir(cli, dname);
    6694             : 
    6695             :         /*
    6696             :          * Setup the destination directory with a DENY ACE to
    6697             :          * prevent new files within it.
    6698             :          */
    6699           4 :         status = cli_ntcreate(cli,
    6700             :                                 dname,
    6701             :                                 0,
    6702             :                                 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
    6703             :                                         WRITE_DAC_ACCESS|FILE_READ_DATA|
    6704             :                                         WRITE_OWNER_ACCESS,
    6705             :                                 FILE_ATTRIBUTE_DIRECTORY,
    6706             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6707             :                                 FILE_CREATE,
    6708             :                                 FILE_DIRECTORY_FILE,
    6709             :                                 0,
    6710             :                                 &fnum,
    6711             :                                 NULL);
    6712           4 :         if (!NT_STATUS_IS_OK(status)) {
    6713           0 :                 printf("Create of %s - %s\n", dname, nt_errstr(status));
    6714           0 :                 goto fail;
    6715             :         }
    6716             : 
    6717           4 :         status = cli_query_secdesc(cli,
    6718             :                                 fnum,
    6719             :                                 frame,
    6720             :                                 &sd);
    6721           4 :         if (!NT_STATUS_IS_OK(status)) {
    6722           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6723             :                         dname, nt_errstr(status));
    6724           0 :                 goto fail;
    6725             :         }
    6726             : 
    6727           4 :         newsd = security_descriptor_dacl_create(frame,
    6728             :                                         0,
    6729             :                                         NULL,
    6730             :                                         NULL,
    6731             :                                         SID_WORLD,
    6732             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6733             :                                         SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
    6734             :                                         0,
    6735             :                                         NULL);
    6736           4 :         if (newsd == NULL) {
    6737           0 :                 goto fail;
    6738             :         }
    6739           8 :         sd->dacl = security_acl_concatenate(frame,
    6740           4 :                                         newsd->dacl,
    6741           4 :                                         sd->dacl);
    6742           4 :         if (sd->dacl == NULL) {
    6743           0 :                 goto fail;
    6744             :         }
    6745           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6746           4 :         if (!NT_STATUS_IS_OK(status)) {
    6747           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6748             :                         dname, nt_errstr(status));
    6749           0 :                 goto fail;
    6750             :         }
    6751           4 :         status = cli_close(cli, fnum);
    6752           4 :         if (!NT_STATUS_IS_OK(status)) {
    6753           0 :                 printf("close failed for %s (%s)\n",
    6754             :                         dname, nt_errstr(status));
    6755           0 :                 goto fail;
    6756             :         }
    6757             :         /* Now go around the back and chmod to 777 via POSIX. */
    6758           4 :         status = cli_posix_chmod(posix_cli, dname, 0777);
    6759           4 :         if (!NT_STATUS_IS_OK(status)) {
    6760           0 :                 printf("cli_posix_chmod failed for %s (%s)\n",
    6761             :                         dname, nt_errstr(status));
    6762           0 :                 goto fail;
    6763             :         }
    6764             : 
    6765             :         /* Check we can't create a file within dname via Windows. */
    6766           4 :         status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6767           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6768           0 :                 cli_close(posix_cli, fnum);
    6769           0 :                 printf("Create of %s should be ACCESS denied, was %s\n",
    6770             :                         dst, nt_errstr(status));
    6771           0 :                 goto fail;
    6772             :         }
    6773             : 
    6774             :         /* Make the sample file/directory. */
    6775           4 :         status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6776           4 :         if (!NT_STATUS_IS_OK(status)) {
    6777           0 :                 printf("open of %s failed (%s)\n", src, nt_errstr(status));
    6778           0 :                 goto fail;
    6779             :         }
    6780           4 :         status = cli_close(cli, fnum);
    6781           4 :         if (!NT_STATUS_IS_OK(status)) {
    6782           0 :                 printf("cli_close failed (%s)\n", nt_errstr(status));
    6783           0 :                 goto fail;
    6784             :         }
    6785             : 
    6786           4 :         status = cli_mkdir(cli, dsrc);
    6787           4 :         if (!NT_STATUS_IS_OK(status)) {
    6788           0 :                 printf("cli_mkdir of %s failed (%s)\n",
    6789             :                         dsrc, nt_errstr(status));
    6790           0 :                 goto fail;
    6791             :         }
    6792             : 
    6793             :         /*
    6794             :          * OK - renames of the new file and directory into the
    6795             :          * dst directory should fail.
    6796             :          */
    6797             : 
    6798           4 :         status = cli_rename(cli, src, dst, false);
    6799           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6800           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6801             :                         src, dst, nt_errstr(status));
    6802           0 :                 goto fail;
    6803             :         }
    6804           4 :         status = cli_rename(cli, dsrc, ddst, false);
    6805           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6806           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6807             :                         src, dst, nt_errstr(status));
    6808           0 :                 goto fail;
    6809             :         }
    6810             : 
    6811           4 :         TALLOC_FREE(frame);
    6812           4 :         return true;
    6813             : 
    6814           0 :   fail:
    6815             : 
    6816           0 :         if (posix_cli) {
    6817           0 :                 torture_close_connection(posix_cli);
    6818             :         }
    6819             : 
    6820           0 :         if (cli) {
    6821           0 :                 if (fnum != (uint16_t)-1) {
    6822           0 :                         cli_close(cli, fnum);
    6823             :                 }
    6824           0 :                 cli_unlink(cli, src,
    6825             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6826           0 :                 cli_unlink(cli, dst,
    6827             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6828           0 :                 cli_rmdir(cli, dsrc);
    6829           0 :                 cli_rmdir(cli, ddst);
    6830           0 :                 cli_rmdir(cli, dname);
    6831             : 
    6832           0 :                 torture_close_connection(cli);
    6833             :         }
    6834             : 
    6835           0 :         TALLOC_FREE(frame);
    6836           0 :         return false;
    6837             : }
    6838             : 
    6839             : /*
    6840             :   Test owner rights ACE.
    6841             :  */
    6842           4 : static bool run_owner_rights(int dummy)
    6843             : {
    6844           0 :         static struct cli_state *cli = NULL;
    6845           4 :         const char *fname = "owner_rights.txt";
    6846           4 :         uint16_t fnum = (uint16_t)-1;
    6847           4 :         struct security_descriptor *sd = NULL;
    6848           4 :         struct security_descriptor *newsd = NULL;
    6849           0 :         NTSTATUS status;
    6850           4 :         TALLOC_CTX *frame = NULL;
    6851             : 
    6852           4 :         frame = talloc_stackframe();
    6853           4 :         printf("starting owner rights test\n");
    6854             : 
    6855             :         /* Windows connection. */
    6856           4 :         if (!torture_open_connection(&cli, 0)) {
    6857           0 :                 goto fail;
    6858             :         }
    6859             : 
    6860           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6861             : 
    6862             :         /* Start with a clean slate. */
    6863           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6864             : 
    6865             :         /* Create the test file. */
    6866             :         /* Now try and open for read and write-dac. */
    6867           4 :         status = cli_ntcreate(cli,
    6868             :                                 fname,
    6869             :                                 0,
    6870             :                                 GENERIC_ALL_ACCESS,
    6871             :                                 FILE_ATTRIBUTE_NORMAL,
    6872             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6873             :                                         FILE_SHARE_DELETE,
    6874             :                                 FILE_CREATE,
    6875             :                                 0,
    6876             :                                 0,
    6877             :                                 &fnum,
    6878             :                                 NULL);
    6879           4 :         if (!NT_STATUS_IS_OK(status)) {
    6880           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6881           0 :                 goto fail;
    6882             :         }
    6883             : 
    6884             :         /* Get the original SD. */
    6885           4 :         status = cli_query_secdesc(cli,
    6886             :                                 fnum,
    6887             :                                 frame,
    6888             :                                 &sd);
    6889           4 :         if (!NT_STATUS_IS_OK(status)) {
    6890           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6891             :                         fname, nt_errstr(status));
    6892           0 :                 goto fail;
    6893             :         }
    6894             : 
    6895             :         /*
    6896             :          * Add an "owner-rights" ACE denying WRITE_DATA,
    6897             :          * and an "owner-rights" ACE allowing READ_DATA.
    6898             :          */
    6899             : 
    6900           4 :         newsd = security_descriptor_dacl_create(frame,
    6901             :                                         0,
    6902             :                                         NULL,
    6903             :                                         NULL,
    6904             :                                         SID_OWNER_RIGHTS,
    6905             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6906             :                                         FILE_WRITE_DATA,
    6907             :                                         0,
    6908             :                                         SID_OWNER_RIGHTS,
    6909             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    6910             :                                         FILE_READ_DATA,
    6911             :                                         0,
    6912             :                                         NULL);
    6913           4 :         if (newsd == NULL) {
    6914           0 :                 goto fail;
    6915             :         }
    6916           8 :         sd->dacl = security_acl_concatenate(frame,
    6917           4 :                                         newsd->dacl,
    6918           4 :                                         sd->dacl);
    6919           4 :         if (sd->dacl == NULL) {
    6920           0 :                 goto fail;
    6921             :         }
    6922           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6923           4 :         if (!NT_STATUS_IS_OK(status)) {
    6924           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6925             :                         fname, nt_errstr(status));
    6926           0 :                 goto fail;
    6927             :         }
    6928           4 :         status = cli_close(cli, fnum);
    6929           4 :         if (!NT_STATUS_IS_OK(status)) {
    6930           0 :                 printf("close failed for %s (%s)\n",
    6931             :                         fname, nt_errstr(status));
    6932           0 :                 goto fail;
    6933             :         }
    6934           4 :         fnum = (uint16_t)-1;
    6935             : 
    6936             :         /* Try and open for FILE_WRITE_DATA */
    6937           4 :         status = cli_ntcreate(cli,
    6938             :                                 fname,
    6939             :                                 0,
    6940             :                                 FILE_WRITE_DATA,
    6941             :                                 FILE_ATTRIBUTE_NORMAL,
    6942             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6943             :                                         FILE_SHARE_DELETE,
    6944             :                                 FILE_OPEN,
    6945             :                                 0,
    6946             :                                 0,
    6947             :                                 &fnum,
    6948             :                                 NULL);
    6949           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6950           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6951           0 :                 goto fail;
    6952             :         }
    6953             : 
    6954             :         /* Now try and open for FILE_READ_DATA */
    6955           4 :         status = cli_ntcreate(cli,
    6956             :                                 fname,
    6957             :                                 0,
    6958             :                                 FILE_READ_DATA,
    6959             :                                 FILE_ATTRIBUTE_NORMAL,
    6960             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6961             :                                         FILE_SHARE_DELETE,
    6962             :                                 FILE_OPEN,
    6963             :                                 0,
    6964             :                                 0,
    6965             :                                 &fnum,
    6966             :                                 NULL);
    6967           4 :         if (!NT_STATUS_IS_OK(status)) {
    6968           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6969           0 :                 goto fail;
    6970             :         }
    6971             : 
    6972           4 :         status = cli_close(cli, fnum);
    6973           4 :         if (!NT_STATUS_IS_OK(status)) {
    6974           0 :                 printf("close failed for %s (%s)\n",
    6975             :                         fname, nt_errstr(status));
    6976           0 :                 goto fail;
    6977             :         }
    6978             : 
    6979             :         /* Restore clean slate. */
    6980           4 :         TALLOC_FREE(sd);
    6981           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6982             : 
    6983             :         /* Create the test file. */
    6984           4 :         status = cli_ntcreate(cli,
    6985             :                                 fname,
    6986             :                                 0,
    6987             :                                 GENERIC_ALL_ACCESS,
    6988             :                                 FILE_ATTRIBUTE_NORMAL,
    6989             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6990             :                                         FILE_SHARE_DELETE,
    6991             :                                 FILE_CREATE,
    6992             :                                 0,
    6993             :                                 0,
    6994             :                                 &fnum,
    6995             :                                 NULL);
    6996           4 :         if (!NT_STATUS_IS_OK(status)) {
    6997           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6998           0 :                 goto fail;
    6999             :         }
    7000             : 
    7001             :         /* Get the original SD. */
    7002           4 :         status = cli_query_secdesc(cli,
    7003             :                                 fnum,
    7004             :                                 frame,
    7005             :                                 &sd);
    7006           4 :         if (!NT_STATUS_IS_OK(status)) {
    7007           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    7008             :                         fname, nt_errstr(status));
    7009           0 :                 goto fail;
    7010             :         }
    7011             : 
    7012             :         /*
    7013             :          * Add an "owner-rights ACE denying WRITE_DATA,
    7014             :          * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
    7015             :          */
    7016             : 
    7017           4 :         newsd = security_descriptor_dacl_create(frame,
    7018             :                                         0,
    7019             :                                         NULL,
    7020             :                                         NULL,
    7021             :                                         SID_OWNER_RIGHTS,
    7022             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    7023             :                                         FILE_WRITE_DATA,
    7024             :                                         0,
    7025             :                                         SID_OWNER_RIGHTS,
    7026             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7027             :                                         FILE_READ_DATA|FILE_WRITE_DATA,
    7028             :                                         0,
    7029             :                                         NULL);
    7030           4 :         if (newsd == NULL) {
    7031           0 :                 goto fail;
    7032             :         }
    7033           8 :         sd->dacl = security_acl_concatenate(frame,
    7034           4 :                                         newsd->dacl,
    7035           4 :                                         sd->dacl);
    7036           4 :         if (sd->dacl == NULL) {
    7037           0 :                 goto fail;
    7038             :         }
    7039           4 :         status = cli_set_secdesc(cli, fnum, sd);
    7040           4 :         if (!NT_STATUS_IS_OK(status)) {
    7041           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    7042             :                         fname, nt_errstr(status));
    7043           0 :                 goto fail;
    7044             :         }
    7045           4 :         status = cli_close(cli, fnum);
    7046           4 :         if (!NT_STATUS_IS_OK(status)) {
    7047           0 :                 printf("close failed for %s (%s)\n",
    7048             :                         fname, nt_errstr(status));
    7049           0 :                 goto fail;
    7050             :         }
    7051           4 :         fnum = (uint16_t)-1;
    7052             : 
    7053             :         /* Try and open for FILE_WRITE_DATA */
    7054           4 :         status = cli_ntcreate(cli,
    7055             :                                 fname,
    7056             :                                 0,
    7057             :                                 FILE_WRITE_DATA,
    7058             :                                 FILE_ATTRIBUTE_NORMAL,
    7059             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7060             :                                         FILE_SHARE_DELETE,
    7061             :                                 FILE_OPEN,
    7062             :                                 0,
    7063             :                                 0,
    7064             :                                 &fnum,
    7065             :                                 NULL);
    7066           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    7067           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7068           0 :                 goto fail;
    7069             :         }
    7070             : 
    7071             :         /* Now try and open for FILE_READ_DATA */
    7072           4 :         status = cli_ntcreate(cli,
    7073             :                                 fname,
    7074             :                                 0,
    7075             :                                 FILE_READ_DATA,
    7076             :                                 FILE_ATTRIBUTE_NORMAL,
    7077             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7078             :                                         FILE_SHARE_DELETE,
    7079             :                                 FILE_OPEN,
    7080             :                                 0,
    7081             :                                 0,
    7082             :                                 &fnum,
    7083             :                                 NULL);
    7084           4 :         if (!NT_STATUS_IS_OK(status)) {
    7085           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7086           0 :                 goto fail;
    7087             :         }
    7088             : 
    7089           4 :         status = cli_close(cli, fnum);
    7090           4 :         if (!NT_STATUS_IS_OK(status)) {
    7091           0 :                 printf("close failed for %s (%s)\n",
    7092             :                         fname, nt_errstr(status));
    7093           0 :                 goto fail;
    7094             :         }
    7095             : 
    7096             :         /* Restore clean slate. */
    7097           4 :         TALLOC_FREE(sd);
    7098           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7099             : 
    7100             : 
    7101             :         /* Create the test file. */
    7102           4 :         status = cli_ntcreate(cli,
    7103             :                                 fname,
    7104             :                                 0,
    7105             :                                 GENERIC_ALL_ACCESS,
    7106             :                                 FILE_ATTRIBUTE_NORMAL,
    7107             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7108             :                                         FILE_SHARE_DELETE,
    7109             :                                 FILE_CREATE,
    7110             :                                 0,
    7111             :                                 0,
    7112             :                                 &fnum,
    7113             :                                 NULL);
    7114           4 :         if (!NT_STATUS_IS_OK(status)) {
    7115           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    7116           0 :                 goto fail;
    7117             :         }
    7118             : 
    7119             :         /* Get the original SD. */
    7120           4 :         status = cli_query_secdesc(cli,
    7121             :                                 fnum,
    7122             :                                 frame,
    7123             :                                 &sd);
    7124           4 :         if (!NT_STATUS_IS_OK(status)) {
    7125           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    7126             :                         fname, nt_errstr(status));
    7127           0 :                 goto fail;
    7128             :         }
    7129             : 
    7130             :         /*
    7131             :          * Add an "authenticated users" ACE allowing READ_DATA,
    7132             :          * add an "owner-rights" denying READ_DATA,
    7133             :          * and an "authenticated users" ACE allowing WRITE_DATA.
    7134             :          */
    7135             : 
    7136           4 :         newsd = security_descriptor_dacl_create(frame,
    7137             :                                         0,
    7138             :                                         NULL,
    7139             :                                         NULL,
    7140             :                                         SID_NT_AUTHENTICATED_USERS,
    7141             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7142             :                                         FILE_READ_DATA,
    7143             :                                         0,
    7144             :                                         SID_OWNER_RIGHTS,
    7145             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    7146             :                                         FILE_READ_DATA,
    7147             :                                         0,
    7148             :                                         SID_NT_AUTHENTICATED_USERS,
    7149             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    7150             :                                         FILE_WRITE_DATA,
    7151             :                                         0,
    7152             :                                         NULL);
    7153           4 :         if (newsd == NULL) {
    7154           0 :                 printf("newsd == NULL\n");
    7155           0 :                 goto fail;
    7156             :         }
    7157           8 :         sd->dacl = security_acl_concatenate(frame,
    7158           4 :                                         newsd->dacl,
    7159           4 :                                         sd->dacl);
    7160           4 :         if (sd->dacl == NULL) {
    7161           0 :                 printf("sd->dacl == NULL\n");
    7162           0 :                 goto fail;
    7163             :         }
    7164           4 :         status = cli_set_secdesc(cli, fnum, sd);
    7165           4 :         if (!NT_STATUS_IS_OK(status)) {
    7166           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    7167             :                         fname, nt_errstr(status));
    7168           0 :                 goto fail;
    7169             :         }
    7170           4 :         status = cli_close(cli, fnum);
    7171           4 :         if (!NT_STATUS_IS_OK(status)) {
    7172           0 :                 printf("close failed for %s (%s)\n",
    7173             :                         fname, nt_errstr(status));
    7174           0 :                 goto fail;
    7175             :         }
    7176           4 :         fnum = (uint16_t)-1;
    7177             : 
    7178             :         /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
    7179           4 :         status = cli_ntcreate(cli,
    7180             :                                 fname,
    7181             :                                 0,
    7182             :                                 FILE_READ_DATA|FILE_WRITE_DATA,
    7183             :                                 FILE_ATTRIBUTE_NORMAL,
    7184             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7185             :                                         FILE_SHARE_DELETE,
    7186             :                                 FILE_OPEN,
    7187             :                                 0,
    7188             :                                 0,
    7189             :                                 &fnum,
    7190             :                                 NULL);
    7191           4 :         if (!NT_STATUS_IS_OK(status)) {
    7192           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7193           0 :                 goto fail;
    7194             :         }
    7195             : 
    7196           4 :         status = cli_close(cli, fnum);
    7197           4 :         if (!NT_STATUS_IS_OK(status)) {
    7198           0 :                 printf("close failed for %s (%s)\n",
    7199             :                         fname, nt_errstr(status));
    7200           0 :                 goto fail;
    7201             :         }
    7202             : 
    7203           4 :         cli_unlink(cli, fname,
    7204             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7205             : 
    7206           4 :         TALLOC_FREE(frame);
    7207           4 :         return true;
    7208             : 
    7209           0 :   fail:
    7210             : 
    7211           0 :         if (cli) {
    7212           0 :                 if (fnum != (uint16_t)-1) {
    7213           0 :                         cli_close(cli, fnum);
    7214             :                 }
    7215           0 :                 cli_unlink(cli, fname,
    7216             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7217           0 :                 torture_close_connection(cli);
    7218             :         }
    7219             : 
    7220           0 :         TALLOC_FREE(frame);
    7221           0 :         return false;
    7222             : }
    7223             : 
    7224             : /*
    7225             :  * Test SMB1-specific open with SEC_FLAG_SYSTEM_SECURITY.
    7226             :  * Note this test only works with a user with SeSecurityPrivilege set.
    7227             :  *
    7228             :  * NB. This is also tested in samba3.base.createx_access
    7229             :  * but this makes it very explicit what we're looking for.
    7230             :  */
    7231           2 : static bool run_smb1_system_security(int dummy)
    7232             : {
    7233           0 :         static struct cli_state *cli = NULL;
    7234           2 :         const char *fname = "system_security.txt";
    7235           2 :         uint16_t fnum = (uint16_t)-1;
    7236           0 :         NTSTATUS status;
    7237           2 :         TALLOC_CTX *frame = NULL;
    7238             : 
    7239           2 :         frame = talloc_stackframe();
    7240           2 :         printf("starting smb1 system security test\n");
    7241             : 
    7242             :         /* SMB1 connection - torture_open_connection() forces this. */
    7243           2 :         if (!torture_open_connection(&cli, 0)) {
    7244           0 :                 goto fail;
    7245             :         }
    7246             : 
    7247           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    7248             : 
    7249             :         /* Start with a clean slate. */
    7250           2 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7251             : 
    7252             :         /* Create the test file. */
    7253           2 :         status = cli_ntcreate(cli,
    7254             :                                 fname,
    7255             :                                 0,
    7256             :                                 GENERIC_ALL_ACCESS,
    7257             :                                 FILE_ATTRIBUTE_NORMAL,
    7258             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7259             :                                         FILE_SHARE_DELETE,
    7260             :                                 FILE_CREATE,
    7261             :                                 0,
    7262             :                                 0,
    7263             :                                 &fnum,
    7264             :                                 NULL);
    7265           2 :         if (!NT_STATUS_IS_OK(status)) {
    7266           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    7267           0 :                 goto fail;
    7268             :         }
    7269             : 
    7270           2 :         status = cli_close(cli, fnum);
    7271             : 
    7272             :         /* Open with SEC_FLAG_SYSTEM_SECURITY only. */
    7273             :         /*
    7274             :          * On SMB1 this succeeds - SMB2 it fails,
    7275             :          * see the SMB2-SACL test.
    7276             :          */
    7277           2 :         status = cli_ntcreate(cli,
    7278             :                                 fname,
    7279             :                                 0,
    7280             :                                 SEC_FLAG_SYSTEM_SECURITY,
    7281             :                                 FILE_ATTRIBUTE_NORMAL,
    7282             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7283             :                                         FILE_SHARE_DELETE,
    7284             :                                 FILE_OPEN,
    7285             :                                 0,
    7286             :                                 0,
    7287             :                                 &fnum,
    7288             :                                 NULL);
    7289           2 :         if (!NT_STATUS_IS_OK(status)) {
    7290           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7291           0 :                 goto fail;
    7292             :         }
    7293             : 
    7294           2 :         status = cli_close(cli, fnum);
    7295             : 
    7296           2 :         cli_unlink(cli, fname,
    7297             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7298             : 
    7299           2 :         torture_close_connection(cli);
    7300           2 :         TALLOC_FREE(frame);
    7301           2 :         return true;
    7302             : 
    7303           0 :   fail:
    7304             : 
    7305           0 :         if (cli) {
    7306           0 :                 if (fnum != (uint16_t)-1) {
    7307           0 :                         cli_close(cli, fnum);
    7308             :                 }
    7309           0 :                 cli_unlink(cli, fname,
    7310             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7311           0 :                 torture_close_connection(cli);
    7312             :         }
    7313             : 
    7314           0 :         TALLOC_FREE(frame);
    7315           0 :         return false;
    7316             : }
    7317             : 
    7318           0 : static bool run_pipe_number(int dummy)
    7319             : {
    7320           0 :         struct cli_state *cli1;
    7321           0 :         const char *pipe_name = "\\SPOOLSS";
    7322           0 :         uint16_t fnum;
    7323           0 :         int num_pipes = 0;
    7324           0 :         NTSTATUS status;
    7325             : 
    7326           0 :         printf("starting pipenumber test\n");
    7327           0 :         if (!torture_open_connection(&cli1, 0)) {
    7328           0 :                 return False;
    7329             :         }
    7330             : 
    7331           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7332           0 :         while(1) {
    7333           0 :                 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
    7334             :                                       FILE_ATTRIBUTE_NORMAL,
    7335             :                                       FILE_SHARE_READ|FILE_SHARE_WRITE,
    7336             :                                       FILE_OPEN_IF, 0, 0, &fnum, NULL);
    7337           0 :                 if (!NT_STATUS_IS_OK(status)) {
    7338           0 :                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
    7339           0 :                         break;
    7340             :                 }
    7341           0 :                 num_pipes++;
    7342           0 :                 printf("\r%6d", num_pipes);
    7343             :         }
    7344             : 
    7345           0 :         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
    7346           0 :         torture_close_connection(cli1);
    7347           0 :         return True;
    7348             : }
    7349             : 
    7350             : /*
    7351             :   Test open mode returns on read-only files.
    7352             :  */
    7353           5 : static bool run_opentest(int dummy)
    7354             : {
    7355           0 :         static struct cli_state *cli1;
    7356           0 :         static struct cli_state *cli2;
    7357           5 :         const char *fname = "\\readonly.file";
    7358           0 :         uint16_t fnum1, fnum2;
    7359           0 :         char buf[20];
    7360           0 :         off_t fsize;
    7361           5 :         bool correct = True;
    7362           0 :         char *tmp_path;
    7363           0 :         NTSTATUS status;
    7364             : 
    7365           5 :         printf("starting open test\n");
    7366             : 
    7367           5 :         if (!torture_open_connection(&cli1, 0)) {
    7368           0 :                 return False;
    7369             :         }
    7370             : 
    7371           5 :         cli_setatr(cli1, fname, 0, 0);
    7372           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7373             : 
    7374           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7375             : 
    7376           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7377           5 :         if (!NT_STATUS_IS_OK(status)) {
    7378           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7379           0 :                 return False;
    7380             :         }
    7381             : 
    7382           5 :         status = cli_close(cli1, fnum1);
    7383           5 :         if (!NT_STATUS_IS_OK(status)) {
    7384           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7385           0 :                 return False;
    7386             :         }
    7387             : 
    7388           5 :         status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
    7389           5 :         if (!NT_STATUS_IS_OK(status)) {
    7390           0 :                 printf("cli_setatr failed (%s)\n", nt_errstr(status));
    7391           0 :                 return False;
    7392             :         }
    7393             : 
    7394           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7395           5 :         if (!NT_STATUS_IS_OK(status)) {
    7396           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7397           0 :                 return False;
    7398             :         }
    7399             : 
    7400             :         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
    7401           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7402             : 
    7403           5 :         if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
    7404           5 :                         NT_STATUS_ACCESS_DENIED)) {
    7405           4 :                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
    7406             :         }
    7407             : 
    7408           5 :         printf("finished open test 1\n");
    7409             : 
    7410           5 :         cli_close(cli1, fnum1);
    7411             : 
    7412             :         /* Now try not readonly and ensure ERRbadshare is returned. */
    7413             : 
    7414           5 :         cli_setatr(cli1, fname, 0, 0);
    7415             : 
    7416           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7417           5 :         if (!NT_STATUS_IS_OK(status)) {
    7418           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7419           0 :                 return False;
    7420             :         }
    7421             : 
    7422             :         /* This will fail - but the error should be ERRshare. */
    7423           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7424             : 
    7425           5 :         if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
    7426           5 :                         NT_STATUS_SHARING_VIOLATION)) {
    7427           5 :                 printf("correct error code ERRDOS/ERRbadshare returned\n");
    7428             :         }
    7429             : 
    7430           5 :         status = cli_close(cli1, fnum1);
    7431           5 :         if (!NT_STATUS_IS_OK(status)) {
    7432           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7433           0 :                 return False;
    7434             :         }
    7435             : 
    7436           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7437             : 
    7438           5 :         printf("finished open test 2\n");
    7439             : 
    7440             :         /* Test truncate open disposition on file opened for read. */
    7441           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7442           5 :         if (!NT_STATUS_IS_OK(status)) {
    7443           0 :                 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
    7444           0 :                 return False;
    7445             :         }
    7446             : 
    7447             :         /* write 20 bytes. */
    7448             : 
    7449           5 :         memset(buf, '\0', 20);
    7450             : 
    7451           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
    7452           5 :         if (!NT_STATUS_IS_OK(status)) {
    7453           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    7454           0 :                 correct = False;
    7455             :         }
    7456             : 
    7457           5 :         status = cli_close(cli1, fnum1);
    7458           5 :         if (!NT_STATUS_IS_OK(status)) {
    7459           0 :                 printf("(3) close1 failed (%s)\n", nt_errstr(status));
    7460           0 :                 return False;
    7461             :         }
    7462             : 
    7463             :         /* Ensure size == 20. */
    7464           5 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7465           5 :         if (!NT_STATUS_IS_OK(status)) {
    7466           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7467           0 :                 return False;
    7468             :         }
    7469             : 
    7470           5 :         if (fsize != 20) {
    7471           0 :                 printf("(3) file size != 20\n");
    7472           0 :                 return False;
    7473             :         }
    7474             : 
    7475             :         /* Now test if we can truncate a file opened for readonly. */
    7476           5 :         status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
    7477           5 :         if (!NT_STATUS_IS_OK(status)) {
    7478           0 :                 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
    7479           0 :                 return False;
    7480             :         }
    7481             : 
    7482           5 :         status = cli_close(cli1, fnum1);
    7483           5 :         if (!NT_STATUS_IS_OK(status)) {
    7484           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7485           0 :                 return False;
    7486             :         }
    7487             : 
    7488             :         /* Ensure size == 0. */
    7489           5 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7490           5 :         if (!NT_STATUS_IS_OK(status)) {
    7491           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7492           0 :                 return False;
    7493             :         }
    7494             : 
    7495           5 :         if (fsize != 0) {
    7496           0 :                 printf("(3) file size != 0\n");
    7497           0 :                 return False;
    7498             :         }
    7499           5 :         printf("finished open test 3\n");
    7500             : 
    7501           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7502             : 
    7503           5 :         printf("Do ctemp tests\n");
    7504           5 :         status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
    7505           5 :         if (!NT_STATUS_IS_OK(status)) {
    7506           0 :                 printf("ctemp failed (%s)\n", nt_errstr(status));
    7507           0 :                 return False;
    7508             :         }
    7509             : 
    7510           5 :         printf("ctemp gave path %s\n", tmp_path);
    7511           5 :         status = cli_close(cli1, fnum1);
    7512           5 :         if (!NT_STATUS_IS_OK(status)) {
    7513           0 :                 printf("close of temp failed (%s)\n", nt_errstr(status));
    7514             :         }
    7515             : 
    7516           5 :         status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7517           5 :         if (!NT_STATUS_IS_OK(status)) {
    7518           0 :                 printf("unlink of temp failed (%s)\n", nt_errstr(status));
    7519             :         }
    7520             : 
    7521             :         /* Test the non-io opens... */
    7522             : 
    7523           5 :         if (!torture_open_connection(&cli2, 1)) {
    7524           0 :                 return False;
    7525             :         }
    7526             : 
    7527           5 :         cli_setatr(cli2, fname, 0, 0);
    7528           5 :         cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7529             : 
    7530           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    7531             : 
    7532           5 :         printf("TEST #1 testing 2 non-io opens (no delete)\n");
    7533           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7534             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7535             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7536           5 :         if (!NT_STATUS_IS_OK(status)) {
    7537           0 :                 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7538           0 :                 return False;
    7539             :         }
    7540             : 
    7541           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7542             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7543             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7544           5 :         if (!NT_STATUS_IS_OK(status)) {
    7545           0 :                 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7546           0 :                 return False;
    7547             :         }
    7548             : 
    7549           5 :         status = cli_close(cli1, fnum1);
    7550           5 :         if (!NT_STATUS_IS_OK(status)) {
    7551           0 :                 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7552           0 :                 return False;
    7553             :         }
    7554             : 
    7555           5 :         status = cli_close(cli2, fnum2);
    7556           5 :         if (!NT_STATUS_IS_OK(status)) {
    7557           0 :                 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7558           0 :                 return False;
    7559             :         }
    7560             : 
    7561           5 :         printf("non-io open test #1 passed.\n");
    7562             : 
    7563           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7564             : 
    7565           5 :         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
    7566             : 
    7567           5 :         status = cli_ntcreate(cli1, fname, 0,
    7568             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7569             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7570             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7571           5 :         if (!NT_STATUS_IS_OK(status)) {
    7572           0 :                 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7573           0 :                 return False;
    7574             :         }
    7575             : 
    7576           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7577             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7578             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7579           5 :         if (!NT_STATUS_IS_OK(status)) {
    7580           0 :                 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7581           0 :                 return False;
    7582             :         }
    7583             : 
    7584           5 :         status = cli_close(cli1, fnum1);
    7585           5 :         if (!NT_STATUS_IS_OK(status)) {
    7586           0 :                 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7587           0 :                 return False;
    7588             :         }
    7589             : 
    7590           5 :         status = cli_close(cli2, fnum2);
    7591           5 :         if (!NT_STATUS_IS_OK(status)) {
    7592           0 :                 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7593           0 :                 return False;
    7594             :         }
    7595             : 
    7596           5 :         printf("non-io open test #2 passed.\n");
    7597             : 
    7598           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7599             : 
    7600           5 :         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
    7601             : 
    7602           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7603             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7604             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7605           5 :         if (!NT_STATUS_IS_OK(status)) {
    7606           0 :                 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7607           0 :                 return False;
    7608             :         }
    7609             : 
    7610           5 :         status = cli_ntcreate(cli2, fname, 0,
    7611             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7612             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7613             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7614           5 :         if (!NT_STATUS_IS_OK(status)) {
    7615           0 :                 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7616           0 :                 return False;
    7617             :         }
    7618             : 
    7619           5 :         status = cli_close(cli1, fnum1);
    7620           5 :         if (!NT_STATUS_IS_OK(status)) {
    7621           0 :                 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7622           0 :                 return False;
    7623             :         }
    7624             : 
    7625           5 :         status = cli_close(cli2, fnum2);
    7626           5 :         if (!NT_STATUS_IS_OK(status)) {
    7627           0 :                 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7628           0 :                 return False;
    7629             :         }
    7630             : 
    7631           5 :         printf("non-io open test #3 passed.\n");
    7632             : 
    7633           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7634             : 
    7635           5 :         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
    7636             : 
    7637           5 :         status = cli_ntcreate(cli1, fname, 0,
    7638             :                                DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7639             :                                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7640             :                                FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7641           5 :         if (!NT_STATUS_IS_OK(status)) {
    7642           0 :                 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7643           0 :                 return False;
    7644             :         }
    7645             : 
    7646           5 :         status = cli_ntcreate(cli2, fname, 0,
    7647             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7648             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7649             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7650           5 :         if (NT_STATUS_IS_OK(status)) {
    7651           0 :                 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7652           0 :                 return False;
    7653             :         }
    7654             : 
    7655           5 :         printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7656             : 
    7657           5 :         status = cli_close(cli1, fnum1);
    7658           5 :         if (!NT_STATUS_IS_OK(status)) {
    7659           0 :                 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7660           0 :                 return False;
    7661             :         }
    7662             : 
    7663           5 :         printf("non-io open test #4 passed.\n");
    7664             : 
    7665           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7666             : 
    7667           5 :         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
    7668             : 
    7669           5 :         status = cli_ntcreate(cli1, fname, 0,
    7670             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7671             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7672             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7673           5 :         if (!NT_STATUS_IS_OK(status)) {
    7674           0 :                 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7675           0 :                 return False;
    7676             :         }
    7677             : 
    7678           5 :         status = cli_ntcreate(cli2, fname, 0,
    7679             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7680             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7681             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7682           5 :         if (!NT_STATUS_IS_OK(status)) {
    7683           0 :                 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7684           0 :                 return False;
    7685             :         }
    7686             : 
    7687           5 :         status = cli_close(cli1, fnum1);
    7688           5 :         if (!NT_STATUS_IS_OK(status)) {
    7689           0 :                 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7690           0 :                 return False;
    7691             :         }
    7692             : 
    7693           5 :         status = cli_close(cli2, fnum2);
    7694           5 :         if (!NT_STATUS_IS_OK(status)) {
    7695           0 :                 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7696           0 :                 return False;
    7697             :         }
    7698             : 
    7699           5 :         printf("non-io open test #5 passed.\n");
    7700             : 
    7701           5 :         printf("TEST #6 testing 1 non-io open, one io open\n");
    7702             : 
    7703           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7704             : 
    7705           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7706             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7707             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7708           5 :         if (!NT_STATUS_IS_OK(status)) {
    7709           0 :                 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7710           0 :                 return False;
    7711             :         }
    7712             : 
    7713           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7714             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    7715             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7716           5 :         if (!NT_STATUS_IS_OK(status)) {
    7717           0 :                 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7718           0 :                 return False;
    7719             :         }
    7720             : 
    7721           5 :         status = cli_close(cli1, fnum1);
    7722           5 :         if (!NT_STATUS_IS_OK(status)) {
    7723           0 :                 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7724           0 :                 return False;
    7725             :         }
    7726             : 
    7727           5 :         status = cli_close(cli2, fnum2);
    7728           5 :         if (!NT_STATUS_IS_OK(status)) {
    7729           0 :                 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7730           0 :                 return False;
    7731             :         }
    7732             : 
    7733           5 :         printf("non-io open test #6 passed.\n");
    7734             : 
    7735           5 :         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
    7736             : 
    7737           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7738             : 
    7739           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7740             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7741             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7742           5 :         if (!NT_STATUS_IS_OK(status)) {
    7743           0 :                 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7744           0 :                 return False;
    7745             :         }
    7746             : 
    7747           5 :         status = cli_ntcreate(cli2, fname, 0,
    7748             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7749             :                               FILE_ATTRIBUTE_NORMAL,
    7750             :                               FILE_SHARE_READ|FILE_SHARE_DELETE,
    7751             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7752           5 :         if (NT_STATUS_IS_OK(status)) {
    7753           0 :                 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7754           0 :                 return False;
    7755             :         }
    7756             : 
    7757           5 :         printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7758             : 
    7759           5 :         status = cli_close(cli1, fnum1);
    7760           5 :         if (!NT_STATUS_IS_OK(status)) {
    7761           0 :                 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7762           0 :                 return False;
    7763             :         }
    7764             : 
    7765           5 :         printf("non-io open test #7 passed.\n");
    7766             : 
    7767           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7768             : 
    7769           5 :         printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
    7770           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
    7771             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    7772             :                                 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7773           5 :         if (!NT_STATUS_IS_OK(status)) {
    7774           0 :                 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
    7775           0 :                 correct = false;
    7776           0 :                 goto out;
    7777             :         }
    7778             : 
    7779             :         /* Write to ensure we have to update the file time. */
    7780           5 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    7781             :                               NULL);
    7782           5 :         if (!NT_STATUS_IS_OK(status)) {
    7783           0 :                 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
    7784           0 :                 correct = false;
    7785           0 :                 goto out;
    7786             :         }
    7787             : 
    7788           5 :         status = cli_close(cli1, fnum1);
    7789           5 :         if (!NT_STATUS_IS_OK(status)) {
    7790           0 :                 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
    7791           0 :                 correct = false;
    7792             :         }
    7793             : 
    7794           5 :   out:
    7795             : 
    7796           5 :         if (!torture_close_connection(cli1)) {
    7797           0 :                 correct = False;
    7798             :         }
    7799           5 :         if (!torture_close_connection(cli2)) {
    7800           0 :                 correct = False;
    7801             :         }
    7802             : 
    7803           5 :         return correct;
    7804             : }
    7805             : 
    7806         102 : NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
    7807             : {
    7808           0 :         uint16_t major, minor;
    7809           0 :         uint32_t caplow, caphigh;
    7810           0 :         NTSTATUS status;
    7811             : 
    7812         102 :         if (!SERVER_HAS_UNIX_CIFS(cli)) {
    7813           0 :                 printf("Server doesn't support UNIX CIFS extensions.\n");
    7814           0 :                 return NT_STATUS_NOT_SUPPORTED;
    7815             :         }
    7816             : 
    7817         102 :         status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
    7818             :                                              &caphigh);
    7819         102 :         if (!NT_STATUS_IS_OK(status)) {
    7820           0 :                 printf("Server didn't return UNIX CIFS extensions: %s\n",
    7821             :                        nt_errstr(status));
    7822           0 :                 return status;
    7823             :         }
    7824             : 
    7825         102 :         status = cli_set_unix_extensions_capabilities(cli, major, minor,
    7826             :                                                       caplow, caphigh);
    7827         102 :         if (!NT_STATUS_IS_OK(status)) {
    7828           0 :                 printf("Server doesn't support setting UNIX CIFS extensions: "
    7829             :                        "%s.\n", nt_errstr(status));
    7830           0 :                 return status;
    7831             :         }
    7832             : 
    7833         102 :         return NT_STATUS_OK;
    7834             : }
    7835             : 
    7836             : /*
    7837             :   Test POSIX open /mkdir calls.
    7838             :  */
    7839           4 : static bool run_simple_posix_open_test(int dummy)
    7840             : {
    7841           0 :         static struct cli_state *cli1;
    7842           4 :         const char *fname = "posix:file";
    7843           4 :         const char *hname = "posix:hlink";
    7844           4 :         const char *sname = "posix:symlink";
    7845           4 :         const char *dname = "posix:dir";
    7846           0 :         char buf[10];
    7847           4 :         char *target = NULL;
    7848           4 :         uint16_t fnum1 = (uint16_t)-1;
    7849           0 :         SMB_STRUCT_STAT sbuf;
    7850           4 :         bool correct = false;
    7851           0 :         NTSTATUS status;
    7852           0 :         size_t nread;
    7853           4 :         const char *fname_windows = "windows_file";
    7854           4 :         uint16_t fnum2 = (uint16_t)-1;
    7855           0 :         bool ok;
    7856             : 
    7857           4 :         printf("Starting simple POSIX open test\n");
    7858             : 
    7859           4 :         if (!torture_open_connection(&cli1, 0)) {
    7860           0 :                 return false;
    7861             :         }
    7862             : 
    7863           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7864             : 
    7865           4 :         status = torture_setup_unix_extensions(cli1);
    7866           4 :         if (!NT_STATUS_IS_OK(status)) {
    7867           0 :                 return false;
    7868             :         }
    7869             : 
    7870           4 :         cli_setatr(cli1, fname, 0, 0);
    7871           4 :         cli_posix_unlink(cli1, fname);
    7872           4 :         cli_setatr(cli1, dname, 0, 0);
    7873           4 :         cli_posix_rmdir(cli1, dname);
    7874           4 :         cli_setatr(cli1, hname, 0, 0);
    7875           4 :         cli_posix_unlink(cli1, hname);
    7876           4 :         cli_setatr(cli1, sname, 0, 0);
    7877           4 :         cli_posix_unlink(cli1, sname);
    7878           4 :         cli_setatr(cli1, fname_windows, 0, 0);
    7879           4 :         cli_posix_unlink(cli1, fname_windows);
    7880             : 
    7881             :         /* Create a directory. */
    7882           4 :         status = cli_posix_mkdir(cli1, dname, 0777);
    7883           4 :         if (!NT_STATUS_IS_OK(status)) {
    7884           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    7885           0 :                 goto out;
    7886             :         }
    7887             : 
    7888           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    7889             :                                 0600, &fnum1);
    7890           4 :         if (!NT_STATUS_IS_OK(status)) {
    7891           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7892           0 :                 goto out;
    7893             :         }
    7894             : 
    7895             :         /* Test ftruncate - set file size. */
    7896           4 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7897           4 :         if (!NT_STATUS_IS_OK(status)) {
    7898           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7899           0 :                 goto out;
    7900             :         }
    7901             : 
    7902             :         /* Ensure st_size == 1000 */
    7903           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7904           4 :         if (!NT_STATUS_IS_OK(status)) {
    7905           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7906           0 :                 goto out;
    7907             :         }
    7908             : 
    7909           4 :         if (sbuf.st_ex_size != 1000) {
    7910           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7911           0 :                 goto out;
    7912             :         }
    7913             : 
    7914             :         /* Ensure st_mode == 0600 */
    7915           4 :         if ((sbuf.st_ex_mode & 07777) != 0600) {
    7916           0 :                 printf("posix_open - bad permissions 0%o != 0600\n",
    7917           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    7918           0 :                 goto out;
    7919             :         }
    7920             : 
    7921             :         /* Test ftruncate - set file size back to zero. */
    7922           4 :         status = cli_ftruncate(cli1, fnum1, 0);
    7923           4 :         if (!NT_STATUS_IS_OK(status)) {
    7924           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7925           0 :                 goto out;
    7926             :         }
    7927             : 
    7928           4 :         status = cli_close(cli1, fnum1);
    7929           4 :         if (!NT_STATUS_IS_OK(status)) {
    7930           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    7931           0 :                 goto out;
    7932             :         }
    7933             : 
    7934             :         /* Now open the file again for read only. */
    7935           4 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7936           4 :         if (!NT_STATUS_IS_OK(status)) {
    7937           0 :                 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
    7938           0 :                 goto out;
    7939             :         }
    7940             : 
    7941             :         /* Now unlink while open. */
    7942           4 :         status = cli_posix_unlink(cli1, fname);
    7943           4 :         if (!NT_STATUS_IS_OK(status)) {
    7944           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    7945           0 :                 goto out;
    7946             :         }
    7947             : 
    7948           4 :         status = cli_close(cli1, fnum1);
    7949           4 :         if (!NT_STATUS_IS_OK(status)) {
    7950           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7951           0 :                 goto out;
    7952             :         }
    7953             : 
    7954             :         /* Ensure the file has gone. */
    7955           4 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7956           4 :         if (NT_STATUS_IS_OK(status)) {
    7957           0 :                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
    7958           0 :                 goto out;
    7959             :         }
    7960             : 
    7961             :         /* Create again to test open with O_TRUNC. */
    7962           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
    7963           4 :         if (!NT_STATUS_IS_OK(status)) {
    7964           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7965           0 :                 goto out;
    7966             :         }
    7967             : 
    7968             :         /* Test ftruncate - set file size. */
    7969           4 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7970           4 :         if (!NT_STATUS_IS_OK(status)) {
    7971           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7972           0 :                 goto out;
    7973             :         }
    7974             : 
    7975             :         /* Ensure st_size == 1000 */
    7976           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7977           4 :         if (!NT_STATUS_IS_OK(status)) {
    7978           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7979           0 :                 goto out;
    7980             :         }
    7981             : 
    7982           4 :         if (sbuf.st_ex_size != 1000) {
    7983           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7984           0 :                 goto out;
    7985             :         }
    7986             : 
    7987           4 :         status = cli_close(cli1, fnum1);
    7988           4 :         if (!NT_STATUS_IS_OK(status)) {
    7989           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7990           0 :                 goto out;
    7991             :         }
    7992             : 
    7993             :         /* Re-open with O_TRUNC. */
    7994           4 :         status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
    7995           4 :         if (!NT_STATUS_IS_OK(status)) {
    7996           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7997           0 :                 goto out;
    7998             :         }
    7999             : 
    8000             :         /* Ensure st_size == 0 */
    8001           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    8002           4 :         if (!NT_STATUS_IS_OK(status)) {
    8003           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    8004           0 :                 goto out;
    8005             :         }
    8006             : 
    8007           4 :         if (sbuf.st_ex_size != 0) {
    8008           0 :                 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
    8009           0 :                 goto out;
    8010             :         }
    8011             : 
    8012           4 :         status = cli_close(cli1, fnum1);
    8013           4 :         if (!NT_STATUS_IS_OK(status)) {
    8014           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    8015           0 :                 goto out;
    8016             :         }
    8017             : 
    8018           4 :         status = cli_posix_unlink(cli1, fname);
    8019           4 :         if (!NT_STATUS_IS_OK(status)) {
    8020           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    8021           0 :                 goto out;
    8022             :         }
    8023             : 
    8024           4 :         status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
    8025           4 :         if (!NT_STATUS_IS_OK(status)) {
    8026           0 :                 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
    8027             :                         dname, nt_errstr(status));
    8028           0 :                 goto out;
    8029             :         }
    8030             : 
    8031           4 :         cli_close(cli1, fnum1);
    8032             : 
    8033             :         /* What happens when we try and POSIX open a directory for write ? */
    8034           4 :         status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
    8035           4 :         if (NT_STATUS_IS_OK(status)) {
    8036           0 :                 printf("POSIX open of directory %s succeeded, "
    8037             :                        "should have failed.\n",
    8038             :                        dname);
    8039           0 :                 goto out;
    8040             :         } else {
    8041           4 :                 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
    8042           4 :                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
    8043           0 :                         goto out;
    8044             :                 }
    8045             :         }
    8046             : 
    8047             :         /* Create the file. */
    8048           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    8049             :                                 0600, &fnum1);
    8050           4 :         if (!NT_STATUS_IS_OK(status)) {
    8051           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    8052           0 :                 goto out;
    8053             :         }
    8054             : 
    8055             :         /* Write some data into it. */
    8056           4 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    8057             :                               NULL);
    8058           4 :         if (!NT_STATUS_IS_OK(status)) {
    8059           0 :                 printf("cli_write failed: %s\n", nt_errstr(status));
    8060           0 :                 goto out;
    8061             :         }
    8062             : 
    8063           4 :         cli_close(cli1, fnum1);
    8064             : 
    8065             :         /* Now create a hardlink. */
    8066           4 :         status = cli_posix_hardlink(cli1, fname, hname);
    8067           4 :         if (!NT_STATUS_IS_OK(status)) {
    8068           0 :                 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
    8069           0 :                 goto out;
    8070             :         }
    8071             : 
    8072             :         /* Now create a symlink. */
    8073           4 :         status = cli_posix_symlink(cli1, fname, sname);
    8074           4 :         if (!NT_STATUS_IS_OK(status)) {
    8075           0 :                 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
    8076           0 :                 goto out;
    8077             :         }
    8078             : 
    8079             :         /* Open the hardlink for read. */
    8080           4 :         status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
    8081           4 :         if (!NT_STATUS_IS_OK(status)) {
    8082           0 :                 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
    8083           0 :                 goto out;
    8084             :         }
    8085             : 
    8086           4 :         status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
    8087           4 :         if (!NT_STATUS_IS_OK(status)) {
    8088           0 :                 printf("POSIX read of %s failed (%s)\n", hname,
    8089             :                        nt_errstr(status));
    8090           0 :                 goto out;
    8091           4 :         } else if (nread != 10) {
    8092           0 :                 printf("POSIX read of %s failed. Received %ld, expected %d\n",
    8093             :                        hname, (unsigned long)nread, 10);
    8094           0 :                 goto out;
    8095             :         }
    8096             : 
    8097           4 :         if (memcmp(buf, "TEST DATA\n", 10)) {
    8098           0 :                 printf("invalid data read from hardlink\n");
    8099           0 :                 goto out;
    8100             :         }
    8101             : 
    8102             :         /* Do a POSIX lock/unlock. */
    8103           4 :         status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
    8104           4 :         if (!NT_STATUS_IS_OK(status)) {
    8105           0 :                 printf("POSIX lock failed %s\n", nt_errstr(status));
    8106           0 :                 goto out;
    8107             :         }
    8108             : 
    8109             :         /* Punch a hole in the locked area. */
    8110           4 :         status = cli_posix_unlock(cli1, fnum1, 10, 80);
    8111           4 :         if (!NT_STATUS_IS_OK(status)) {
    8112           0 :                 printf("POSIX unlock failed %s\n", nt_errstr(status));
    8113           0 :                 goto out;
    8114             :         }
    8115             : 
    8116           4 :         cli_close(cli1, fnum1);
    8117             : 
    8118             :         /* Open the symlink for read - this should fail. A POSIX
    8119             :            client should not be doing opens on a symlink. */
    8120           4 :         status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
    8121           4 :         if (NT_STATUS_IS_OK(status)) {
    8122           0 :                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
    8123           0 :                 goto out;
    8124             :         }
    8125           4 :         ok = check_both_error(
    8126             :                 __LINE__, status, ERRDOS, ERRbadpath,
    8127           4 :                 NT_STATUS_OBJECT_NAME_NOT_FOUND);
    8128           4 :         if (!ok) {
    8129           0 :                 printf("POSIX open of %s should have failed "
    8130             :                        "with NT_STATUS_OBJECT_NAME_NOT_FOUND, "
    8131             :                        "failed with %s instead.\n",
    8132             :                        sname, nt_errstr(status));
    8133           0 :                 goto out;
    8134             :         }
    8135             : 
    8136           4 :         status = cli_readlink(cli1, sname, talloc_tos(), &target, NULL, NULL);
    8137           4 :         if (!NT_STATUS_IS_OK(status)) {
    8138           0 :                 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
    8139           0 :                 goto out;
    8140             :         }
    8141             : 
    8142           4 :         if (strcmp(target, fname) != 0) {
    8143           0 :                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
    8144             :                         sname, fname, target);
    8145           0 :                 goto out;
    8146             :         }
    8147             : 
    8148           4 :         status = cli_posix_rmdir(cli1, dname);
    8149           4 :         if (!NT_STATUS_IS_OK(status)) {
    8150           0 :                 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
    8151           0 :                 goto out;
    8152             :         }
    8153             : 
    8154             :         /* Check directory opens with a specific permission. */
    8155           4 :         status = cli_posix_mkdir(cli1, dname, 0700);
    8156           4 :         if (!NT_STATUS_IS_OK(status)) {
    8157           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    8158           0 :                 goto out;
    8159             :         }
    8160             : 
    8161             :         /* Ensure st_mode == 0700 */
    8162           4 :         status = cli_posix_stat(cli1, dname, &sbuf);
    8163           4 :         if (!NT_STATUS_IS_OK(status)) {
    8164           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    8165           0 :                 goto out;
    8166             :         }
    8167             : 
    8168           4 :         if ((sbuf.st_ex_mode & 07777) != 0700) {
    8169           0 :                 printf("posix_mkdir - bad permissions 0%o != 0700\n",
    8170           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    8171           0 :                 goto out;
    8172             :         }
    8173             : 
    8174             :         /*
    8175             :          * Now create a Windows file, and attempt a POSIX unlink.
    8176             :          * This should fail with a sharing violation but due to:
    8177             :          *
    8178             :          * [Bug 9571] Unlink after open causes smbd to panic
    8179             :          *
    8180             :          * ensure we've fixed the lock ordering violation.
    8181             :          */
    8182             : 
    8183           4 :         status = cli_ntcreate(cli1, fname_windows, 0,
    8184             :                         FILE_READ_DATA|FILE_WRITE_DATA, 0,
    8185             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8186             :                         FILE_CREATE,
    8187             :                         0x0, 0x0, &fnum2, NULL);
    8188           4 :         if (!NT_STATUS_IS_OK(status)) {
    8189           0 :                 printf("Windows create of %s failed (%s)\n", fname_windows,
    8190             :                         nt_errstr(status));
    8191           0 :                 goto out;
    8192             :         }
    8193             : 
    8194             :         /* Now try posix_unlink. */
    8195           4 :         status = cli_posix_unlink(cli1, fname_windows);
    8196           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    8197           0 :                 printf("POSIX unlink of %s should fail "
    8198             :                         "with NT_STATUS_SHARING_VIOLATION "
    8199             :                         "got %s instead !\n",
    8200             :                         fname_windows,
    8201             :                         nt_errstr(status));
    8202           0 :                 goto out;
    8203             :         }
    8204             : 
    8205           4 :         cli_close(cli1, fnum2);
    8206             : 
    8207           4 :         printf("Simple POSIX open test passed\n");
    8208           4 :         correct = true;
    8209             : 
    8210           4 :   out:
    8211             : 
    8212           4 :         if (fnum1 != (uint16_t)-1) {
    8213           4 :                 cli_close(cli1, fnum1);
    8214           4 :                 fnum1 = (uint16_t)-1;
    8215             :         }
    8216             : 
    8217           4 :         if (fnum2 != (uint16_t)-1) {
    8218           4 :                 cli_close(cli1, fnum2);
    8219           4 :                 fnum2 = (uint16_t)-1;
    8220             :         }
    8221             : 
    8222           4 :         cli_setatr(cli1, sname, 0, 0);
    8223           4 :         cli_posix_unlink(cli1, sname);
    8224           4 :         cli_setatr(cli1, hname, 0, 0);
    8225           4 :         cli_posix_unlink(cli1, hname);
    8226           4 :         cli_setatr(cli1, fname, 0, 0);
    8227           4 :         cli_posix_unlink(cli1, fname);
    8228           4 :         cli_setatr(cli1, dname, 0, 0);
    8229           4 :         cli_posix_rmdir(cli1, dname);
    8230           4 :         cli_setatr(cli1, fname_windows, 0, 0);
    8231           4 :         cli_posix_unlink(cli1, fname_windows);
    8232             : 
    8233           4 :         if (!torture_close_connection(cli1)) {
    8234           0 :                 correct = false;
    8235             :         }
    8236             : 
    8237           4 :         return correct;
    8238             : }
    8239             : 
    8240             : /*
    8241             :   Test POSIX and Windows ACLs are rejected on symlinks.
    8242             :  */
    8243           4 : static bool run_acl_symlink_test(int dummy)
    8244             : {
    8245           0 :         static struct cli_state *cli;
    8246           4 :         const char *fname = "posix_file";
    8247           4 :         const char *sname = "posix_symlink";
    8248           4 :         uint16_t fnum = (uint16_t)-1;
    8249           4 :         bool correct = false;
    8250           0 :         NTSTATUS status;
    8251           4 :         char *posix_acl = NULL;
    8252           4 :         size_t posix_acl_len = 0;
    8253           4 :         char *posix_acl_sym = NULL;
    8254           4 :         size_t posix_acl_len_sym = 0;
    8255           4 :         struct security_descriptor *sd = NULL;
    8256           4 :         TALLOC_CTX *frame = NULL;
    8257             : 
    8258           4 :         frame = talloc_stackframe();
    8259             : 
    8260           4 :         printf("Starting acl symlink test\n");
    8261             : 
    8262           4 :         if (!torture_open_connection(&cli, 0)) {
    8263           0 :                 TALLOC_FREE(frame);
    8264           0 :                 return false;
    8265             :         }
    8266             : 
    8267           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8268             : 
    8269           4 :         status = torture_setup_unix_extensions(cli);
    8270           4 :         if (!NT_STATUS_IS_OK(status)) {
    8271           0 :                 TALLOC_FREE(frame);
    8272           0 :                 return false;
    8273             :         }
    8274             : 
    8275           4 :         cli_setatr(cli, fname, 0, 0);
    8276           4 :         cli_posix_unlink(cli, fname);
    8277           4 :         cli_setatr(cli, sname, 0, 0);
    8278           4 :         cli_posix_unlink(cli, sname);
    8279             : 
    8280           4 :         status = cli_ntcreate(cli,
    8281             :                         fname,
    8282             :                         0,
    8283             :                         READ_CONTROL_ACCESS,
    8284             :                         0,
    8285             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8286             :                         FILE_CREATE,
    8287             :                         0x0,
    8288             :                         0x0,
    8289             :                         &fnum,
    8290             :                         NULL);
    8291             : 
    8292           4 :         if (!NT_STATUS_IS_OK(status)) {
    8293           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8294             :                         fname,
    8295             :                         nt_errstr(status));
    8296           0 :                 goto out;
    8297             :         }
    8298             : 
    8299             :         /* Get the Windows ACL on the file. */
    8300           4 :         status = cli_query_secdesc(cli,
    8301             :                                 fnum,
    8302             :                                 frame,
    8303             :                                 &sd);
    8304           4 :         if (!NT_STATUS_IS_OK(status)) {
    8305           0 :                 printf("cli_query_secdesc failed (%s)\n",
    8306             :                         nt_errstr(status));
    8307           0 :                 goto out;
    8308             :         }
    8309             : 
    8310             :         /* Get the POSIX ACL on the file. */
    8311           4 :         status = cli_posix_getacl(cli,
    8312             :                                 fname,
    8313             :                                 frame,
    8314             :                                 &posix_acl_len,
    8315             :                                 &posix_acl);
    8316             : 
    8317           4 :         if (!NT_STATUS_IS_OK(status)) {
    8318           0 :                 printf("cli_posix_getacl failed (%s)\n",
    8319             :                         nt_errstr(status));
    8320           0 :                 goto out;
    8321             :         }
    8322             : 
    8323           4 :         status = cli_close(cli, fnum);
    8324           4 :         if (!NT_STATUS_IS_OK(status)) {
    8325           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    8326           0 :                 goto out;
    8327             :         }
    8328           4 :         fnum = (uint16_t)-1;
    8329             : 
    8330             :         /* Now create a symlink. */
    8331           4 :         status = cli_posix_symlink(cli, fname, sname);
    8332           4 :         if (!NT_STATUS_IS_OK(status)) {
    8333           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8334             :                         sname,
    8335             :                         fname,
    8336             :                         nt_errstr(status));
    8337           0 :                 goto out;
    8338             :         }
    8339             : 
    8340             :         /* Open a handle on the symlink for SD set/get should fail. */
    8341           4 :         status = cli_ntcreate(cli,
    8342             :                         sname,
    8343             :                         0,
    8344             :                         READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
    8345             :                         0,
    8346             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8347             :                         FILE_OPEN,
    8348             :                         0x0,
    8349             :                         0x0,
    8350             :                         &fnum,
    8351             :                         NULL);
    8352             : 
    8353           4 :         if (NT_STATUS_IS_OK(status)) {
    8354           0 :                 printf("Symlink open for getsd/setsd of %s "
    8355             :                         "succeeded (should fail)\n",
    8356             :                         sname);
    8357           0 :                 goto out;
    8358             :         }
    8359             : 
    8360             :         /* Try a stat-open on the symlink, should also fail. */
    8361           4 :         status = cli_ntcreate(cli,
    8362             :                         sname,
    8363             :                         0,
    8364             :                         FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES,
    8365             :                         0,
    8366             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8367             :                         FILE_OPEN,
    8368             :                         0x0,
    8369             :                         0x0,
    8370             :                         &fnum,
    8371             :                         NULL);
    8372             : 
    8373           4 :         if (NT_STATUS_IS_OK(status)) {
    8374           0 :                 printf("Stat-open of symlink succeeded (should fail)\n");
    8375           0 :                 goto out;
    8376             :         }
    8377             : 
    8378             :         /* Get the POSIX ACL on the symlink pathname. Should fail. */
    8379           4 :         status = cli_posix_getacl(cli,
    8380             :                                 sname,
    8381             :                                 frame,
    8382             :                                 &posix_acl_len_sym,
    8383             :                                 &posix_acl_sym);
    8384             : 
    8385           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8386           0 :                 printf("cli_posix_getacl on a symlink gave %s. "
    8387             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8388             :                         nt_errstr(status));
    8389           0 :                 goto out;
    8390             :         }
    8391             : 
    8392             :         /* Set the POSIX ACL on the symlink pathname. Should fail. */
    8393           4 :         status = cli_posix_setacl(cli,
    8394             :                                 sname,
    8395             :                                 posix_acl,
    8396             :                                 posix_acl_len);
    8397             : 
    8398           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8399           0 :                 printf("cli_posix_setacl on a symlink gave %s. "
    8400             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8401             :                         nt_errstr(status));
    8402           0 :                 goto out;
    8403             :         }
    8404             : 
    8405           4 :         printf("ACL symlink test passed\n");
    8406           4 :         correct = true;
    8407             : 
    8408           4 :   out:
    8409             : 
    8410           4 :         if (fnum != (uint16_t)-1) {
    8411           0 :                 cli_close(cli, fnum);
    8412           0 :                 fnum = (uint16_t)-1;
    8413             :         }
    8414             : 
    8415           4 :         cli_setatr(cli, sname, 0, 0);
    8416           4 :         cli_posix_unlink(cli, sname);
    8417           4 :         cli_setatr(cli, fname, 0, 0);
    8418           4 :         cli_posix_unlink(cli, fname);
    8419             : 
    8420           4 :         if (!torture_close_connection(cli)) {
    8421           0 :                 correct = false;
    8422             :         }
    8423             : 
    8424           4 :         TALLOC_FREE(frame);
    8425           4 :         return correct;
    8426             : }
    8427             : 
    8428             : /*
    8429             :   Test POSIX can delete a file containing streams.
    8430             :  */
    8431           4 : static bool run_posix_stream_delete(int dummy)
    8432             : {
    8433           4 :         struct cli_state *cli1 = NULL;
    8434           4 :         struct cli_state *cli2 = NULL;
    8435           4 :         const char *fname = "streamfile";
    8436           4 :         const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
    8437           4 :         uint16_t fnum1 = (uint16_t)-1;
    8438           4 :         bool correct = false;
    8439           0 :         NTSTATUS status;
    8440           4 :         TALLOC_CTX *frame = NULL;
    8441             : 
    8442           4 :         frame = talloc_stackframe();
    8443             : 
    8444           4 :         printf("Starting POSIX stream delete test\n");
    8445             : 
    8446           4 :         if (!torture_open_connection(&cli1, 0) ||
    8447           4 :                         !torture_open_connection(&cli2, 1)) {
    8448           0 :                 TALLOC_FREE(frame);
    8449           0 :                 return false;
    8450             :         }
    8451             : 
    8452           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    8453           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    8454             : 
    8455           4 :         status = torture_setup_unix_extensions(cli2);
    8456           4 :         if (!NT_STATUS_IS_OK(status)) {
    8457           0 :                 goto out;
    8458             :         }
    8459             : 
    8460           4 :         cli_setatr(cli1, fname, 0, 0);
    8461           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8462             : 
    8463             :         /* Create the file. */
    8464           4 :         status = cli_ntcreate(cli1,
    8465             :                         fname,
    8466             :                         0,
    8467             :                         READ_CONTROL_ACCESS,
    8468             :                         0,
    8469             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8470             :                         FILE_CREATE,
    8471             :                         0x0,
    8472             :                         0x0,
    8473             :                         &fnum1,
    8474             :                         NULL);
    8475             : 
    8476           4 :         if (!NT_STATUS_IS_OK(status)) {
    8477           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8478             :                         fname,
    8479             :                         nt_errstr(status));
    8480           0 :                 goto out;
    8481             :         }
    8482             : 
    8483           4 :         status = cli_close(cli1, fnum1);
    8484           4 :         if (!NT_STATUS_IS_OK(status)) {
    8485           0 :                 printf("cli_close of %s failed (%s)\n",
    8486             :                         fname,
    8487             :                         nt_errstr(status));
    8488           0 :                 goto out;
    8489             :         }
    8490           4 :         fnum1 = (uint16_t)-1;
    8491             : 
    8492             :         /* Now create the stream. */
    8493           4 :         status = cli_ntcreate(cli1,
    8494             :                         stream_fname,
    8495             :                         0,
    8496             :                         FILE_WRITE_DATA,
    8497             :                         0,
    8498             :                         FILE_SHARE_READ|FILE_SHARE_WRITE,
    8499             :                         FILE_CREATE,
    8500             :                         0x0,
    8501             :                         0x0,
    8502             :                         &fnum1,
    8503             :                         NULL);
    8504             : 
    8505           4 :         if (!NT_STATUS_IS_OK(status)) {
    8506           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8507             :                         stream_fname,
    8508             :                         nt_errstr(status));
    8509           0 :                 goto out;
    8510             :         }
    8511             : 
    8512             :         /* Leave the stream handle open... */
    8513             : 
    8514             :         /* POSIX unlink should fail. */
    8515           4 :         status = cli_posix_unlink(cli2, fname);
    8516           4 :         if (NT_STATUS_IS_OK(status)) {
    8517           0 :                 printf("cli_posix_unlink of %s succeeded, should have failed\n",
    8518             :                         fname);
    8519           0 :                 goto out;
    8520             :         }
    8521             : 
    8522           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    8523           0 :                 printf("cli_posix_unlink of %s failed with (%s) "
    8524             :                         "should have been NT_STATUS_SHARING_VIOLATION\n",
    8525             :                         fname,
    8526             :                         nt_errstr(status));
    8527           0 :                 goto out;
    8528             :         }
    8529             : 
    8530             :         /* Close the stream handle. */
    8531           4 :         status = cli_close(cli1, fnum1);
    8532           4 :         if (!NT_STATUS_IS_OK(status)) {
    8533           0 :                 printf("cli_close of %s failed (%s)\n",
    8534             :                         stream_fname,
    8535             :                         nt_errstr(status));
    8536           0 :                 goto out;
    8537             :         }
    8538           4 :         fnum1 = (uint16_t)-1;
    8539             : 
    8540             :         /* POSIX unlink after stream handle closed should succeed. */
    8541           4 :         status = cli_posix_unlink(cli2, fname);
    8542           4 :         if (!NT_STATUS_IS_OK(status)) {
    8543           0 :                 printf("cli_posix_unlink of %s failed (%s)\n",
    8544             :                         fname,
    8545             :                         nt_errstr(status));
    8546           0 :                 goto out;
    8547             :         }
    8548             : 
    8549           4 :         printf("POSIX stream delete test passed\n");
    8550           4 :         correct = true;
    8551             : 
    8552           4 :   out:
    8553             : 
    8554           4 :         if (fnum1 != (uint16_t)-1) {
    8555           0 :                 cli_close(cli1, fnum1);
    8556           0 :                 fnum1 = (uint16_t)-1;
    8557             :         }
    8558             : 
    8559           4 :         cli_setatr(cli1, fname, 0, 0);
    8560           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8561             : 
    8562           4 :         if (!torture_close_connection(cli1)) {
    8563           0 :                 correct = false;
    8564             :         }
    8565           4 :         if (!torture_close_connection(cli2)) {
    8566           0 :                 correct = false;
    8567             :         }
    8568             : 
    8569           4 :         TALLOC_FREE(frame);
    8570           4 :         return correct;
    8571             : }
    8572             : 
    8573             : /*
    8574             :   Test setting EA's are rejected on symlinks.
    8575             :  */
    8576           4 : static bool run_ea_symlink_test(int dummy)
    8577             : {
    8578           0 :         static struct cli_state *cli;
    8579           4 :         const char *fname = "posix_file_ea";
    8580           4 :         const char *sname = "posix_symlink_ea";
    8581           4 :         const char *ea_name = "testea_name";
    8582           4 :         const char *ea_value = "testea_value";
    8583           4 :         uint16_t fnum = (uint16_t)-1;
    8584           4 :         bool correct = false;
    8585           0 :         NTSTATUS status;
    8586           0 :         size_t i, num_eas;
    8587           4 :         struct ea_struct *eas = NULL;
    8588           4 :         TALLOC_CTX *frame = NULL;
    8589             : 
    8590           4 :         frame = talloc_stackframe();
    8591             : 
    8592           4 :         printf("Starting EA symlink test\n");
    8593             : 
    8594           4 :         if (!torture_open_connection(&cli, 0)) {
    8595           0 :                 TALLOC_FREE(frame);
    8596           0 :                 return false;
    8597             :         }
    8598             : 
    8599           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8600             : 
    8601           4 :         status = torture_setup_unix_extensions(cli);
    8602           4 :         if (!NT_STATUS_IS_OK(status)) {
    8603           0 :                 TALLOC_FREE(frame);
    8604           0 :                 return false;
    8605             :         }
    8606             : 
    8607           4 :         cli_setatr(cli, fname, 0, 0);
    8608           4 :         cli_posix_unlink(cli, fname);
    8609           4 :         cli_setatr(cli, sname, 0, 0);
    8610           4 :         cli_posix_unlink(cli, sname);
    8611             : 
    8612           4 :         status = cli_ntcreate(cli,
    8613             :                         fname,
    8614             :                         0,
    8615             :                         READ_CONTROL_ACCESS,
    8616             :                         0,
    8617             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8618             :                         FILE_CREATE,
    8619             :                         0x0,
    8620             :                         0x0,
    8621             :                         &fnum,
    8622             :                         NULL);
    8623             : 
    8624           4 :         if (!NT_STATUS_IS_OK(status)) {
    8625           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8626             :                         fname,
    8627             :                         nt_errstr(status));
    8628           0 :                 goto out;
    8629             :         }
    8630             : 
    8631           4 :         status = cli_close(cli, fnum);
    8632           4 :         if (!NT_STATUS_IS_OK(status)) {
    8633           0 :                 printf("close failed (%s)\n",
    8634             :                         nt_errstr(status));
    8635           0 :                 goto out;
    8636             :         }
    8637           4 :         fnum = (uint16_t)-1;
    8638             : 
    8639             :         /* Set an EA on the path. */
    8640           4 :         status = cli_set_ea_path(cli,
    8641             :                                 fname,
    8642             :                                 ea_name,
    8643             :                                 ea_value,
    8644           4 :                                 strlen(ea_value)+1);
    8645             : 
    8646           4 :         if (!NT_STATUS_IS_OK(status)) {
    8647           0 :                 printf("cli_set_ea_path failed (%s)\n",
    8648             :                         nt_errstr(status));
    8649           0 :                 goto out;
    8650             :         }
    8651             : 
    8652             :         /* Now create a symlink. */
    8653           4 :         status = cli_posix_symlink(cli, fname, sname);
    8654           4 :         if (!NT_STATUS_IS_OK(status)) {
    8655           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8656             :                         sname,
    8657             :                         fname,
    8658             :                         nt_errstr(status));
    8659           0 :                 goto out;
    8660             :         }
    8661             : 
    8662             :         /* Get the EA list on the path. Should return value set. */
    8663           4 :         status = cli_get_ea_list_path(cli,
    8664             :                                 fname,
    8665             :                                 frame,
    8666             :                                 &num_eas,
    8667             :                                 &eas);
    8668             : 
    8669           4 :         if (!NT_STATUS_IS_OK(status)) {
    8670           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8671             :                         nt_errstr(status));
    8672           0 :                 goto out;
    8673             :         }
    8674             : 
    8675             :         /* Ensure the EA we set is there. */
    8676           4 :         for (i=0; i<num_eas; i++) {
    8677           4 :                 if (strcmp(eas[i].name, ea_name) == 0 &&
    8678           4 :                                 eas[i].value.length == strlen(ea_value)+1 &&
    8679           4 :                                 memcmp(eas[i].value.data,
    8680             :                                         ea_value,
    8681           4 :                                         eas[i].value.length) == 0) {
    8682           4 :                         break;
    8683             :                 }
    8684             :         }
    8685             : 
    8686           4 :         if (i == num_eas) {
    8687           0 :                 printf("Didn't find EA on pathname %s\n",
    8688             :                         fname);
    8689           0 :                 goto out;
    8690             :         }
    8691             : 
    8692           4 :         num_eas = 0;
    8693           4 :         TALLOC_FREE(eas);
    8694             : 
    8695             :         /* Get the EA list on the symlink. Should return empty list. */
    8696           4 :         status = cli_get_ea_list_path(cli,
    8697             :                                 sname,
    8698             :                                 frame,
    8699             :                                 &num_eas,
    8700             :                                 &eas);
    8701             : 
    8702           4 :         if (!NT_STATUS_IS_OK(status)) {
    8703           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8704             :                         nt_errstr(status));
    8705           0 :                 goto out;
    8706             :         }
    8707             : 
    8708           4 :         if (num_eas != 0) {
    8709           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8710             :                         nt_errstr(status));
    8711           0 :                 goto out;
    8712             :         }
    8713             : 
    8714             :         /* Set an EA on the symlink. Should fail. */
    8715           4 :         status = cli_set_ea_path(cli,
    8716             :                                 sname,
    8717             :                                 ea_name,
    8718             :                                 ea_value,
    8719           4 :                                 strlen(ea_value)+1);
    8720             : 
    8721           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8722           0 :                 printf("cli_set_ea_path on a symlink gave %s. "
    8723             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8724             :                         nt_errstr(status));
    8725           0 :                 goto out;
    8726             :         }
    8727             : 
    8728           4 :         printf("EA symlink test passed\n");
    8729           4 :         correct = true;
    8730             : 
    8731           4 :   out:
    8732             : 
    8733           4 :         if (fnum != (uint16_t)-1) {
    8734           0 :                 cli_close(cli, fnum);
    8735           0 :                 fnum = (uint16_t)-1;
    8736             :         }
    8737             : 
    8738           4 :         cli_setatr(cli, sname, 0, 0);
    8739           4 :         cli_posix_unlink(cli, sname);
    8740           4 :         cli_setatr(cli, fname, 0, 0);
    8741           4 :         cli_posix_unlink(cli, fname);
    8742             : 
    8743           4 :         if (!torture_close_connection(cli)) {
    8744           0 :                 correct = false;
    8745             :         }
    8746             : 
    8747           4 :         TALLOC_FREE(frame);
    8748           4 :         return correct;
    8749             : }
    8750             : 
    8751             : /*
    8752             :   Test POSIX locks are OFD-locks.
    8753             :  */
    8754           4 : static bool run_posix_ofd_lock_test(int dummy)
    8755             : {
    8756           0 :         static struct cli_state *cli;
    8757           4 :         const char *fname = "posix_file";
    8758           4 :         uint16_t fnum1 = (uint16_t)-1;
    8759           4 :         uint16_t fnum2 = (uint16_t)-1;
    8760           4 :         bool correct = false;
    8761           0 :         NTSTATUS status;
    8762           4 :         TALLOC_CTX *frame = NULL;
    8763             : 
    8764           4 :         frame = talloc_stackframe();
    8765             : 
    8766           4 :         printf("Starting POSIX ofd-lock test\n");
    8767             : 
    8768           4 :         if (!torture_open_connection(&cli, 0)) {
    8769           0 :                 TALLOC_FREE(frame);
    8770           0 :                 return false;
    8771             :         }
    8772             : 
    8773           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8774             : 
    8775           4 :         status = torture_setup_unix_extensions(cli);
    8776           4 :         if (!NT_STATUS_IS_OK(status)) {
    8777           0 :                 TALLOC_FREE(frame);
    8778           0 :                 return false;
    8779             :         }
    8780             : 
    8781           4 :         cli_setatr(cli, fname, 0, 0);
    8782           4 :         cli_posix_unlink(cli, fname);
    8783             : 
    8784             :         /* Open the file twice. */
    8785           4 :         status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
    8786             :                                 0600, &fnum1);
    8787           4 :         if (!NT_STATUS_IS_OK(status)) {
    8788           0 :                 printf("First POSIX open of %s failed\n", fname);
    8789           0 :                 goto out;
    8790             :         }
    8791             : 
    8792           4 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
    8793           4 :         if (!NT_STATUS_IS_OK(status)) {
    8794           0 :                 printf("First POSIX open of %s failed\n", fname);
    8795           0 :                 goto out;
    8796             :         }
    8797             : 
    8798             :         /* Set a 0-50 lock on fnum1. */
    8799           4 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8800           4 :         if (!NT_STATUS_IS_OK(status)) {
    8801           0 :                 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
    8802           0 :                 goto out;
    8803             :         }
    8804             : 
    8805             :         /* Set a 60-100 lock on fnum2. */
    8806           4 :         status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
    8807           4 :         if (!NT_STATUS_IS_OK(status)) {
    8808           0 :                 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
    8809           0 :                 goto out;
    8810             :         }
    8811             : 
    8812             :         /* close fnum1 - 0-50 lock should go away. */
    8813           4 :         status = cli_close(cli, fnum1);
    8814           4 :         if (!NT_STATUS_IS_OK(status)) {
    8815           0 :                 printf("close failed (%s)\n",
    8816             :                         nt_errstr(status));
    8817           0 :                 goto out;
    8818             :         }
    8819           4 :         fnum1 = (uint16_t)-1;
    8820             : 
    8821             :         /* Change the lock context. */
    8822           4 :         cli_setpid(cli, cli_getpid(cli) + 1);
    8823             : 
    8824             :         /* Re-open fnum1. */
    8825           4 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
    8826           4 :         if (!NT_STATUS_IS_OK(status)) {
    8827           0 :                 printf("Third POSIX open of %s failed\n", fname);
    8828           0 :                 goto out;
    8829             :         }
    8830             : 
    8831             :         /* 60-100 lock should still be there. */
    8832           4 :         status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
    8833           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    8834           0 :                 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
    8835           0 :                 goto out;
    8836             :         }
    8837             : 
    8838             :         /* 0-50 lock should be gone. */
    8839           4 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8840           4 :         if (!NT_STATUS_IS_OK(status)) {
    8841           0 :                 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
    8842           0 :                 goto out;
    8843             :         }
    8844             : 
    8845           4 :         printf("POSIX OFD lock test passed\n");
    8846           4 :         correct = true;
    8847             : 
    8848           4 :   out:
    8849             : 
    8850           4 :         if (fnum1 != (uint16_t)-1) {
    8851           4 :                 cli_close(cli, fnum1);
    8852           4 :                 fnum1 = (uint16_t)-1;
    8853             :         }
    8854           4 :         if (fnum2 != (uint16_t)-1) {
    8855           4 :                 cli_close(cli, fnum2);
    8856           4 :                 fnum2 = (uint16_t)-1;
    8857             :         }
    8858             : 
    8859           4 :         cli_setatr(cli, fname, 0, 0);
    8860           4 :         cli_posix_unlink(cli, fname);
    8861             : 
    8862           4 :         if (!torture_close_connection(cli)) {
    8863           0 :                 correct = false;
    8864             :         }
    8865             : 
    8866           4 :         TALLOC_FREE(frame);
    8867           4 :         return correct;
    8868             : }
    8869             : 
    8870             : struct posix_blocking_state {
    8871             :         struct tevent_context *ev;
    8872             :         struct cli_state *cli1;
    8873             :         uint16_t fnum1;
    8874             :         struct cli_state *cli2;
    8875             :         uint16_t fnum2;
    8876             :         bool gotblocked;
    8877             :         bool gotecho;
    8878             : };
    8879             : 
    8880             : static void posix_blocking_locked(struct tevent_req *subreq);
    8881             : static void posix_blocking_gotblocked(struct tevent_req *subreq);
    8882             : static void posix_blocking_gotecho(struct tevent_req *subreq);
    8883             : static void posix_blocking_unlocked(struct tevent_req *subreq);
    8884             : 
    8885           4 : static struct tevent_req *posix_blocking_send(
    8886             :         TALLOC_CTX *mem_ctx,
    8887             :         struct tevent_context *ev,
    8888             :         struct cli_state *cli1,
    8889             :         uint16_t fnum1,
    8890             :         struct cli_state *cli2,
    8891             :         uint16_t fnum2)
    8892             : {
    8893           4 :         struct tevent_req *req = NULL, *subreq = NULL;
    8894           4 :         struct posix_blocking_state *state = NULL;
    8895             : 
    8896           4 :         req = tevent_req_create(mem_ctx, &state, struct posix_blocking_state);
    8897           4 :         if (req == NULL) {
    8898           0 :                 return NULL;
    8899             :         }
    8900           4 :         state->ev = ev;
    8901           4 :         state->cli1 = cli1;
    8902           4 :         state->fnum1 = fnum1;
    8903           4 :         state->cli2 = cli2;
    8904           4 :         state->fnum2 = fnum2;
    8905             : 
    8906           4 :         subreq = cli_posix_lock_send(
    8907             :                 state,
    8908           4 :                 state->ev,
    8909           4 :                 state->cli1,
    8910           4 :                 state->fnum1,
    8911             :                 0,
    8912             :                 1,
    8913             :                 false,
    8914             :                 WRITE_LOCK);
    8915           4 :         if (tevent_req_nomem(subreq, req)) {
    8916           0 :                 return tevent_req_post(req, ev);
    8917             :         }
    8918           4 :         tevent_req_set_callback(subreq, posix_blocking_locked, req);
    8919           4 :         return req;
    8920             : }
    8921             : 
    8922           4 : static void posix_blocking_locked(struct tevent_req *subreq)
    8923             : {
    8924           4 :         struct tevent_req *req = tevent_req_callback_data(
    8925             :                 subreq, struct tevent_req);
    8926           4 :         struct posix_blocking_state *state = tevent_req_data(
    8927             :                 req, struct posix_blocking_state);
    8928           0 :         NTSTATUS status;
    8929             : 
    8930           4 :         status = cli_posix_lock_recv(subreq);
    8931           4 :         TALLOC_FREE(subreq);
    8932           4 :         if (tevent_req_nterror(req, status)) {
    8933           0 :                 return;
    8934             :         }
    8935             : 
    8936           4 :         subreq = cli_posix_lock_send(
    8937             :                 state,
    8938             :                 state->ev,
    8939             :                 state->cli2,
    8940           4 :                 state->fnum2,
    8941             :                 0,
    8942             :                 1,
    8943             :                 true,
    8944             :                 WRITE_LOCK);
    8945           4 :         if (tevent_req_nomem(subreq, req)) {
    8946           0 :                 return;
    8947             :         }
    8948           4 :         tevent_req_set_callback(subreq, posix_blocking_gotblocked, req);
    8949             : 
    8950             :         /* Make sure the blocking request is delivered */
    8951           4 :         subreq = cli_echo_send(
    8952             :                 state,
    8953             :                 state->ev,
    8954             :                 state->cli2,
    8955             :                 1,
    8956           4 :                 (DATA_BLOB) { .data = (uint8_t *)state, .length = 1 });
    8957           4 :         if (tevent_req_nomem(subreq, req)) {
    8958           0 :                 return;
    8959             :         }
    8960           4 :         tevent_req_set_callback(subreq, posix_blocking_gotecho, req);
    8961             : }
    8962             : 
    8963           4 : static void posix_blocking_gotblocked(struct tevent_req *subreq)
    8964             : {
    8965           4 :         struct tevent_req *req = tevent_req_callback_data(
    8966             :                 subreq, struct tevent_req);
    8967           4 :         struct posix_blocking_state *state = tevent_req_data(
    8968             :                 req, struct posix_blocking_state);
    8969           0 :         NTSTATUS status;
    8970             : 
    8971           4 :         status = cli_posix_lock_recv(subreq);
    8972           4 :         TALLOC_FREE(subreq);
    8973           4 :         if (tevent_req_nterror(req, status)) {
    8974           0 :                 return;
    8975             :         }
    8976           4 :         if (!state->gotecho) {
    8977           0 :                 printf("blocked req got through before echo\n");
    8978           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    8979           0 :                 return;
    8980             :         }
    8981           4 :         tevent_req_done(req);
    8982             : }
    8983             : 
    8984           4 : static void posix_blocking_gotecho(struct tevent_req *subreq)
    8985             : {
    8986           4 :         struct tevent_req *req = tevent_req_callback_data(
    8987             :                 subreq, struct tevent_req);
    8988           4 :         struct posix_blocking_state *state = tevent_req_data(
    8989             :                 req, struct posix_blocking_state);
    8990           0 :         NTSTATUS status;
    8991             : 
    8992           4 :         status = cli_echo_recv(subreq);
    8993           4 :         TALLOC_FREE(subreq);
    8994           4 :         if (tevent_req_nterror(req, status)) {
    8995           0 :                 return;
    8996             :         }
    8997           4 :         if (state->gotblocked) {
    8998           0 :                 printf("blocked req got through before echo\n");
    8999           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    9000           0 :                 return;
    9001             :         }
    9002           4 :         state->gotecho = true;
    9003             : 
    9004           4 :         subreq = cli_posix_lock_send(
    9005             :                 state,
    9006             :                 state->ev,
    9007             :                 state->cli1,
    9008           4 :                 state->fnum1,
    9009             :                 0,
    9010             :                 1,
    9011             :                 false,
    9012             :                 UNLOCK_LOCK);
    9013           4 :         if (tevent_req_nomem(subreq, req)) {
    9014           0 :                 return;
    9015             :         }
    9016           4 :         tevent_req_set_callback(subreq, posix_blocking_unlocked, req);
    9017             : }
    9018             : 
    9019           4 : static void posix_blocking_unlocked(struct tevent_req *subreq)
    9020             : {
    9021           4 :         struct tevent_req *req = tevent_req_callback_data(
    9022             :                 subreq, struct tevent_req);
    9023           0 :         NTSTATUS status;
    9024             : 
    9025           4 :         status = cli_posix_lock_recv(subreq);
    9026           4 :         TALLOC_FREE(subreq);
    9027           4 :         if (tevent_req_nterror(req, status)) {
    9028           0 :                 return;
    9029             :         }
    9030             :         /* tevent_req_done in posix_blocking_gotlocked */
    9031             : }
    9032             : 
    9033           4 : static NTSTATUS posix_blocking_recv(struct tevent_req *req)
    9034             : {
    9035           4 :         return tevent_req_simple_recv_ntstatus(req);
    9036             : }
    9037             : 
    9038           4 : static bool run_posix_blocking_lock(int dummy)
    9039             : {
    9040           4 :         struct tevent_context *ev = NULL;
    9041           4 :         struct cli_state *cli1 = NULL, *cli2 = NULL;
    9042           4 :         const char *fname = "posix_blocking";
    9043           4 :         uint16_t fnum1 = UINT16_MAX, fnum2 = UINT16_MAX;
    9044           4 :         struct tevent_req *req = NULL;
    9045           0 :         NTSTATUS status;
    9046           4 :         bool ret = false;
    9047           0 :         bool ok;
    9048             : 
    9049           4 :         printf("Starting posix blocking lock test\n");
    9050             : 
    9051           4 :         ev = samba_tevent_context_init(NULL);
    9052           4 :         if (ev == NULL) {
    9053           0 :                 return false;
    9054             :         }
    9055             : 
    9056           4 :         ok = torture_open_connection(&cli1, 0);
    9057           4 :         if (!ok) {
    9058           0 :                 goto fail;
    9059             :         }
    9060           4 :         ok = torture_open_connection(&cli2, 0);
    9061           4 :         if (!ok) {
    9062           0 :                 goto fail;
    9063             :         }
    9064             : 
    9065           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9066             : 
    9067           4 :         status = torture_setup_unix_extensions(cli1);
    9068           4 :         if (!NT_STATUS_IS_OK(status)) {
    9069           0 :                 return false;
    9070             :         }
    9071             : 
    9072           4 :         status = torture_setup_unix_extensions(cli2);
    9073           4 :         if (!NT_STATUS_IS_OK(status)) {
    9074           0 :                 return false;
    9075             :         }
    9076             : 
    9077           4 :         cli_setatr(cli1, fname, 0, 0);
    9078           4 :         cli_posix_unlink(cli1, fname);
    9079             : 
    9080           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    9081             :                                 0600, &fnum1);
    9082           4 :         if (!NT_STATUS_IS_OK(status)) {
    9083           0 :                 printf("First POSIX open of %s failed: %s\n",
    9084             :                        fname,
    9085             :                        nt_errstr(status));
    9086           0 :                 goto fail;
    9087             :         }
    9088             : 
    9089           4 :         status = cli_posix_open(cli2, fname, O_RDWR, 0600, &fnum2);
    9090           4 :         if (!NT_STATUS_IS_OK(status)) {
    9091           0 :                 printf("Second POSIX open of %s failed: %s\n",
    9092             :                        fname,
    9093             :                        nt_errstr(status));
    9094           0 :                 goto fail;
    9095             :         }
    9096             : 
    9097           4 :         req = posix_blocking_send(ev, ev, cli1, fnum1, cli2, fnum2);
    9098           4 :         if (req == NULL) {
    9099           0 :                 printf("cli_posix_blocking failed\n");
    9100           0 :                 goto fail;
    9101             :         }
    9102             : 
    9103           4 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    9104           4 :         if (!ok) {
    9105           0 :                 printf("tevent_req_poll_ntstatus failed: %s\n",
    9106             :                        nt_errstr(status));
    9107           0 :                 goto fail;
    9108             :         }
    9109           4 :         status = posix_blocking_recv(req);
    9110           4 :         TALLOC_FREE(req);
    9111           4 :         if (!NT_STATUS_IS_OK(status)) {
    9112           0 :                 printf("posix_blocking_recv returned %s\n",
    9113             :                        nt_errstr(status));
    9114           0 :                 goto fail;
    9115             :         }
    9116             : 
    9117           4 :         ret = true;
    9118           4 : fail:
    9119             : 
    9120           4 :         if (fnum1 != UINT16_MAX) {
    9121           4 :                 cli_close(cli1, fnum1);
    9122           4 :                 fnum1 = UINT16_MAX;
    9123             :         }
    9124           4 :         if (fnum2 != UINT16_MAX) {
    9125           4 :                 cli_close(cli2, fnum2);
    9126           4 :                 fnum2 = UINT16_MAX;
    9127             :         }
    9128             : 
    9129           4 :         if (cli1 != NULL) {
    9130           4 :                 cli_setatr(cli1, fname, 0, 0);
    9131           4 :                 cli_posix_unlink(cli1, fname);
    9132             :         }
    9133             : 
    9134           4 :         ok = true;
    9135             : 
    9136           4 :         if (cli1 != NULL) {
    9137           4 :                 ok &= torture_close_connection(cli1);
    9138           4 :                 cli1 = NULL;
    9139             :         }
    9140           4 :         if (cli2 != NULL) {
    9141           4 :                 ok &= torture_close_connection(cli2);
    9142           4 :                 cli2 = NULL;
    9143             :         }
    9144             : 
    9145           4 :         if (!ok) {
    9146           0 :                 ret = false;
    9147             :         }
    9148           4 :         TALLOC_FREE(ev);
    9149           4 :         return ret;
    9150             : }
    9151             : 
    9152             : /*
    9153             :   Test POSIX mkdir is case-sensitive.
    9154             :  */
    9155           4 : static bool run_posix_mkdir_test(int dummy)
    9156             : {
    9157           0 :         static struct cli_state *cli;
    9158           4 :         const char *fname_foo = "POSIX_foo";
    9159           4 :         const char *fname_foo_Foo = "POSIX_foo/Foo";
    9160           4 :         const char *fname_foo_foo = "POSIX_foo/foo";
    9161           4 :         const char *fname_Foo = "POSIX_Foo";
    9162           4 :         const char *fname_Foo_Foo = "POSIX_Foo/Foo";
    9163           4 :         const char *fname_Foo_foo = "POSIX_Foo/foo";
    9164           4 :         bool correct = false;
    9165           0 :         NTSTATUS status;
    9166           4 :         TALLOC_CTX *frame = NULL;
    9167           4 :         uint16_t fnum = (uint16_t)-1;
    9168             : 
    9169           4 :         frame = talloc_stackframe();
    9170             : 
    9171           4 :         printf("Starting POSIX mkdir test\n");
    9172             : 
    9173           4 :         if (!torture_open_connection(&cli, 0)) {
    9174           0 :                 TALLOC_FREE(frame);
    9175           0 :                 return false;
    9176             :         }
    9177             : 
    9178           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9179             : 
    9180           4 :         status = torture_setup_unix_extensions(cli);
    9181           4 :         if (!NT_STATUS_IS_OK(status)) {
    9182           0 :                 TALLOC_FREE(frame);
    9183           0 :                 return false;
    9184             :         }
    9185             : 
    9186           4 :         cli_posix_rmdir(cli, fname_foo_foo);
    9187           4 :         cli_posix_rmdir(cli, fname_foo_Foo);
    9188           4 :         cli_posix_rmdir(cli, fname_foo);
    9189             : 
    9190           4 :         cli_posix_rmdir(cli, fname_Foo_foo);
    9191           4 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    9192           4 :         cli_posix_rmdir(cli, fname_Foo);
    9193             : 
    9194             :         /*
    9195             :          * Create a file POSIX_foo then try
    9196             :          * and use it in a directory path by
    9197             :          * doing mkdir POSIX_foo/bar.
    9198             :          * The mkdir should fail with
    9199             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND
    9200             :          */
    9201             : 
    9202           4 :         status = cli_posix_open(cli,
    9203             :                         fname_foo,
    9204             :                         O_RDWR|O_CREAT,
    9205             :                         0666,
    9206             :                         &fnum);
    9207           4 :         if (!NT_STATUS_IS_OK(status)) {
    9208           0 :                 printf("cli_posix_open of %s failed error %s\n",
    9209             :                         fname_foo,
    9210             :                         nt_errstr(status));
    9211           0 :                 goto out;
    9212             :         }
    9213             : 
    9214           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9215           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9216           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9217             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9218             :                         "%s instead\n",
    9219             :                         fname_foo_foo,
    9220             :                         nt_errstr(status));
    9221           0 :                 goto out;
    9222             :         }
    9223             : 
    9224           4 :         status = cli_close(cli, fnum);
    9225           4 :         if (!NT_STATUS_IS_OK(status)) {
    9226           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    9227           0 :                 goto out;
    9228             :         }
    9229           4 :         fnum = (uint16_t)-1;
    9230             : 
    9231           4 :         status = cli_posix_unlink(cli, fname_foo);
    9232           4 :         if (!NT_STATUS_IS_OK(status)) {
    9233           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
    9234             :                         fname_foo,
    9235             :                         nt_errstr(status));
    9236           0 :                 goto out;
    9237             :         }
    9238             : 
    9239             :         /*
    9240             :          * Now we've deleted everything, posix_mkdir, posix_rmdir,
    9241             :          * posix_open, posix_unlink, on
    9242             :          * POSIX_foo/foo should return NT_STATUS_OBJECT_PATH_NOT_FOUND
    9243             :          * not silently create POSIX_foo/foo.
    9244             :          */
    9245             : 
    9246           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9247           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9248           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9249             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9250             :                         "%s instead\n",
    9251             :                         fname_foo_foo,
    9252             :                         nt_errstr(status));
    9253           0 :                 goto out;
    9254             :         }
    9255             : 
    9256           4 :         status = cli_posix_rmdir(cli, fname_foo_foo);
    9257           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9258           0 :                 printf("cli_posix_rmdir of %s should fail with "
    9259             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9260             :                         "%s instead\n",
    9261             :                         fname_foo_foo,
    9262             :                         nt_errstr(status));
    9263           0 :                 goto out;
    9264             :         }
    9265             : 
    9266           4 :         status = cli_posix_open(cli,
    9267             :                         fname_foo_foo,
    9268             :                         O_RDWR|O_CREAT,
    9269             :                         0666,
    9270             :                         &fnum);
    9271           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9272           0 :                 printf("cli_posix_open of %s should fail with "
    9273             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9274             :                         "%s instead\n",
    9275             :                         fname_foo_foo,
    9276             :                         nt_errstr(status));
    9277           0 :                 goto out;
    9278             :         }
    9279             : 
    9280           4 :         status = cli_posix_unlink(cli, fname_foo_foo);
    9281           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9282           0 :                 printf("cli_posix_unlink of %s should fail with "
    9283             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9284             :                         "%s instead\n",
    9285             :                         fname_foo_foo,
    9286             :                         nt_errstr(status));
    9287           0 :                 goto out;
    9288             :         }
    9289             : 
    9290           4 :         status = cli_posix_mkdir(cli, fname_foo, 0777);
    9291           4 :         if (!NT_STATUS_IS_OK(status)) {
    9292           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo);
    9293           0 :                 goto out;
    9294             :         }
    9295             : 
    9296           4 :         status = cli_posix_mkdir(cli, fname_Foo, 0777);
    9297           4 :         if (!NT_STATUS_IS_OK(status)) {
    9298           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo);
    9299           0 :                 goto out;
    9300             :         }
    9301             : 
    9302           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9303           4 :         if (!NT_STATUS_IS_OK(status)) {
    9304           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_foo);
    9305           0 :                 goto out;
    9306             :         }
    9307             : 
    9308           4 :         status = cli_posix_mkdir(cli, fname_foo_Foo, 0777);
    9309           4 :         if (!NT_STATUS_IS_OK(status)) {
    9310           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_Foo);
    9311           0 :                 goto out;
    9312             :         }
    9313             : 
    9314           4 :         status = cli_posix_mkdir(cli, fname_Foo_foo, 0777);
    9315           4 :         if (!NT_STATUS_IS_OK(status)) {
    9316           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_foo);
    9317           0 :                 goto out;
    9318             :         }
    9319             : 
    9320           4 :         status = cli_posix_mkdir(cli, fname_Foo_Foo, 0777);
    9321           4 :         if (!NT_STATUS_IS_OK(status)) {
    9322           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_Foo);
    9323           0 :                 goto out;
    9324             :         }
    9325             : 
    9326           4 :         printf("POSIX mkdir test passed\n");
    9327           4 :         correct = true;
    9328             : 
    9329           4 :   out:
    9330             : 
    9331           4 :         if (fnum != (uint16_t)-1) {
    9332           0 :                 cli_close(cli, fnum);
    9333           0 :                 fnum = (uint16_t)-1;
    9334             :         }
    9335             : 
    9336           4 :         cli_posix_rmdir(cli, fname_foo_foo);
    9337           4 :         cli_posix_rmdir(cli, fname_foo_Foo);
    9338           4 :         cli_posix_rmdir(cli, fname_foo);
    9339             : 
    9340           4 :         cli_posix_rmdir(cli, fname_Foo_foo);
    9341           4 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    9342           4 :         cli_posix_rmdir(cli, fname_Foo);
    9343             : 
    9344           4 :         if (!torture_close_connection(cli)) {
    9345           0 :                 correct = false;
    9346             :         }
    9347             : 
    9348           4 :         TALLOC_FREE(frame);
    9349           4 :         return correct;
    9350             : }
    9351             : 
    9352             : struct posix_acl_oplock_state {
    9353             :         struct tevent_context *ev;
    9354             :         struct cli_state *cli;
    9355             :         bool *got_break;
    9356             :         bool *acl_ret;
    9357             :         NTSTATUS status;
    9358             : };
    9359             : 
    9360           4 : static void posix_acl_oplock_got_break(struct tevent_req *req)
    9361             : {
    9362           4 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9363             :                 req, struct posix_acl_oplock_state);
    9364           0 :         uint16_t fnum;
    9365           0 :         uint8_t level;
    9366           0 :         NTSTATUS status;
    9367             : 
    9368           4 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    9369           4 :         TALLOC_FREE(req);
    9370           4 :         if (!NT_STATUS_IS_OK(status)) {
    9371           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    9372             :                        nt_errstr(status));
    9373           0 :                 return;
    9374             :         }
    9375           4 :         *state->got_break = true;
    9376             : 
    9377           4 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    9378             :                                   NO_OPLOCK);
    9379           4 :         if (req == NULL) {
    9380           0 :                 printf("cli_oplock_ack_send failed\n");
    9381           0 :                 return;
    9382             :         }
    9383             : }
    9384             : 
    9385           4 : static void posix_acl_oplock_got_acl(struct tevent_req *req)
    9386             : {
    9387           4 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9388             :                 req, struct posix_acl_oplock_state);
    9389           4 :         size_t ret_size = 0;
    9390           4 :         char *ret_data = NULL;
    9391             : 
    9392           4 :         state->status = cli_posix_getacl_recv(req,
    9393             :                         state,
    9394             :                         &ret_size,
    9395             :                         &ret_data);
    9396             : 
    9397           4 :         if (!NT_STATUS_IS_OK(state->status)) {
    9398           0 :                 printf("cli_posix_getacl_recv returned %s\n",
    9399             :                         nt_errstr(state->status));
    9400             :         }
    9401           4 :         *state->acl_ret = true;
    9402           4 : }
    9403             : 
    9404           4 : static bool run_posix_acl_oplock_test(int dummy)
    9405             : {
    9406           0 :         struct tevent_context *ev;
    9407           0 :         struct cli_state *cli1, *cli2;
    9408           0 :         struct tevent_req *oplock_req, *getacl_req;
    9409           4 :         const char *fname = "posix_acl_oplock";
    9410           0 :         uint16_t fnum;
    9411           4 :         int saved_use_oplocks = use_oplocks;
    9412           0 :         NTSTATUS status;
    9413           4 :         bool correct = true;
    9414           4 :         bool got_break = false;
    9415           4 :         bool acl_ret = false;
    9416             : 
    9417           0 :         struct posix_acl_oplock_state *state;
    9418             : 
    9419           4 :         printf("starting posix_acl_oplock test\n");
    9420             : 
    9421           4 :         if (!torture_open_connection(&cli1, 0)) {
    9422           0 :                 use_level_II_oplocks = false;
    9423           0 :                 use_oplocks = saved_use_oplocks;
    9424           0 :                 return false;
    9425             :         }
    9426             : 
    9427           4 :         if (!torture_open_connection(&cli2, 1)) {
    9428           0 :                 use_level_II_oplocks = false;
    9429           0 :                 use_oplocks = saved_use_oplocks;
    9430           0 :                 return false;
    9431             :         }
    9432             : 
    9433             :         /* Setup posix on cli2 only. */
    9434           4 :         status = torture_setup_unix_extensions(cli2);
    9435           4 :         if (!NT_STATUS_IS_OK(status)) {
    9436           0 :                 return false;
    9437             :         }
    9438             : 
    9439           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9440           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    9441             : 
    9442           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9443             : 
    9444             :         /* Create the file on the Windows connection. */
    9445           4 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    9446             :                           &fnum);
    9447           4 :         if (!NT_STATUS_IS_OK(status)) {
    9448           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9449           0 :                 return false;
    9450             :         }
    9451             : 
    9452           4 :         status = cli_close(cli1, fnum);
    9453           4 :         if (!NT_STATUS_IS_OK(status)) {
    9454           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    9455           0 :                 return false;
    9456             :         }
    9457             : 
    9458           4 :         cli1->use_oplocks = true;
    9459             : 
    9460             :         /* Open with oplock. */
    9461           4 :         status = cli_ntcreate(cli1,
    9462             :                         fname,
    9463             :                         0,
    9464             :                         FILE_READ_DATA,
    9465             :                         FILE_ATTRIBUTE_NORMAL,
    9466             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    9467             :                         FILE_OPEN,
    9468             :                         0,
    9469             :                         0,
    9470             :                         &fnum,
    9471             :                         NULL);
    9472             : 
    9473           4 :         if (!NT_STATUS_IS_OK(status)) {
    9474           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9475           0 :                 return false;
    9476             :         }
    9477             : 
    9478           4 :         ev = samba_tevent_context_init(talloc_tos());
    9479           4 :         if (ev == NULL) {
    9480           0 :                 printf("tevent_context_init failed\n");
    9481           0 :                 return false;
    9482             :         }
    9483             : 
    9484           4 :         state = talloc_zero(ev, struct posix_acl_oplock_state);
    9485           4 :         if (state == NULL) {
    9486           0 :                 printf("talloc failed\n");
    9487           0 :                 return false;
    9488             :         }
    9489           4 :         state->ev = ev;
    9490           4 :         state->cli = cli1;
    9491           4 :         state->got_break = &got_break;
    9492           4 :         state->acl_ret = &acl_ret;
    9493             : 
    9494           4 :         oplock_req = cli_smb_oplock_break_waiter_send(
    9495             :                 talloc_tos(), ev, cli1);
    9496           4 :         if (oplock_req == NULL) {
    9497           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    9498           0 :                 return false;
    9499             :         }
    9500           4 :         tevent_req_set_callback(oplock_req, posix_acl_oplock_got_break, state);
    9501             : 
    9502             :         /* Get ACL on POSIX connection - should break oplock. */
    9503           4 :         getacl_req = cli_posix_getacl_send(talloc_tos(),
    9504             :                                 ev,
    9505             :                                 cli2,
    9506             :                                 fname);
    9507           4 :         if (getacl_req == NULL) {
    9508           0 :                 printf("cli_posix_getacl_send failed\n");
    9509           0 :                 return false;
    9510             :         }
    9511           4 :         tevent_req_set_callback(getacl_req, posix_acl_oplock_got_acl, state);
    9512             : 
    9513          36 :         while (!got_break || !acl_ret) {
    9514           0 :                 int ret;
    9515          32 :                 ret = tevent_loop_once(ev);
    9516          32 :                 if (ret == -1) {
    9517           0 :                         printf("tevent_loop_once failed: %s\n",
    9518           0 :                                strerror(errno));
    9519           0 :                         return false;
    9520             :                 }
    9521             :         }
    9522             : 
    9523           4 :         if (!NT_STATUS_IS_OK(state->status)) {
    9524           0 :                 printf("getacl failed (%s)\n", nt_errstr(state->status));
    9525           0 :                 correct = false;
    9526             :         }
    9527             : 
    9528           4 :         status = cli_close(cli1, fnum);
    9529           4 :         if (!NT_STATUS_IS_OK(status)) {
    9530           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    9531           0 :                 correct = false;
    9532             :         }
    9533             : 
    9534           4 :         status = cli_unlink(cli1,
    9535             :                         fname,
    9536             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9537           4 :         if (!NT_STATUS_IS_OK(status)) {
    9538           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    9539           0 :                 correct = false;
    9540             :         }
    9541             : 
    9542           4 :         if (!torture_close_connection(cli1)) {
    9543           0 :                 correct = false;
    9544             :         }
    9545           4 :         if (!torture_close_connection(cli2)) {
    9546           0 :                 correct = false;
    9547             :         }
    9548             : 
    9549           4 :         if (!got_break) {
    9550           0 :                 correct = false;
    9551             :         }
    9552             : 
    9553           4 :         printf("finished posix acl oplock test\n");
    9554             : 
    9555           4 :         return correct;
    9556             : }
    9557             : 
    9558           4 : static bool run_posix_acl_shareroot_test(int dummy)
    9559             : {
    9560           0 :         struct cli_state *cli;
    9561           0 :         NTSTATUS status;
    9562           4 :         bool correct = false;
    9563           4 :         char *posix_acl = NULL;
    9564           4 :         size_t posix_acl_len = 0;
    9565           4 :         uint16_t num_file_acls = 0;
    9566           4 :         uint16_t num_dir_acls = 0;
    9567           0 :         uint16_t i;
    9568           4 :         uint32_t expected_size = 0;
    9569           4 :         bool got_user = false;
    9570           4 :         bool got_group = false;
    9571           4 :         bool got_other = false;
    9572           4 :         TALLOC_CTX *frame = NULL;
    9573             : 
    9574           4 :         frame = talloc_stackframe();
    9575             : 
    9576           4 :         printf("starting posix_acl_shareroot test\n");
    9577             : 
    9578           4 :         if (!torture_open_connection(&cli, 0)) {
    9579           0 :                 TALLOC_FREE(frame);
    9580           0 :                 return false;
    9581             :         }
    9582             : 
    9583           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9584             : 
    9585           4 :         status = torture_setup_unix_extensions(cli);
    9586           4 :         if (!NT_STATUS_IS_OK(status)) {
    9587           0 :                 printf("Failed to setup unix extensions\n");
    9588           0 :                 goto out;
    9589             :         }
    9590             : 
    9591             :         /* Get the POSIX ACL on the root of the share. */
    9592           4 :         status = cli_posix_getacl(cli,
    9593             :                                 ".",
    9594             :                                 frame,
    9595             :                                 &posix_acl_len,
    9596             :                                 &posix_acl);
    9597             : 
    9598           4 :         if (!NT_STATUS_IS_OK(status)) {
    9599           0 :                 printf("cli_posix_getacl of '.' failed (%s)\n",
    9600             :                         nt_errstr(status));
    9601           0 :                 goto out;
    9602             :         }
    9603             : 
    9604           4 :         if (posix_acl_len < 6 ||
    9605           4 :                         SVAL(posix_acl,0) != SMB_POSIX_ACL_VERSION) {
    9606           0 :                 printf("getfacl ., unknown POSIX acl version %u.\n",
    9607           0 :                         (unsigned int)CVAL(posix_acl,0) );
    9608           0 :                 goto out;
    9609             :         }
    9610             : 
    9611           4 :         num_file_acls = SVAL(posix_acl,2);
    9612           4 :         num_dir_acls = SVAL(posix_acl,4);
    9613           4 :         expected_size = SMB_POSIX_ACL_HEADER_SIZE +
    9614           4 :                                 SMB_POSIX_ACL_ENTRY_SIZE*
    9615           4 :                                 (num_file_acls+num_dir_acls);
    9616             : 
    9617           4 :         if (posix_acl_len != expected_size) {
    9618           0 :                 printf("incorrect POSIX acl buffer size "
    9619             :                         "(should be %u, was %u).\n",
    9620             :                         (unsigned int)expected_size,
    9621             :                         (unsigned int)posix_acl_len);
    9622           0 :                 goto out;
    9623             :         }
    9624             : 
    9625             :         /*
    9626             :          * We don't need to know what the ACL's are
    9627             :          * we just need to know we have at least 3
    9628             :          * file entries (u,g,o).
    9629             :          */
    9630             : 
    9631          16 :         for (i = 0; i < num_file_acls; i++) {
    9632          12 :                 unsigned char tagtype =
    9633          12 :                         CVAL(posix_acl,
    9634             :                                 SMB_POSIX_ACL_HEADER_SIZE+
    9635             :                                 (i*SMB_POSIX_ACL_ENTRY_SIZE));
    9636             : 
    9637          12 :                 switch(tagtype) {
    9638           4 :                         case SMB_POSIX_ACL_USER_OBJ:
    9639           4 :                                 got_user = true;
    9640           4 :                                 break;
    9641           4 :                         case SMB_POSIX_ACL_GROUP_OBJ:
    9642           4 :                                 got_group = true;
    9643           4 :                                 break;
    9644           4 :                         case SMB_POSIX_ACL_OTHER:
    9645           4 :                                 got_other = true;
    9646           4 :                                 break;
    9647           0 :                         default:
    9648           0 :                                 break;
    9649             :                 }
    9650             :         }
    9651             : 
    9652           4 :         if (!got_user) {
    9653           0 :                 printf("Missing user entry\n");
    9654           0 :                 goto out;
    9655             :         }
    9656             : 
    9657           4 :         if (!got_group) {
    9658           0 :                 printf("Missing group entry\n");
    9659           0 :                 goto out;
    9660             :         }
    9661             : 
    9662           4 :         if (!got_other) {
    9663           0 :                 printf("Missing other entry\n");
    9664           0 :                 goto out;
    9665             :         }
    9666             : 
    9667           4 :         correct = true;
    9668             : 
    9669           4 :   out:
    9670             : 
    9671           4 :         if (!torture_close_connection(cli)) {
    9672           0 :                 correct = false;
    9673             :         }
    9674             : 
    9675           4 :         printf("finished posix acl shareroot test\n");
    9676           4 :         TALLOC_FREE(frame);
    9677             : 
    9678           4 :         return correct;
    9679             : }
    9680             : 
    9681             : static uint32_t open_attrs_table[] = {
    9682             :                 FILE_ATTRIBUTE_NORMAL,
    9683             :                 FILE_ATTRIBUTE_ARCHIVE,
    9684             :                 FILE_ATTRIBUTE_READONLY,
    9685             :                 FILE_ATTRIBUTE_HIDDEN,
    9686             :                 FILE_ATTRIBUTE_SYSTEM,
    9687             : 
    9688             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
    9689             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
    9690             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
    9691             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9692             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9693             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9694             : 
    9695             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9696             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9697             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9698             :                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
    9699             : };
    9700             : 
    9701             : struct trunc_open_results {
    9702             :         unsigned int num;
    9703             :         uint32_t init_attr;
    9704             :         uint32_t trunc_attr;
    9705             :         uint32_t result_attr;
    9706             : };
    9707             : 
    9708             : static struct trunc_open_results attr_results[] = {
    9709             :         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9710             :         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9711             :         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9712             :         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9713             :         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9714             :         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9715             :         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9716             :         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9717             :         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9718             :         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9719             :         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9720             :         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
    9721             :         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9722             :         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9723             :         { 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 },
    9724             :         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9725             :         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9726             :         { 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 },
    9727             :         { 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 },
    9728             :         { 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 },
    9729             :         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9730             :         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9731             :         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9732             :         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9733             :         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9734             :         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
    9735             : };
    9736             : 
    9737           0 : static bool run_openattrtest(int dummy)
    9738             : {
    9739           0 :         static struct cli_state *cli1;
    9740           0 :         const char *fname = "\\openattr.file";
    9741           0 :         uint16_t fnum1;
    9742           0 :         bool correct = True;
    9743           0 :         uint32_t attr;
    9744           0 :         unsigned int i, j, k, l;
    9745           0 :         NTSTATUS status;
    9746             : 
    9747           0 :         printf("starting open attr test\n");
    9748             : 
    9749           0 :         if (!torture_open_connection(&cli1, 0)) {
    9750           0 :                 return False;
    9751             :         }
    9752             : 
    9753           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9754             : 
    9755           0 :         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
    9756           0 :                 cli_setatr(cli1, fname, 0, 0);
    9757           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9758             : 
    9759           0 :                 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
    9760             :                                        open_attrs_table[i], FILE_SHARE_NONE,
    9761             :                                        FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    9762           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9763           0 :                         printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9764           0 :                         return False;
    9765             :                 }
    9766             : 
    9767           0 :                 status = cli_close(cli1, fnum1);
    9768           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9769           0 :                         printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9770           0 :                         return False;
    9771             :                 }
    9772             : 
    9773           0 :                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
    9774           0 :                         status = cli_ntcreate(cli1, fname, 0,
    9775             :                                               FILE_READ_DATA|FILE_WRITE_DATA,
    9776             :                                               open_attrs_table[j],
    9777             :                                               FILE_SHARE_NONE, FILE_OVERWRITE,
    9778             :                                               0, 0, &fnum1, NULL);
    9779           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9780           0 :                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9781           0 :                                         if (attr_results[l].num == k) {
    9782           0 :                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
    9783             :                                                                 k, open_attrs_table[i],
    9784             :                                                                 open_attrs_table[j],
    9785             :                                                                 fname, NT_STATUS_V(status), nt_errstr(status));
    9786           0 :                                                 correct = False;
    9787             :                                         }
    9788             :                                 }
    9789             : 
    9790           0 :                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    9791           0 :                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
    9792             :                                                         k, open_attrs_table[i], open_attrs_table[j],
    9793             :                                                         nt_errstr(status));
    9794           0 :                                         correct = False;
    9795             :                                 }
    9796             : #if 0
    9797             :                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
    9798             : #endif
    9799           0 :                                 k++;
    9800           0 :                                 continue;
    9801             :                         }
    9802             : 
    9803           0 :                         status = cli_close(cli1, fnum1);
    9804           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9805           0 :                                 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
    9806           0 :                                 return False;
    9807             :                         }
    9808             : 
    9809           0 :                         status = cli_getatr(cli1, fname, &attr, NULL, NULL);
    9810           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9811           0 :                                 printf("getatr(2) failed (%s)\n", nt_errstr(status));
    9812           0 :                                 return False;
    9813             :                         }
    9814             : 
    9815             : #if 0
    9816             :                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
    9817             :                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
    9818             : #endif
    9819             : 
    9820           0 :                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9821           0 :                                 if (attr_results[l].num == k) {
    9822           0 :                                         if (attr != attr_results[l].result_attr ||
    9823           0 :                                                         open_attrs_table[i] != attr_results[l].init_attr ||
    9824           0 :                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
    9825           0 :                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
    9826             :                                                 open_attrs_table[i],
    9827             :                                                 open_attrs_table[j],
    9828             :                                                 (unsigned int)attr,
    9829             :                                                 attr_results[l].result_attr);
    9830           0 :                                                 correct = False;
    9831             :                                         }
    9832           0 :                                         break;
    9833             :                                 }
    9834             :                         }
    9835           0 :                         k++;
    9836             :                 }
    9837             :         }
    9838             : 
    9839           0 :         cli_setatr(cli1, fname, 0, 0);
    9840           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9841             : 
    9842           0 :         printf("open attr test %s.\n", correct ? "passed" : "failed");
    9843             : 
    9844           0 :         if (!torture_close_connection(cli1)) {
    9845           0 :                 correct = False;
    9846             :         }
    9847           0 :         return correct;
    9848             : }
    9849             : 
    9850           0 : static NTSTATUS list_fn(struct file_info *finfo,
    9851             :                     const char *name, void *state)
    9852             : {
    9853           0 :         int *matched = (int *)state;
    9854           0 :         if (matched != NULL) {
    9855           0 :                 *matched += 1;
    9856             :         }
    9857           0 :         return NT_STATUS_OK;
    9858             : }
    9859             : 
    9860             : /*
    9861             :   test directory listing speed
    9862             :  */
    9863           5 : static bool run_dirtest(int dummy)
    9864             : {
    9865           0 :         int i;
    9866           0 :         static struct cli_state *cli;
    9867           0 :         uint16_t fnum;
    9868           0 :         struct timeval core_start;
    9869           5 :         bool correct = True;
    9870           0 :         int matched;
    9871             : 
    9872           5 :         printf("starting directory test\n");
    9873             : 
    9874           5 :         if (!torture_open_connection(&cli, 0)) {
    9875           0 :                 return False;
    9876             :         }
    9877             : 
    9878           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9879             : 
    9880           5 :         srandom(0);
    9881         505 :         for (i=0;i<torture_numops;i++) {
    9882           0 :                 fstring fname;
    9883         500 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9884         500 :                 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
    9885           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
    9886           0 :                         return False;
    9887             :                 }
    9888         500 :                 cli_close(cli, fnum);
    9889             :         }
    9890             : 
    9891           5 :         core_start = timeval_current();
    9892             : 
    9893           5 :         matched = 0;
    9894           5 :         cli_list(cli, "a*.*", 0, list_fn, &matched);
    9895           5 :         printf("Matched %d\n", matched);
    9896             : 
    9897           5 :         matched = 0;
    9898           5 :         cli_list(cli, "b*.*", 0, list_fn, &matched);
    9899           5 :         printf("Matched %d\n", matched);
    9900             : 
    9901           5 :         matched = 0;
    9902           5 :         cli_list(cli, "xyzabc", 0, list_fn, &matched);
    9903           5 :         printf("Matched %d\n", matched);
    9904             : 
    9905           5 :         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
    9906             : 
    9907           5 :         srandom(0);
    9908         505 :         for (i=0;i<torture_numops;i++) {
    9909           0 :                 fstring fname;
    9910         500 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9911         500 :                 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9912             :         }
    9913             : 
    9914           5 :         if (!torture_close_connection(cli)) {
    9915           0 :                 correct = False;
    9916             :         }
    9917             : 
    9918           5 :         printf("finished dirtest\n");
    9919             : 
    9920           5 :         return correct;
    9921             : }
    9922             : 
    9923           0 : static NTSTATUS del_fn(struct file_info *finfo, const char *mask,
    9924             :                    void *state)
    9925             : {
    9926           0 :         struct cli_state *pcli = (struct cli_state *)state;
    9927           0 :         fstring fname;
    9928           0 :         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
    9929             : 
    9930           0 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
    9931           0 :                 return NT_STATUS_OK;
    9932             : 
    9933           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
    9934           0 :                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
    9935           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
    9936             :         } else {
    9937           0 :                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
    9938           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
    9939             :         }
    9940           0 :         return NT_STATUS_OK;
    9941             : }
    9942             : 
    9943             : 
    9944             : /*
    9945             :    send a raw ioctl - used by the torture code
    9946             : */
    9947      327690 : static NTSTATUS cli_raw_ioctl(struct cli_state *cli,
    9948             :                               uint16_t fnum,
    9949             :                               uint32_t code,
    9950             :                               DATA_BLOB *blob)
    9951             : {
    9952           0 :         uint16_t vwv[3];
    9953           0 :         NTSTATUS status;
    9954             : 
    9955      327690 :         PUSH_LE_U16(vwv + 0, 0, fnum);
    9956      327690 :         PUSH_LE_U16(vwv + 1, 0, code >> 16);
    9957      327690 :         PUSH_LE_U16(vwv + 2, 0, (code & 0xFFFF));
    9958             : 
    9959      327690 :         status = cli_smb(talloc_tos(),
    9960             :                          cli,
    9961             :                          SMBioctl,
    9962             :                          0,
    9963             :                          3,
    9964             :                          vwv,
    9965             :                          0,
    9966             :                          NULL,
    9967             :                          NULL,
    9968             :                          0,
    9969             :                          NULL,
    9970             :                          NULL,
    9971             :                          NULL,
    9972             :                          NULL);
    9973      327690 :         if (!NT_STATUS_IS_OK(status)) {
    9974      327682 :                 return status;
    9975             :         }
    9976           8 :         *blob = data_blob_null;
    9977           8 :         return NT_STATUS_OK;
    9978             : }
    9979             : 
    9980             : /*
    9981             :   sees what IOCTLs are supported
    9982             :  */
    9983           5 : bool torture_ioctl_test(int dummy)
    9984             : {
    9985           0 :         static struct cli_state *cli;
    9986           0 :         uint16_t device, function;
    9987           0 :         uint16_t fnum;
    9988           5 :         const char *fname = "\\ioctl.dat";
    9989           0 :         DATA_BLOB blob;
    9990           0 :         NTSTATUS status;
    9991             : 
    9992           5 :         if (!torture_open_connection(&cli, 0)) {
    9993           0 :                 return False;
    9994             :         }
    9995             : 
    9996           5 :         printf("starting ioctl test\n");
    9997             : 
    9998           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9999             : 
   10000           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
   10001           5 :         if (!NT_STATUS_IS_OK(status)) {
   10002           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
   10003           0 :                 return False;
   10004             :         }
   10005             : 
   10006           5 :         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
   10007           5 :         printf("ioctl device info: %s\n", nt_errstr(status));
   10008             : 
   10009           5 :         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
   10010           5 :         printf("ioctl job info: %s\n", nt_errstr(status));
   10011             : 
   10012        1285 :         for (device=0;device<0x100;device++) {
   10013        1280 :                 printf("ioctl test with device = 0x%x\n", device);
   10014      328960 :                 for (function=0;function<0x100;function++) {
   10015      327680 :                         uint32_t code = (device<<16) | function;
   10016             : 
   10017      327680 :                         status = cli_raw_ioctl(cli, fnum, code, &blob);
   10018             : 
   10019      327680 :                         if (NT_STATUS_IS_OK(status)) {
   10020           4 :                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
   10021           4 :                                        (int)blob.length);
   10022           4 :                                 data_blob_free(&blob);
   10023             :                         }
   10024             :                 }
   10025             :         }
   10026             : 
   10027           5 :         if (!torture_close_connection(cli)) {
   10028           0 :                 return False;
   10029             :         }
   10030             : 
   10031           5 :         return True;
   10032             : }
   10033             : 
   10034             : 
   10035             : /*
   10036             :   tries variants of chkpath
   10037             :  */
   10038           5 : bool torture_chkpath_test(int dummy)
   10039             : {
   10040           0 :         static struct cli_state *cli;
   10041           0 :         uint16_t fnum;
   10042           0 :         bool ret;
   10043           0 :         NTSTATUS status;
   10044             : 
   10045           5 :         if (!torture_open_connection(&cli, 0)) {
   10046           0 :                 return False;
   10047             :         }
   10048             : 
   10049           5 :         printf("starting chkpath test\n");
   10050             : 
   10051             :         /* cleanup from an old run */
   10052           5 :         torture_deltree(cli, "\\chkpath.dir");
   10053             : 
   10054           5 :         status = cli_mkdir(cli, "\\chkpath.dir");
   10055           5 :         if (!NT_STATUS_IS_OK(status)) {
   10056           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
   10057           0 :                 return False;
   10058             :         }
   10059             : 
   10060           5 :         status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
   10061           5 :         if (!NT_STATUS_IS_OK(status)) {
   10062           0 :                 printf("mkdir2 failed : %s\n", nt_errstr(status));
   10063           0 :                 return False;
   10064             :         }
   10065             : 
   10066           5 :         status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
   10067             :                           DENY_NONE, &fnum);
   10068           5 :         if (!NT_STATUS_IS_OK(status)) {
   10069           0 :                 printf("open1 failed (%s)\n", nt_errstr(status));
   10070           0 :                 return False;
   10071             :         }
   10072           5 :         cli_close(cli, fnum);
   10073             : 
   10074           5 :         status = cli_chkpath(cli, "\\chkpath.dir");
   10075           5 :         if (!NT_STATUS_IS_OK(status)) {
   10076           0 :                 printf("chkpath1 failed: %s\n", nt_errstr(status));
   10077           0 :                 ret = False;
   10078             :         }
   10079             : 
   10080           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
   10081           5 :         if (!NT_STATUS_IS_OK(status)) {
   10082           0 :                 printf("chkpath2 failed: %s\n", nt_errstr(status));
   10083           0 :                 ret = False;
   10084             :         }
   10085             : 
   10086           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
   10087           5 :         if (!NT_STATUS_IS_OK(status)) {
   10088           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
   10089           5 :                                   NT_STATUS_NOT_A_DIRECTORY);
   10090             :         } else {
   10091           0 :                 printf("* chkpath on a file should fail\n");
   10092           0 :                 ret = False;
   10093             :         }
   10094             : 
   10095           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
   10096           5 :         if (!NT_STATUS_IS_OK(status)) {
   10097           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
   10098           5 :                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
   10099             :         } else {
   10100           0 :                 printf("* chkpath on a non existent file should fail\n");
   10101           0 :                 ret = False;
   10102             :         }
   10103             : 
   10104           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
   10105           5 :         if (!NT_STATUS_IS_OK(status)) {
   10106           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
   10107           5 :                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
   10108             :         } else {
   10109           0 :                 printf("* chkpath on a non existent component should fail\n");
   10110           0 :                 ret = False;
   10111             :         }
   10112             : 
   10113           5 :         torture_deltree(cli, "\\chkpath.dir");
   10114             : 
   10115           5 :         if (!torture_close_connection(cli)) {
   10116           0 :                 return False;
   10117             :         }
   10118             : 
   10119           5 :         return ret;
   10120             : }
   10121             : 
   10122           0 : static bool run_eatest(int dummy)
   10123             : {
   10124           0 :         static struct cli_state *cli;
   10125           0 :         const char *fname = "\\eatest.txt";
   10126           0 :         bool correct = True;
   10127           0 :         uint16_t fnum;
   10128           0 :         size_t i, num_eas;
   10129           0 :         struct ea_struct *ea_list = NULL;
   10130           0 :         TALLOC_CTX *mem_ctx = talloc_init("eatest");
   10131           0 :         NTSTATUS status;
   10132             : 
   10133           0 :         printf("starting eatest\n");
   10134             : 
   10135           0 :         if (!torture_open_connection(&cli, 0)) {
   10136           0 :                 talloc_destroy(mem_ctx);
   10137           0 :                 return False;
   10138             :         }
   10139             : 
   10140           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   10141             : 
   10142           0 :         status = cli_ntcreate(cli, fname, 0,
   10143             :                               FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
   10144             :                               FILE_SHARE_NONE, FILE_OVERWRITE_IF,
   10145             :                               0x4044, 0, &fnum, NULL);
   10146           0 :         if (!NT_STATUS_IS_OK(status)) {
   10147           0 :                 printf("open failed - %s\n", nt_errstr(status));
   10148           0 :                 talloc_destroy(mem_ctx);
   10149           0 :                 return False;
   10150             :         }
   10151             : 
   10152           0 :         for (i = 0; i < 10; i++) {
   10153           0 :                 fstring ea_name, ea_val;
   10154             : 
   10155           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%zu", i);
   10156           0 :                 memset(ea_val, (char)i+1, i+1);
   10157           0 :                 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
   10158           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10159           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10160             :                                nt_errstr(status));
   10161           0 :                         talloc_destroy(mem_ctx);
   10162           0 :                         return False;
   10163             :                 }
   10164             :         }
   10165             : 
   10166           0 :         cli_close(cli, fnum);
   10167           0 :         for (i = 0; i < 10; i++) {
   10168           0 :                 fstring ea_name, ea_val;
   10169             : 
   10170           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%zu", i+10);
   10171           0 :                 memset(ea_val, (char)i+1, i+1);
   10172           0 :                 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
   10173           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10174           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10175             :                                nt_errstr(status));
   10176           0 :                         talloc_destroy(mem_ctx);
   10177           0 :                         return False;
   10178             :                 }
   10179             :         }
   10180             : 
   10181           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
   10182           0 :         if (!NT_STATUS_IS_OK(status)) {
   10183           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
   10184           0 :                 correct = False;
   10185             :         }
   10186             : 
   10187           0 :         printf("num_eas = %d\n", (int)num_eas);
   10188             : 
   10189           0 :         if (num_eas != 20) {
   10190           0 :                 printf("Should be 20 EA's stored... failing.\n");
   10191           0 :                 correct = False;
   10192             :         }
   10193             : 
   10194           0 :         for (i = 0; i < num_eas; i++) {
   10195           0 :                 printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
   10196           0 :                 dump_data(0, ea_list[i].value.data,
   10197           0 :                           ea_list[i].value.length);
   10198             :         }
   10199             : 
   10200             :         /* Setting EA's to zero length deletes them. Test this */
   10201           0 :         printf("Now deleting all EA's - case independent....\n");
   10202             : 
   10203             : #if 1
   10204           0 :         cli_set_ea_path(cli, fname, "", "", 0);
   10205             : #else
   10206             :         for (i = 0; i < 20; i++) {
   10207             :                 fstring ea_name;
   10208             :                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
   10209             :                 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
   10210             :                 if (!NT_STATUS_IS_OK(status)) {
   10211             :                         printf("ea_set of name %s failed - %s\n", ea_name,
   10212             :                                nt_errstr(status));
   10213             :                         talloc_destroy(mem_ctx);
   10214             :                         return False;
   10215             :                 }
   10216             :         }
   10217             : #endif
   10218             : 
   10219           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
   10220           0 :         if (!NT_STATUS_IS_OK(status)) {
   10221           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
   10222           0 :                 correct = False;
   10223             :         }
   10224             : 
   10225           0 :         printf("num_eas = %d\n", (int)num_eas);
   10226           0 :         for (i = 0; i < num_eas; i++) {
   10227           0 :                 printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
   10228           0 :                 dump_data(0, ea_list[i].value.data,
   10229           0 :                           ea_list[i].value.length);
   10230             :         }
   10231             : 
   10232           0 :         if (num_eas != 0) {
   10233           0 :                 printf("deleting EA's failed.\n");
   10234           0 :                 correct = False;
   10235             :         }
   10236             : 
   10237             :         /* Try and delete a non existent EA. */
   10238           0 :         status = cli_set_ea_path(cli, fname, "foo", "", 0);
   10239           0 :         if (!NT_STATUS_IS_OK(status)) {
   10240           0 :                 printf("deleting non-existent EA 'foo' should succeed. %s\n",
   10241             :                        nt_errstr(status));
   10242           0 :                 correct = False;
   10243             :         }
   10244             : 
   10245           0 :         talloc_destroy(mem_ctx);
   10246           0 :         if (!torture_close_connection(cli)) {
   10247           0 :                 correct = False;
   10248             :         }
   10249             : 
   10250           0 :         return correct;
   10251             : }
   10252             : 
   10253           0 : static bool run_dirtest1(int dummy)
   10254             : {
   10255           0 :         int i;
   10256           0 :         static struct cli_state *cli;
   10257           0 :         uint16_t fnum;
   10258           0 :         int num_seen;
   10259           0 :         bool correct = True;
   10260             : 
   10261           0 :         printf("starting directory test\n");
   10262             : 
   10263           0 :         if (!torture_open_connection(&cli, 0)) {
   10264           0 :                 return False;
   10265             :         }
   10266             : 
   10267           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   10268             : 
   10269           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10270           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10271           0 :         cli_rmdir(cli, "\\LISTDIR");
   10272           0 :         cli_mkdir(cli, "\\LISTDIR");
   10273             : 
   10274             :         /* Create 1000 files and 1000 directories. */
   10275           0 :         for (i=0;i<1000;i++) {
   10276           0 :                 fstring fname;
   10277           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
   10278           0 :                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
   10279             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
   10280             :                                    0, 0, &fnum, NULL))) {
   10281           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10282           0 :                         return False;
   10283             :                 }
   10284           0 :                 cli_close(cli, fnum);
   10285             :         }
   10286           0 :         for (i=0;i<1000;i++) {
   10287           0 :                 fstring fname;
   10288           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
   10289           0 :                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
   10290           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10291           0 :                         return False;
   10292             :                 }
   10293             :         }
   10294             : 
   10295             :         /* Now ensure that doing an old list sees both files and directories. */
   10296           0 :         num_seen = 0;
   10297           0 :         cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10298           0 :         printf("num_seen = %d\n", num_seen );
   10299             :         /* We should see 100 files + 1000 directories + . and .. */
   10300           0 :         if (num_seen != 2002)
   10301           0 :                 correct = False;
   10302             : 
   10303             :         /* Ensure if we have the "must have" bits we only see the
   10304             :          * relevant entries.
   10305             :          */
   10306           0 :         num_seen = 0;
   10307           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10308           0 :         printf("num_seen = %d\n", num_seen );
   10309           0 :         if (num_seen != 1002)
   10310           0 :                 correct = False;
   10311             : 
   10312           0 :         num_seen = 0;
   10313           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10314           0 :         printf("num_seen = %d\n", num_seen );
   10315           0 :         if (num_seen != 1000)
   10316           0 :                 correct = False;
   10317             : 
   10318             :         /* Delete everything. */
   10319           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10320           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10321           0 :         cli_rmdir(cli, "\\LISTDIR");
   10322             : 
   10323             : #if 0
   10324             :         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
   10325             :         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
   10326             :         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
   10327             : #endif
   10328             : 
   10329           0 :         if (!torture_close_connection(cli)) {
   10330           0 :                 correct = False;
   10331             :         }
   10332             : 
   10333           0 :         printf("finished dirtest1\n");
   10334             : 
   10335           0 :         return correct;
   10336             : }
   10337             : 
   10338           0 : static bool run_error_map_extract(int dummy) {
   10339             : 
   10340           0 :         static struct cli_state *c_dos;
   10341           0 :         static struct cli_state *c_nt;
   10342           0 :         NTSTATUS status;
   10343             : 
   10344           0 :         uint32_t error;
   10345             : 
   10346           0 :         uint32_t errnum;
   10347           0 :         uint8_t errclass;
   10348             : 
   10349           0 :         NTSTATUS nt_status;
   10350             : 
   10351           0 :         fstring user;
   10352             : 
   10353             :         /* NT-Error connection */
   10354             : 
   10355           0 :         disable_spnego = true;
   10356           0 :         if (!(c_nt = open_nbt_connection())) {
   10357           0 :                 disable_spnego = false;
   10358           0 :                 return False;
   10359             :         }
   10360           0 :         disable_spnego = false;
   10361             : 
   10362           0 :         status = smbXcli_negprot(c_nt->conn,
   10363           0 :                                  c_nt->timeout,
   10364             :                                  PROTOCOL_CORE,
   10365             :                                  PROTOCOL_NT1,
   10366             :                                  NULL,
   10367             :                                  NULL,
   10368             :                                  NULL);
   10369             : 
   10370           0 :         if (!NT_STATUS_IS_OK(status)) {
   10371           0 :                 printf("%s rejected the NT-error negprot (%s)\n", host,
   10372             :                        nt_errstr(status));
   10373           0 :                 cli_shutdown(c_nt);
   10374           0 :                 return False;
   10375             :         }
   10376             : 
   10377           0 :         status = cli_session_setup_anon(c_nt);
   10378           0 :         if (!NT_STATUS_IS_OK(status)) {
   10379           0 :                 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
   10380           0 :                 return False;
   10381             :         }
   10382             : 
   10383             :         /* DOS-Error connection */
   10384             : 
   10385           0 :         disable_spnego = true;
   10386           0 :         force_dos_errors = true;
   10387           0 :         if (!(c_dos = open_nbt_connection())) {
   10388           0 :                 disable_spnego = false;
   10389           0 :                 force_dos_errors = false;
   10390           0 :                 return False;
   10391             :         }
   10392           0 :         disable_spnego = false;
   10393           0 :         force_dos_errors = false;
   10394             : 
   10395           0 :         status = smbXcli_negprot(c_dos->conn,
   10396           0 :                                  c_dos->timeout,
   10397             :                                  PROTOCOL_CORE,
   10398             :                                  PROTOCOL_NT1,
   10399             :                                  NULL,
   10400             :                                  NULL,
   10401             :                                  NULL);
   10402           0 :         if (!NT_STATUS_IS_OK(status)) {
   10403           0 :                 printf("%s rejected the DOS-error negprot (%s)\n", host,
   10404             :                        nt_errstr(status));
   10405           0 :                 cli_shutdown(c_dos);
   10406           0 :                 return False;
   10407             :         }
   10408             : 
   10409           0 :         status = cli_session_setup_anon(c_dos);
   10410           0 :         if (!NT_STATUS_IS_OK(status)) {
   10411           0 :                 printf("%s rejected the DOS-error initial session setup (%s)\n",
   10412             :                         host, nt_errstr(status));
   10413           0 :                 return False;
   10414             :         }
   10415             : 
   10416           0 :         c_nt->map_dos_errors = false;
   10417           0 :         c_dos->map_dos_errors = false;
   10418             : 
   10419           0 :         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
   10420           0 :                 struct cli_credentials *user_creds = NULL;
   10421             : 
   10422           0 :                 fstr_sprintf(user, "%X", error);
   10423             : 
   10424           0 :                 user_creds = cli_session_creds_init(talloc_tos(),
   10425             :                                                     user,
   10426             :                                                     workgroup,
   10427             :                                                     NULL, /* realm */
   10428             :                                                     password,
   10429             :                                                     false, /* use_kerberos */
   10430             :                                                     false, /* fallback_after_kerberos */
   10431             :                                                     false, /* use_ccache */
   10432             :                                                     false); /* password_is_nt_hash */
   10433           0 :                 if (user_creds == NULL) {
   10434           0 :                         printf("cli_session_creds_init(%s) failed\n", user);
   10435           0 :                         return false;
   10436             :                 }
   10437             : 
   10438           0 :                 status = cli_session_setup_creds(c_nt, user_creds);
   10439           0 :                 if (NT_STATUS_IS_OK(status)) {
   10440           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10441             :                 }
   10442             : 
   10443             :                 /* Case #1: 32-bit NT errors */
   10444           0 :                 if (!NT_STATUS_IS_DOS(status)) {
   10445           0 :                         nt_status = status;
   10446             :                 } else {
   10447           0 :                         printf("/** Dos error on NT connection! (%s) */\n",
   10448             :                                nt_errstr(status));
   10449           0 :                         nt_status = NT_STATUS(0xc0000000);
   10450             :                 }
   10451             : 
   10452           0 :                 status = cli_session_setup_creds(c_dos, user_creds);
   10453           0 :                 if (NT_STATUS_IS_OK(status)) {
   10454           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10455             :                 }
   10456             : 
   10457             :                 /* Case #1: 32-bit NT errors */
   10458           0 :                 if (NT_STATUS_IS_DOS(status)) {
   10459           0 :                         printf("/** NT error on DOS connection! (%s) */\n",
   10460             :                                nt_errstr(status));
   10461           0 :                         errnum = errclass = 0;
   10462             :                 } else {
   10463           0 :                         errclass = NT_STATUS_DOS_CLASS(status);
   10464           0 :                         errnum = NT_STATUS_DOS_CODE(status);
   10465             :                 }
   10466             : 
   10467           0 :                 if (NT_STATUS_V(nt_status) != error) {
   10468           0 :                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
   10469           0 :                                get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
   10470           0 :                                get_nt_error_c_code(talloc_tos(), nt_status));
   10471             :                 }
   10472             : 
   10473           0 :                 printf("\t{%s,\t%s,\t%s},\n",
   10474             :                        smb_dos_err_class(errclass),
   10475             :                        smb_dos_err_name(errclass, errnum),
   10476           0 :                        get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
   10477             : 
   10478           0 :                 TALLOC_FREE(user_creds);
   10479             :         }
   10480           0 :         return True;
   10481             : }
   10482             : 
   10483           0 : static bool run_sesssetup_bench(int dummy)
   10484             : {
   10485           0 :         static struct cli_state *c;
   10486           0 :         const char *fname = "\\file.dat";
   10487           0 :         uint16_t fnum;
   10488           0 :         NTSTATUS status;
   10489           0 :         int i;
   10490             : 
   10491           0 :         if (!torture_open_connection(&c, 0)) {
   10492           0 :                 return false;
   10493             :         }
   10494             : 
   10495           0 :         status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   10496             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   10497             :                               FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
   10498           0 :         if (!NT_STATUS_IS_OK(status)) {
   10499           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   10500           0 :                 return false;
   10501             :         }
   10502             : 
   10503           0 :         for (i=0; i<torture_numops; i++) {
   10504           0 :                 status = cli_session_setup_creds(c, torture_creds);
   10505           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10506           0 :                         d_printf("(%s) cli_session_setup_creds failed: %s\n",
   10507             :                                  __location__, nt_errstr(status));
   10508           0 :                         return false;
   10509             :                 }
   10510             : 
   10511           0 :                 d_printf("\r%d   ", (int)cli_state_get_uid(c));
   10512             : 
   10513           0 :                 status = cli_ulogoff(c);
   10514           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10515           0 :                         d_printf("(%s) cli_ulogoff failed: %s\n",
   10516             :                                  __location__, nt_errstr(status));
   10517           0 :                         return false;
   10518             :                 }
   10519             :         }
   10520             : 
   10521           0 :         return true;
   10522             : }
   10523             : 
   10524           9 : static bool subst_test(const char *str, const char *user, const char *domain,
   10525             :                        uid_t uid, gid_t gid, const char *expected)
   10526             : {
   10527           9 :         char *subst;
   10528           9 :         bool result = true;
   10529             : 
   10530           9 :         subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
   10531             : 
   10532           9 :         if (strcmp(subst, expected) != 0) {
   10533           0 :                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
   10534             :                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
   10535             :                        expected);
   10536           0 :                 result = false;
   10537             :         }
   10538             : 
   10539           9 :         TALLOC_FREE(subst);
   10540           9 :         return result;
   10541             : }
   10542             : 
   10543           5 : static void chain1_open_completion(struct tevent_req *req)
   10544             : {
   10545           0 :         uint16_t fnum;
   10546           0 :         NTSTATUS status;
   10547           5 :         status = cli_openx_recv(req, &fnum);
   10548           5 :         TALLOC_FREE(req);
   10549             : 
   10550           5 :         d_printf("cli_openx_recv returned %s: %d\n",
   10551             :                  nt_errstr(status),
   10552           5 :                  NT_STATUS_IS_OK(status) ? fnum : -1);
   10553           5 : }
   10554             : 
   10555           5 : static void chain1_write_completion(struct tevent_req *req)
   10556             : {
   10557           0 :         size_t written;
   10558           0 :         NTSTATUS status;
   10559           5 :         status = cli_write_andx_recv(req, &written);
   10560           5 :         TALLOC_FREE(req);
   10561             : 
   10562           5 :         d_printf("cli_write_andx_recv returned %s: %d\n",
   10563             :                  nt_errstr(status),
   10564           5 :                  NT_STATUS_IS_OK(status) ? (int)written : -1);
   10565           5 : }
   10566             : 
   10567           5 : static void chain1_close_completion(struct tevent_req *req)
   10568             : {
   10569           0 :         NTSTATUS status;
   10570           5 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10571             : 
   10572           5 :         status = cli_close_recv(req);
   10573           5 :         *done = true;
   10574             : 
   10575           5 :         TALLOC_FREE(req);
   10576             : 
   10577           5 :         d_printf("cli_close returned %s\n", nt_errstr(status));
   10578           5 : }
   10579             : 
   10580           5 : static bool run_chain1(int dummy)
   10581             : {
   10582           0 :         struct cli_state *cli1;
   10583           5 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10584           0 :         struct tevent_req *reqs[3], *smbreqs[3];
   10585           5 :         bool done = false;
   10586           5 :         const char *str = "foobar";
   10587           5 :         const char *fname = "\\test_chain";
   10588           0 :         NTSTATUS status;
   10589             : 
   10590           5 :         printf("starting chain1 test\n");
   10591           5 :         if (!torture_open_connection(&cli1, 0)) {
   10592           0 :                 return False;
   10593             :         }
   10594             : 
   10595           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10596             : 
   10597           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   10598             : 
   10599           5 :         reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, fname,
   10600             :                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
   10601           5 :         if (reqs[0] == NULL) return false;
   10602           5 :         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
   10603             : 
   10604             : 
   10605           5 :         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
   10606           5 :                                         (const uint8_t *)str, 0, strlen(str)+1,
   10607             :                                         smbreqs, 1, &smbreqs[1]);
   10608           5 :         if (reqs[1] == NULL) return false;
   10609           5 :         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
   10610             : 
   10611           5 :         reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
   10612           5 :         if (reqs[2] == NULL) return false;
   10613           5 :         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
   10614             : 
   10615           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10616           5 :         if (!NT_STATUS_IS_OK(status)) {
   10617           0 :                 return false;
   10618             :         }
   10619             : 
   10620          35 :         while (!done) {
   10621          30 :                 tevent_loop_once(evt);
   10622             :         }
   10623             : 
   10624           5 :         torture_close_connection(cli1);
   10625           5 :         return True;
   10626             : }
   10627             : 
   10628           5 : static void chain2_sesssetup_completion(struct tevent_req *req)
   10629             : {
   10630           0 :         NTSTATUS status;
   10631           5 :         status = cli_session_setup_guest_recv(req);
   10632           5 :         d_printf("sesssetup returned %s\n", nt_errstr(status));
   10633           5 : }
   10634             : 
   10635           5 : static void chain2_tcon_completion(struct tevent_req *req)
   10636             : {
   10637           5 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10638           0 :         NTSTATUS status;
   10639           5 :         status = cli_tcon_andx_recv(req);
   10640           5 :         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
   10641           5 :         *done = true;
   10642           5 : }
   10643             : 
   10644           5 : static bool run_chain2(int dummy)
   10645             : {
   10646           0 :         struct cli_state *cli1;
   10647           5 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10648           0 :         struct tevent_req *reqs[2], *smbreqs[2];
   10649           5 :         bool done = false;
   10650           0 :         NTSTATUS status;
   10651           5 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
   10652             : 
   10653           5 :         printf("starting chain2 test\n");
   10654           5 :         status = cli_start_connection(talloc_tos(),
   10655             :                                       &cli1,
   10656             :                                       lp_netbios_name(),
   10657             :                                       host,
   10658             :                                       NULL,
   10659             :                                       port_to_use,
   10660             :                                       SMB_SIGNING_DEFAULT,
   10661             :                                       flags);
   10662           5 :         if (!NT_STATUS_IS_OK(status)) {
   10663           0 :                 return False;
   10664             :         }
   10665             : 
   10666           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10667             : 
   10668           5 :         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
   10669             :                                                  &smbreqs[0]);
   10670           5 :         if (reqs[0] == NULL) return false;
   10671           5 :         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
   10672             : 
   10673           5 :         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
   10674             :                                        "?????", NULL, 0, &smbreqs[1]);
   10675           5 :         if (reqs[1] == NULL) return false;
   10676           5 :         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
   10677             : 
   10678           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10679           5 :         if (!NT_STATUS_IS_OK(status)) {
   10680           0 :                 return false;
   10681             :         }
   10682             : 
   10683          30 :         while (!done) {
   10684          25 :                 tevent_loop_once(evt);
   10685             :         }
   10686             : 
   10687           5 :         torture_close_connection(cli1);
   10688           5 :         return True;
   10689             : }
   10690             : 
   10691             : 
   10692             : struct torture_createdel_state {
   10693             :         struct tevent_context *ev;
   10694             :         struct cli_state *cli;
   10695             : };
   10696             : 
   10697             : static void torture_createdel_created(struct tevent_req *subreq);
   10698             : static void torture_createdel_closed(struct tevent_req *subreq);
   10699             : 
   10700           0 : static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
   10701             :                                                  struct tevent_context *ev,
   10702             :                                                  struct cli_state *cli,
   10703             :                                                  const char *name)
   10704             : {
   10705           0 :         struct tevent_req *req, *subreq;
   10706           0 :         struct torture_createdel_state *state;
   10707             : 
   10708           0 :         req = tevent_req_create(mem_ctx, &state,
   10709             :                                 struct torture_createdel_state);
   10710           0 :         if (req == NULL) {
   10711           0 :                 return NULL;
   10712             :         }
   10713           0 :         state->ev = ev;
   10714           0 :         state->cli = cli;
   10715             : 
   10716           0 :         subreq = cli_ntcreate_send(
   10717             :                 state, ev, cli, name, 0,
   10718             :                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
   10719             :                 FILE_ATTRIBUTE_NORMAL,
   10720             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   10721             :                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE,
   10722             :                 SMB2_IMPERSONATION_IMPERSONATION, 0);
   10723             : 
   10724           0 :         if (tevent_req_nomem(subreq, req)) {
   10725           0 :                 return tevent_req_post(req, ev);
   10726             :         }
   10727           0 :         tevent_req_set_callback(subreq, torture_createdel_created, req);
   10728           0 :         return req;
   10729             : }
   10730             : 
   10731           0 : static void torture_createdel_created(struct tevent_req *subreq)
   10732             : {
   10733           0 :         struct tevent_req *req = tevent_req_callback_data(
   10734             :                 subreq, struct tevent_req);
   10735           0 :         struct torture_createdel_state *state = tevent_req_data(
   10736             :                 req, struct torture_createdel_state);
   10737           0 :         NTSTATUS status;
   10738           0 :         uint16_t fnum;
   10739             : 
   10740           0 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
   10741           0 :         TALLOC_FREE(subreq);
   10742           0 :         if (tevent_req_nterror(req, status)) {
   10743           0 :                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
   10744             :                            nt_errstr(status)));
   10745           0 :                 return;
   10746             :         }
   10747             : 
   10748           0 :         subreq = cli_close_send(state, state->ev, state->cli, fnum, 0);
   10749           0 :         if (tevent_req_nomem(subreq, req)) {
   10750           0 :                 return;
   10751             :         }
   10752           0 :         tevent_req_set_callback(subreq, torture_createdel_closed, req);
   10753             : }
   10754             : 
   10755           0 : static void torture_createdel_closed(struct tevent_req *subreq)
   10756             : {
   10757           0 :         struct tevent_req *req = tevent_req_callback_data(
   10758             :                 subreq, struct tevent_req);
   10759           0 :         NTSTATUS status;
   10760             : 
   10761           0 :         status = cli_close_recv(subreq);
   10762           0 :         if (tevent_req_nterror(req, status)) {
   10763           0 :                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
   10764           0 :                 return;
   10765             :         }
   10766           0 :         tevent_req_done(req);
   10767             : }
   10768             : 
   10769           0 : static NTSTATUS torture_createdel_recv(struct tevent_req *req)
   10770             : {
   10771           0 :         return tevent_req_simple_recv_ntstatus(req);
   10772             : }
   10773             : 
   10774             : struct torture_createdels_state {
   10775             :         struct tevent_context *ev;
   10776             :         struct cli_state *cli;
   10777             :         const char *base_name;
   10778             :         int sent;
   10779             :         int received;
   10780             :         int num_files;
   10781             :         struct tevent_req **reqs;
   10782             : };
   10783             : 
   10784             : static void torture_createdels_done(struct tevent_req *subreq);
   10785             : 
   10786           0 : static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
   10787             :                                                   struct tevent_context *ev,
   10788             :                                                   struct cli_state *cli,
   10789             :                                                   const char *base_name,
   10790             :                                                   int num_parallel,
   10791             :                                                   int num_files)
   10792             : {
   10793           0 :         struct tevent_req *req;
   10794           0 :         struct torture_createdels_state *state;
   10795           0 :         int i;
   10796             : 
   10797           0 :         req = tevent_req_create(mem_ctx, &state,
   10798             :                                 struct torture_createdels_state);
   10799           0 :         if (req == NULL) {
   10800           0 :                 return NULL;
   10801             :         }
   10802           0 :         state->ev = ev;
   10803           0 :         state->cli = cli;
   10804           0 :         state->base_name = talloc_strdup(state, base_name);
   10805           0 :         if (tevent_req_nomem(state->base_name, req)) {
   10806           0 :                 return tevent_req_post(req, ev);
   10807             :         }
   10808           0 :         state->num_files = MAX(num_parallel, num_files);
   10809           0 :         state->sent = 0;
   10810           0 :         state->received = 0;
   10811             : 
   10812           0 :         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
   10813           0 :         if (tevent_req_nomem(state->reqs, req)) {
   10814           0 :                 return tevent_req_post(req, ev);
   10815             :         }
   10816             : 
   10817           0 :         for (i=0; i<num_parallel; i++) {
   10818           0 :                 char *name;
   10819             : 
   10820           0 :                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10821           0 :                                        state->sent);
   10822           0 :                 if (tevent_req_nomem(name, req)) {
   10823           0 :                         return tevent_req_post(req, ev);
   10824             :                 }
   10825           0 :                 state->reqs[i] = torture_createdel_send(
   10826           0 :                         state->reqs, state->ev, state->cli, name);
   10827           0 :                 if (tevent_req_nomem(state->reqs[i], req)) {
   10828           0 :                         return tevent_req_post(req, ev);
   10829             :                 }
   10830           0 :                 name = talloc_move(state->reqs[i], &name);
   10831           0 :                 tevent_req_set_callback(state->reqs[i],
   10832             :                                         torture_createdels_done, req);
   10833           0 :                 state->sent += 1;
   10834             :         }
   10835           0 :         return req;
   10836             : }
   10837             : 
   10838           0 : static void torture_createdels_done(struct tevent_req *subreq)
   10839             : {
   10840           0 :         struct tevent_req *req = tevent_req_callback_data(
   10841             :                 subreq, struct tevent_req);
   10842           0 :         struct torture_createdels_state *state = tevent_req_data(
   10843             :                 req, struct torture_createdels_state);
   10844           0 :         size_t i, num_parallel = talloc_array_length(state->reqs);
   10845           0 :         NTSTATUS status;
   10846           0 :         char *name;
   10847             : 
   10848           0 :         status = torture_createdel_recv(subreq);
   10849           0 :         if (!NT_STATUS_IS_OK(status)){
   10850           0 :                 DEBUG(10, ("torture_createdel_recv returned %s\n",
   10851             :                            nt_errstr(status)));
   10852           0 :                 TALLOC_FREE(subreq);
   10853           0 :                 tevent_req_nterror(req, status);
   10854           0 :                 return;
   10855             :         }
   10856             : 
   10857           0 :         for (i=0; i<num_parallel; i++) {
   10858           0 :                 if (subreq == state->reqs[i]) {
   10859           0 :                         break;
   10860             :                 }
   10861             :         }
   10862           0 :         if (i == num_parallel) {
   10863           0 :                 DEBUG(10, ("received something we did not send\n"));
   10864           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
   10865           0 :                 return;
   10866             :         }
   10867           0 :         TALLOC_FREE(state->reqs[i]);
   10868             : 
   10869           0 :         if (state->sent >= state->num_files) {
   10870           0 :                 tevent_req_done(req);
   10871           0 :                 return;
   10872             :         }
   10873             : 
   10874           0 :         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10875             :                                state->sent);
   10876           0 :         if (tevent_req_nomem(name, req)) {
   10877           0 :                 return;
   10878             :         }
   10879           0 :         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
   10880             :                                                 state->cli, name);
   10881           0 :         if (tevent_req_nomem(state->reqs[i], req)) {
   10882           0 :                 return;
   10883             :         }
   10884           0 :         name = talloc_move(state->reqs[i], &name);
   10885           0 :         tevent_req_set_callback(state->reqs[i],      torture_createdels_done, req);
   10886           0 :         state->sent += 1;
   10887             : }
   10888             : 
   10889           0 : static NTSTATUS torture_createdels_recv(struct tevent_req *req)
   10890             : {
   10891           0 :         return tevent_req_simple_recv_ntstatus(req);
   10892             : }
   10893             : 
   10894             : struct swallow_notify_state {
   10895             :         struct tevent_context *ev;
   10896             :         struct cli_state *cli;
   10897             :         uint16_t fnum;
   10898             :         uint32_t completion_filter;
   10899             :         bool recursive;
   10900             :         bool (*fn)(uint32_t action, const char *name, void *priv);
   10901             :         void *priv;
   10902             : };
   10903             : 
   10904             : static void swallow_notify_done(struct tevent_req *subreq);
   10905             : 
   10906           0 : static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
   10907             :                                               struct tevent_context *ev,
   10908             :                                               struct cli_state *cli,
   10909             :                                               uint16_t fnum,
   10910             :                                               uint32_t completion_filter,
   10911             :                                               bool recursive,
   10912             :                                               bool (*fn)(uint32_t action,
   10913             :                                                          const char *name,
   10914             :                                                          void *priv),
   10915             :                                               void *priv)
   10916             : {
   10917           0 :         struct tevent_req *req, *subreq;
   10918           0 :         struct swallow_notify_state *state;
   10919             : 
   10920           0 :         req = tevent_req_create(mem_ctx, &state,
   10921             :                                 struct swallow_notify_state);
   10922           0 :         if (req == NULL) {
   10923           0 :                 return NULL;
   10924             :         }
   10925           0 :         state->ev = ev;
   10926           0 :         state->cli = cli;
   10927           0 :         state->fnum = fnum;
   10928           0 :         state->completion_filter = completion_filter;
   10929           0 :         state->recursive = recursive;
   10930           0 :         state->fn = fn;
   10931           0 :         state->priv = priv;
   10932             : 
   10933           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10934           0 :                                  0xffff, state->completion_filter,
   10935           0 :                                  state->recursive);
   10936           0 :         if (tevent_req_nomem(subreq, req)) {
   10937           0 :                 return tevent_req_post(req, ev);
   10938             :         }
   10939           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10940           0 :         return req;
   10941             : }
   10942             : 
   10943           0 : static void swallow_notify_done(struct tevent_req *subreq)
   10944             : {
   10945           0 :         struct tevent_req *req = tevent_req_callback_data(
   10946             :                 subreq, struct tevent_req);
   10947           0 :         struct swallow_notify_state *state = tevent_req_data(
   10948             :                 req, struct swallow_notify_state);
   10949           0 :         NTSTATUS status;
   10950           0 :         uint32_t i, num_changes;
   10951           0 :         struct notify_change *changes;
   10952             : 
   10953           0 :         status = cli_notify_recv(subreq, state, &num_changes, &changes);
   10954           0 :         TALLOC_FREE(subreq);
   10955           0 :         if (!NT_STATUS_IS_OK(status)) {
   10956           0 :                 DEBUG(10, ("cli_notify_recv returned %s\n",
   10957             :                            nt_errstr(status)));
   10958           0 :                 tevent_req_nterror(req, status);
   10959           0 :                 return;
   10960             :         }
   10961             : 
   10962           0 :         for (i=0; i<num_changes; i++) {
   10963           0 :                 state->fn(changes[i].action, changes[i].name, state->priv);
   10964             :         }
   10965           0 :         TALLOC_FREE(changes);
   10966             : 
   10967           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10968             :                                  0xffff, state->completion_filter,
   10969           0 :                                  state->recursive);
   10970           0 :         if (tevent_req_nomem(subreq, req)) {
   10971           0 :                 return;
   10972             :         }
   10973           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10974             : }
   10975             : 
   10976           0 : static bool print_notifies(uint32_t action, const char *name, void *priv)
   10977             : {
   10978           0 :         if (DEBUGLEVEL > 5) {
   10979           0 :                 d_printf("%d %s\n", (int)action, name);
   10980             :         }
   10981           0 :         return true;
   10982             : }
   10983             : 
   10984           0 : static void notify_bench_done(struct tevent_req *req)
   10985             : {
   10986           0 :         int *num_finished = (int *)tevent_req_callback_data_void(req);
   10987           0 :         *num_finished += 1;
   10988           0 : }
   10989             : 
   10990           0 : static bool run_notify_bench(int dummy)
   10991             : {
   10992           0 :         const char *dname = "\\notify-bench";
   10993           0 :         struct tevent_context *ev;
   10994           0 :         NTSTATUS status;
   10995           0 :         uint16_t dnum;
   10996           0 :         struct tevent_req *req1;
   10997           0 :         struct tevent_req *req2 = NULL;
   10998           0 :         int i, num_unc_names;
   10999           0 :         int num_finished = 0;
   11000             : 
   11001           0 :         printf("starting notify-bench test\n");
   11002             : 
   11003           0 :         if (use_multishare_conn) {
   11004           0 :                 char **unc_list;
   11005           0 :                 unc_list = file_lines_load(multishare_conn_fname,
   11006             :                                            &num_unc_names, 0, NULL);
   11007           0 :                 if (!unc_list || num_unc_names <= 0) {
   11008           0 :                         d_printf("Failed to load unc names list from '%s'\n",
   11009             :                                  multishare_conn_fname);
   11010           0 :                         return false;
   11011             :                 }
   11012           0 :                 TALLOC_FREE(unc_list);
   11013             :         } else {
   11014           0 :                 num_unc_names = 1;
   11015             :         }
   11016             : 
   11017           0 :         ev = samba_tevent_context_init(talloc_tos());
   11018           0 :         if (ev == NULL) {
   11019           0 :                 d_printf("tevent_context_init failed\n");
   11020           0 :                 return false;
   11021             :         }
   11022             : 
   11023           0 :         for (i=0; i<num_unc_names; i++) {
   11024           0 :                 struct cli_state *cli;
   11025           0 :                 char *base_fname;
   11026             : 
   11027           0 :                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
   11028             :                                              dname, i);
   11029           0 :                 if (base_fname == NULL) {
   11030           0 :                         return false;
   11031             :                 }
   11032             : 
   11033           0 :                 if (!torture_open_connection(&cli, i)) {
   11034           0 :                         return false;
   11035             :                 }
   11036             : 
   11037           0 :                 status = cli_ntcreate(cli, dname, 0,
   11038             :                                       MAXIMUM_ALLOWED_ACCESS,
   11039             :                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
   11040             :                                       FILE_SHARE_DELETE,
   11041             :                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
   11042             :                                       &dnum, NULL);
   11043             : 
   11044           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11045           0 :                         d_printf("Could not create %s: %s\n", dname,
   11046             :                                  nt_errstr(status));
   11047           0 :                         return false;
   11048             :                 }
   11049             : 
   11050           0 :                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
   11051             :                                            FILE_NOTIFY_CHANGE_FILE_NAME |
   11052             :                                            FILE_NOTIFY_CHANGE_DIR_NAME |
   11053             :                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
   11054             :                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
   11055             :                                            false, print_notifies, NULL);
   11056           0 :                 if (req1 == NULL) {
   11057           0 :                         d_printf("Could not create notify request\n");
   11058           0 :                         return false;
   11059             :                 }
   11060             : 
   11061           0 :                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
   11062             :                                                base_fname, 10, torture_numops);
   11063           0 :                 if (req2 == NULL) {
   11064           0 :                         d_printf("Could not create createdels request\n");
   11065           0 :                         return false;
   11066             :                 }
   11067           0 :                 TALLOC_FREE(base_fname);
   11068             : 
   11069           0 :                 tevent_req_set_callback(req2, notify_bench_done,
   11070             :                                         &num_finished);
   11071             :         }
   11072             : 
   11073           0 :         while (num_finished < num_unc_names) {
   11074           0 :                 int ret;
   11075           0 :                 ret = tevent_loop_once(ev);
   11076           0 :                 if (ret != 0) {
   11077           0 :                         d_printf("tevent_loop_once failed\n");
   11078           0 :                         return false;
   11079             :                 }
   11080             :         }
   11081             : 
   11082           0 :         if (!tevent_req_poll(req2, ev)) {
   11083           0 :                 d_printf("tevent_req_poll failed\n");
   11084             :         }
   11085             : 
   11086           0 :         status = torture_createdels_recv(req2);
   11087           0 :         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
   11088             : 
   11089           0 :         return true;
   11090             : }
   11091             : 
   11092           0 : static bool run_mangle1(int dummy)
   11093             : {
   11094           0 :         struct cli_state *cli;
   11095           0 :         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
   11096           0 :         uint16_t fnum;
   11097           0 :         fstring alt_name;
   11098           0 :         NTSTATUS status;
   11099             : 
   11100           0 :         printf("starting mangle1 test\n");
   11101           0 :         if (!torture_open_connection(&cli, 0)) {
   11102           0 :                 return False;
   11103             :         }
   11104             : 
   11105           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11106             : 
   11107           0 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   11108             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11109             :                               0, 0, &fnum, NULL);
   11110           0 :         if (!NT_STATUS_IS_OK(status)) {
   11111           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11112           0 :                 return false;
   11113             :         }
   11114           0 :         cli_close(cli, fnum);
   11115             : 
   11116           0 :         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
   11117           0 :         if (!NT_STATUS_IS_OK(status)) {
   11118           0 :                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
   11119             :                          nt_errstr(status));
   11120           0 :                 return false;
   11121             :         }
   11122           0 :         d_printf("alt_name: %s\n", alt_name);
   11123             : 
   11124           0 :         status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
   11125           0 :         if (!NT_STATUS_IS_OK(status)) {
   11126           0 :                 d_printf("cli_openx(%s) failed: %s\n", alt_name,
   11127             :                          nt_errstr(status));
   11128           0 :                 return false;
   11129             :         }
   11130           0 :         cli_close(cli, fnum);
   11131             : 
   11132           0 :         status = cli_qpathinfo1(cli, alt_name, NULL, NULL, NULL, NULL, NULL);
   11133           0 :         if (!NT_STATUS_IS_OK(status)) {
   11134           0 :                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
   11135             :                          nt_errstr(status));
   11136           0 :                 return false;
   11137             :         }
   11138             : 
   11139           0 :         return true;
   11140             : }
   11141             : 
   11142           2 : static NTSTATUS mangle_illegal_list_shortname_fn(struct file_info *f,
   11143             :                                                  const char *mask,
   11144             :                                                  void *state)
   11145             : {
   11146           2 :         if (f->short_name == NULL) {
   11147           2 :                 return NT_STATUS_OK;
   11148             :         }
   11149             : 
   11150           0 :         if (strlen(f->short_name) == 0) {
   11151           0 :                 return NT_STATUS_OK;
   11152             :         }
   11153             : 
   11154           0 :         printf("unexpected shortname: %s\n", f->short_name);
   11155             : 
   11156           0 :         return NT_STATUS_OBJECT_NAME_INVALID;
   11157             : }
   11158             : 
   11159           2 : static NTSTATUS mangle_illegal_list_name_fn(struct file_info *f,
   11160             :                                             const char *mask,
   11161             :                                             void *state)
   11162             : {
   11163           2 :         char *name = state;
   11164             : 
   11165           2 :         printf("name: %s\n", f->name);
   11166           2 :         fstrcpy(name, f->name);
   11167           2 :         return NT_STATUS_OK;
   11168             : }
   11169             : 
   11170           2 : static bool run_mangle_illegal(int dummy)
   11171             : {
   11172           2 :         struct cli_state *cli = NULL;
   11173           2 :         struct cli_state *cli_posix = NULL;
   11174           2 :         const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
   11175           2 :         const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
   11176           2 :         char *mangled_path = NULL;
   11177           0 :         uint16_t fnum;
   11178           0 :         fstring name;
   11179           0 :         fstring alt_name;
   11180           0 :         NTSTATUS status;
   11181             : 
   11182           2 :         printf("starting mangle-illegal test\n");
   11183             : 
   11184           2 :         if (!torture_open_connection(&cli, 0)) {
   11185           0 :                 return False;
   11186             :         }
   11187             : 
   11188           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11189             : 
   11190           2 :         if (!torture_open_connection(&cli_posix, 0)) {
   11191           0 :                 return false;
   11192             :         }
   11193             : 
   11194           2 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   11195             : 
   11196           2 :         status = torture_setup_unix_extensions(cli_posix);
   11197           2 :         if (!NT_STATUS_IS_OK(status)) {
   11198           0 :                 return false;
   11199             :         }
   11200             : 
   11201           2 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   11202           2 :         status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
   11203           2 :         if (!NT_STATUS_IS_OK(status)) {
   11204           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
   11205           0 :                 return False;
   11206             :         }
   11207             : 
   11208             :         /*
   11209             :          * Create a file with illegal NTFS characters and test that we
   11210             :          * get a usable mangled name
   11211             :          */
   11212             : 
   11213           2 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   11214           2 :         cli_posix_unlink(cli_posix, illegal_fname);
   11215             : 
   11216           2 :         status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
   11217             :                                 0600, &fnum);
   11218           2 :         if (!NT_STATUS_IS_OK(status)) {
   11219           0 :                 printf("POSIX create of %s failed (%s)\n",
   11220             :                        illegal_fname, nt_errstr(status));
   11221           0 :                 return false;
   11222             :         }
   11223             : 
   11224           2 :         status = cli_close(cli_posix, fnum);
   11225           2 :         if (!NT_STATUS_IS_OK(status)) {
   11226           0 :                 printf("close failed (%s)\n", nt_errstr(status));
   11227           0 :                 return false;
   11228             :         }
   11229             : 
   11230           2 :         status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
   11231           2 :         if (!NT_STATUS_IS_OK(status)) {
   11232           0 :                 d_printf("cli_list failed: %s\n", nt_errstr(status));
   11233           0 :                 return false;
   11234             :         }
   11235             : 
   11236           2 :         mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
   11237           2 :         if (mangled_path == NULL) {
   11238           0 :                 return false;
   11239             :         }
   11240             : 
   11241           2 :         status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
   11242           2 :         if (!NT_STATUS_IS_OK(status)) {
   11243           0 :                 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
   11244           0 :                 TALLOC_FREE(mangled_path);
   11245           0 :                 return false;
   11246             :         }
   11247           2 :         TALLOC_FREE(mangled_path);
   11248           2 :         cli_close(cli, fnum);
   11249             : 
   11250           2 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   11251           2 :         cli_posix_unlink(cli_posix, illegal_fname);
   11252             : 
   11253             :         /*
   11254             :          * Create a file with a long name and check that we got *no* short name.
   11255             :          */
   11256             : 
   11257           2 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   11258             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11259             :                               0, 0, &fnum, NULL);
   11260           2 :         if (!NT_STATUS_IS_OK(status)) {
   11261           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11262           0 :                 return false;
   11263             :         }
   11264           2 :         cli_close(cli, fnum);
   11265             : 
   11266           2 :         status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
   11267           2 :         if (!NT_STATUS_IS_OK(status)) {
   11268           0 :                 d_printf("cli_list failed\n");
   11269           0 :                 return false;
   11270             :         }
   11271             : 
   11272           2 :         cli_unlink(cli, fname, 0);
   11273           2 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   11274             : 
   11275           2 :         if (!torture_close_connection(cli_posix)) {
   11276           0 :                 return false;
   11277             :         }
   11278             : 
   11279           2 :         if (!torture_close_connection(cli)) {
   11280           0 :                 return false;
   11281             :         }
   11282             : 
   11283           2 :         return true;
   11284             : }
   11285             : 
   11286           0 : static size_t null_source(uint8_t *buf, size_t n, void *priv)
   11287             : {
   11288           0 :         size_t *to_pull = (size_t *)priv;
   11289           0 :         size_t thistime = *to_pull;
   11290             : 
   11291           0 :         thistime = MIN(thistime, n);
   11292           0 :         if (thistime == 0) {
   11293           0 :                 return 0;
   11294             :         }
   11295             : 
   11296           0 :         memset(buf, 0, thistime);
   11297           0 :         *to_pull -= thistime;
   11298           0 :         return thistime;
   11299             : }
   11300             : 
   11301           0 : static bool run_windows_write(int dummy)
   11302             : {
   11303           0 :         struct cli_state *cli1;
   11304           0 :         uint16_t fnum;
   11305           0 :         int i;
   11306           0 :         bool ret = false;
   11307           0 :         const char *fname = "\\writetest.txt";
   11308           0 :         struct timeval start_time;
   11309           0 :         double seconds;
   11310           0 :         double kbytes;
   11311           0 :         NTSTATUS status;
   11312             : 
   11313           0 :         printf("starting windows_write test\n");
   11314           0 :         if (!torture_open_connection(&cli1, 0)) {
   11315           0 :                 return False;
   11316             :         }
   11317             : 
   11318           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
   11319           0 :         if (!NT_STATUS_IS_OK(status)) {
   11320           0 :                 printf("open failed (%s)\n", nt_errstr(status));
   11321           0 :                 return False;
   11322             :         }
   11323             : 
   11324           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   11325             : 
   11326           0 :         start_time = timeval_current();
   11327             : 
   11328           0 :         for (i=0; i<torture_numops; i++) {
   11329           0 :                 uint8_t c = 0;
   11330           0 :                 off_t start = i * torture_blocksize;
   11331           0 :                 size_t to_pull = torture_blocksize - 1;
   11332             : 
   11333           0 :                 status = cli_writeall(cli1, fnum, 0, &c,
   11334           0 :                                       start + torture_blocksize - 1, 1, NULL);
   11335           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11336           0 :                         printf("cli_write failed: %s\n", nt_errstr(status));
   11337           0 :                         goto fail;
   11338             :                 }
   11339             : 
   11340           0 :                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
   11341             :                                   null_source, &to_pull);
   11342           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11343           0 :                         printf("cli_push returned: %s\n", nt_errstr(status));
   11344           0 :                         goto fail;
   11345             :                 }
   11346             :         }
   11347             : 
   11348           0 :         seconds = timeval_elapsed(&start_time);
   11349           0 :         kbytes = (double)torture_blocksize * torture_numops;
   11350           0 :         kbytes /= 1024;
   11351             : 
   11352           0 :         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
   11353           0 :                (double)seconds, (int)(kbytes/seconds));
   11354             : 
   11355           0 :         ret = true;
   11356           0 :  fail:
   11357           0 :         cli_close(cli1, fnum);
   11358           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11359           0 :         torture_close_connection(cli1);
   11360           0 :         return ret;
   11361             : }
   11362             : 
   11363          64 : static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
   11364             : {
   11365          64 :         size_t max_pdu = 0x1FFFF;
   11366             : 
   11367          64 :         if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
   11368          32 :                 max_pdu = 0xFFFFFF;
   11369             :         }
   11370             : 
   11371          64 :         if (smb1cli_conn_signing_is_active(cli->conn)) {
   11372          32 :                 max_pdu = 0x1FFFF;
   11373             :         }
   11374             : 
   11375          64 :         if (smb1cli_conn_encryption_on(cli->conn)) {
   11376          16 :                 max_pdu = CLI_BUFFER_SIZE;
   11377             :         }
   11378             : 
   11379          64 :         if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
   11380           8 :                 len_requested &= 0xFFFF;
   11381             :         }
   11382             : 
   11383          64 :         return MIN(len_requested,
   11384             :                    max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
   11385             : }
   11386             : 
   11387          64 : static bool check_read_call(struct cli_state *cli,
   11388             :                             uint16_t fnum,
   11389             :                             uint8_t *buf,
   11390             :                             size_t len_requested)
   11391             : {
   11392           0 :         NTSTATUS status;
   11393          64 :         struct tevent_req *subreq = NULL;
   11394          64 :         ssize_t len_read = 0;
   11395          64 :         size_t len_expected = 0;
   11396          64 :         struct tevent_context *ev = NULL;
   11397             : 
   11398          64 :         ev = samba_tevent_context_init(talloc_tos());
   11399          64 :         if (ev == NULL) {
   11400           0 :                 return false;
   11401             :         }
   11402             : 
   11403          64 :         subreq = cli_read_andx_send(talloc_tos(),
   11404             :                                     ev,
   11405             :                                     cli,
   11406             :                                     fnum,
   11407             :                                     0,
   11408             :                                     len_requested);
   11409             : 
   11410          64 :         if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
   11411           0 :                 return false;
   11412             :         }
   11413             : 
   11414          64 :         status = cli_read_andx_recv(subreq, &len_read, &buf);
   11415          64 :         if (!NT_STATUS_IS_OK(status)) {
   11416           0 :                 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
   11417           0 :                 return false;
   11418             :         }
   11419             : 
   11420          64 :         TALLOC_FREE(subreq);
   11421          64 :         TALLOC_FREE(ev);
   11422             : 
   11423          64 :         len_expected = calc_expected_return(cli, len_requested);
   11424             : 
   11425          64 :         if (len_expected > 0x10000 && len_read == 0x10000) {
   11426             :                 /* Windows servers only return a max of 0x10000,
   11427             :                    doesn't matter if you set CAP_LARGE_READX in
   11428             :                    the client sessionsetupX call or not. */
   11429          12 :                 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
   11430             :                         (unsigned int)len_requested);
   11431          52 :         } else if (len_read != len_expected) {
   11432           0 :                 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
   11433             :                         (unsigned int)len_requested,
   11434             :                         (unsigned int)len_read,
   11435             :                         (unsigned int)len_expected);
   11436           0 :                 return false;
   11437             :         } else {
   11438          52 :                 d_printf("Correct read reply.\n");
   11439             :         }
   11440             : 
   11441          64 :         return true;
   11442             : }
   11443             : 
   11444             : /* Test large readX variants. */
   11445           8 : static bool large_readx_tests(struct cli_state *cli,
   11446             :                                 uint16_t fnum,
   11447             :                                 uint8_t *buf)
   11448             : {
   11449             :         /* A read of 0xFFFF0001 should *always* return 1 byte. */
   11450           8 :         if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
   11451           0 :                 return false;
   11452             :         }
   11453             :         /* A read of 0x10000 should return 0x10000 bytes. */
   11454           8 :         if (check_read_call(cli, fnum, buf,    0x10000) == false) {
   11455           0 :                 return false;
   11456             :         }
   11457             :         /* A read of 0x10000 should return 0x10001 bytes. */
   11458           8 :         if (check_read_call(cli, fnum, buf,    0x10001) == false) {
   11459           0 :                 return false;
   11460             :         }
   11461             :         /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
   11462             :            the requested number of bytes. */
   11463           8 :         if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
   11464           0 :                 return false;
   11465             :         }
   11466             :         /* A read of 1MB should return 1MB bytes (on Samba). */
   11467           8 :         if (check_read_call(cli, fnum, buf,   0x100000) == false) {
   11468           0 :                 return false;
   11469             :         }
   11470             : 
   11471           8 :         if (check_read_call(cli, fnum, buf,    0x20001) == false) {
   11472           0 :                 return false;
   11473             :         }
   11474           8 :         if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
   11475           0 :                 return false;
   11476             :         }
   11477           8 :         if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
   11478           0 :                 return false;
   11479             :         }
   11480           8 :         return true;
   11481             : }
   11482             : 
   11483           5 : static bool run_large_readx(int dummy)
   11484             : {
   11485           5 :         uint8_t *buf = NULL;
   11486           5 :         struct cli_state *cli1 = NULL;
   11487           5 :         struct cli_state *cli2 = NULL;
   11488           5 :         bool correct = false;
   11489           5 :         const char *fname = "\\large_readx.dat";
   11490           0 :         NTSTATUS status;
   11491           5 :         uint16_t fnum1 = UINT16_MAX;
   11492           5 :         uint32_t normal_caps = 0;
   11493           5 :         size_t file_size = 20*1024*1024;
   11494           5 :         TALLOC_CTX *frame = talloc_stackframe();
   11495           0 :         size_t i;
   11496           0 :         struct {
   11497             :                 const char *name;
   11498             :                 enum smb_signing_setting signing_setting;
   11499             :                 enum protocol_types protocol;
   11500           5 :         } runs[] = {
   11501             :                 {
   11502             :                         .name = "NT1",
   11503             :                         .signing_setting = SMB_SIGNING_IF_REQUIRED,
   11504             :                         .protocol = PROTOCOL_NT1,
   11505             :                 },{
   11506             :                         .name = "NT1 - SIGNING_REQUIRED",
   11507             :                         .signing_setting = SMB_SIGNING_REQUIRED,
   11508             :                         .protocol = PROTOCOL_NT1,
   11509             :                 },
   11510             :         };
   11511             : 
   11512           5 :         printf("starting large_readx test\n");
   11513             : 
   11514           5 :         if (!torture_open_connection(&cli1, 0)) {
   11515           0 :                 goto out;
   11516             :         }
   11517             : 
   11518           5 :         normal_caps = smb1cli_conn_capabilities(cli1->conn);
   11519             : 
   11520           5 :         if (!(normal_caps & CAP_LARGE_READX)) {
   11521           0 :                 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11522             :                         (unsigned int)normal_caps);
   11523           0 :                 goto out;
   11524             :         }
   11525             : 
   11526             :         /* Create a file of size 4MB. */
   11527           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
   11528             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11529             :                         0, 0, &fnum1, NULL);
   11530             : 
   11531           5 :         if (!NT_STATUS_IS_OK(status)) {
   11532           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11533           0 :                 goto out;
   11534             :         }
   11535             : 
   11536             :         /* Write file_size bytes. */
   11537           5 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11538           5 :         if (buf == NULL) {
   11539           0 :                 goto out;
   11540             :         }
   11541             : 
   11542           5 :         status = cli_writeall(cli1,
   11543             :                               fnum1,
   11544             :                               0,
   11545             :                               buf,
   11546             :                               0,
   11547             :                               file_size,
   11548             :                               NULL);
   11549           5 :         if (!NT_STATUS_IS_OK(status)) {
   11550           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11551           0 :                 goto out;
   11552             :         }
   11553             : 
   11554           5 :         status = cli_close(cli1, fnum1);
   11555           5 :         if (!NT_STATUS_IS_OK(status)) {
   11556           0 :                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11557           0 :                 goto out;
   11558             :         }
   11559             : 
   11560           5 :         fnum1 = UINT16_MAX;
   11561             : 
   11562          15 :         for (i=0; i < ARRAY_SIZE(runs); i++) {
   11563          10 :                 enum smb_signing_setting saved_signing_setting = signing_state;
   11564          10 :                 uint16_t fnum2 = -1;
   11565             : 
   11566          10 :                 if (do_encrypt &&
   11567           4 :                     (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
   11568             :                 {
   11569           2 :                         d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
   11570           2 :                         continue;
   11571             :                 }
   11572             : 
   11573           8 :                 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
   11574             : 
   11575           8 :                 signing_state = runs[i].signing_setting;
   11576           8 :                 cli2 = open_nbt_connection();
   11577           8 :                 signing_state = saved_signing_setting;
   11578           8 :                 if (cli2 == NULL) {
   11579           0 :                         goto out;
   11580             :                 }
   11581             : 
   11582           8 :                 status = smbXcli_negprot(cli2->conn,
   11583           8 :                                          cli2->timeout,
   11584             :                                          runs[i].protocol,
   11585             :                                          runs[i].protocol,
   11586             :                                          NULL,
   11587             :                                          NULL,
   11588             :                                          NULL);
   11589           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11590           0 :                         goto out;
   11591             :                 }
   11592             : 
   11593           8 :                 status = cli_session_setup_creds(cli2, torture_creds);
   11594           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11595           0 :                         goto out;
   11596             :                 }
   11597             : 
   11598           8 :                 status = cli_tree_connect(cli2,
   11599             :                                         share,
   11600             :                                         "?????",
   11601             :                                         password);
   11602           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11603           0 :                         goto out;
   11604             :                 }
   11605             : 
   11606           8 :                 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
   11607             : 
   11608           8 :                 normal_caps = smb1cli_conn_capabilities(cli2->conn);
   11609             : 
   11610           8 :                 if (!(normal_caps & CAP_LARGE_READX)) {
   11611           0 :                         d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11612             :                                 (unsigned int)normal_caps);
   11613           0 :                         goto out;
   11614             :                 }
   11615             : 
   11616           8 :                 if (do_encrypt) {
   11617           2 :                         if (force_cli_encryption(cli2, share) == false) {
   11618           0 :                                 goto out;
   11619             :                         }
   11620           6 :                 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
   11621           0 :                         uint16_t major, minor;
   11622           0 :                         uint32_t caplow, caphigh;
   11623             : 
   11624           4 :                         status = cli_unix_extensions_version(cli2,
   11625             :                                                              &major, &minor,
   11626             :                                                              &caplow, &caphigh);
   11627           4 :                         if (!NT_STATUS_IS_OK(status)) {
   11628           0 :                                 goto out;
   11629             :                         }
   11630             :                 }
   11631             : 
   11632           8 :                 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
   11633             :                                 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
   11634             :                                 0, 0, &fnum2, NULL);
   11635           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11636           0 :                         d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
   11637           0 :                         goto out;
   11638             :                 }
   11639             : 
   11640             :                 /* All reads must return less than file_size bytes. */
   11641           8 :                 if (!large_readx_tests(cli2, fnum2, buf)) {
   11642           0 :                         goto out;
   11643             :                 }
   11644             : 
   11645           8 :                 status = cli_close(cli2, fnum2);
   11646           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11647           0 :                         d_printf("cli_close failed: %s\n", nt_errstr(status));
   11648           0 :                         goto out;
   11649             :                 }
   11650           8 :                 fnum2 = -1;
   11651             : 
   11652           8 :                 if (!torture_close_connection(cli2)) {
   11653           0 :                         goto out;
   11654             :                 }
   11655           8 :                 cli2 = NULL;
   11656             :         }
   11657             : 
   11658           5 :         correct = true;
   11659           5 :         printf("Success on large_readx test\n");
   11660             : 
   11661           5 :   out:
   11662             : 
   11663           5 :         if (cli2) {
   11664           0 :                 if (!torture_close_connection(cli2)) {
   11665           0 :                         correct = false;
   11666             :                 }
   11667             :         }
   11668             : 
   11669           5 :         if (cli1) {
   11670           5 :                 if (fnum1 != UINT16_MAX) {
   11671           0 :                         status = cli_close(cli1, fnum1);
   11672           0 :                         if (!NT_STATUS_IS_OK(status)) {
   11673           0 :                                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11674             :                         }
   11675           0 :                         fnum1 = UINT16_MAX;
   11676             :                 }
   11677             : 
   11678           5 :                 status = cli_unlink(cli1, fname,
   11679             :                                     FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11680           5 :                 if (!NT_STATUS_IS_OK(status)) {
   11681           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
   11682             :                 }
   11683             : 
   11684           5 :                 if (!torture_close_connection(cli1)) {
   11685           0 :                         correct = false;
   11686             :                 }
   11687             :         }
   11688             : 
   11689           5 :         TALLOC_FREE(frame);
   11690             : 
   11691           5 :         printf("finished large_readx test\n");
   11692           5 :         return correct;
   11693             : }
   11694             : 
   11695          24 : static NTSTATUS msdfs_attribute_list_fn(struct file_info *finfo,
   11696             :                                   const char *mask,
   11697             :                                   void *private_data)
   11698             : {
   11699          24 :         uint32_t *p_attr = (uint32_t *)private_data;
   11700             : 
   11701          24 :         if (strequal(finfo->name, test_filename)) {
   11702           4 :                 *p_attr = finfo->attr;
   11703             :         }
   11704             : 
   11705          24 :         return NT_STATUS_OK;
   11706             : }
   11707             : 
   11708           4 : static bool run_msdfs_attribute(int dummy)
   11709             : {
   11710           0 :         static struct cli_state *cli;
   11711           4 :         bool correct = false;
   11712           4 :         uint32_t attr = 0;
   11713           0 :         NTSTATUS status;
   11714             : 
   11715           4 :         printf("Starting MSDFS-ATTRIBUTE test\n");
   11716             : 
   11717           4 :         if (test_filename == NULL || test_filename[0] == '\0') {
   11718           0 :                 printf("MSDFS-ATTRIBUTE test "
   11719             :                         "needs -f filename-of-msdfs-link\n");
   11720           0 :                 return false;
   11721             :         }
   11722             : 
   11723             :         /*
   11724             :          * NB. We use torture_open_connection_flags() not
   11725             :          * torture_open_connection() as the latter forces
   11726             :          * SMB1.
   11727             :          */
   11728           4 :         if (!torture_open_connection_flags(&cli, 0, 0)) {
   11729           0 :                 return false;
   11730             :         }
   11731             : 
   11732           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11733             : 
   11734           4 :         status = cli_list(cli,
   11735             :                         "*",
   11736             :                         FILE_ATTRIBUTE_DIRECTORY,
   11737             :                         msdfs_attribute_list_fn,
   11738             :                         &attr);
   11739             : 
   11740           4 :         if (!NT_STATUS_IS_OK(status)) {
   11741           0 :                 printf("cli_list failed with %s\n",
   11742             :                         nt_errstr(status));
   11743           0 :                 goto out;
   11744             :         }
   11745           4 :         if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
   11746           0 :                 printf("file %s should have "
   11747             :                         "FILE_ATTRIBUTE_REPARSE_POINT set. attr = 0x%x\n",
   11748             :                         test_filename,
   11749             :                         (unsigned int)attr);
   11750           0 :                 goto out;
   11751             :         }
   11752             : 
   11753           4 :         if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
   11754           0 :                 printf("file %s should have "
   11755             :                         "FILE_ATTRIBUTE_DIRECTORY set. attr = 0x%x\n",
   11756             :                         test_filename,
   11757             :                         (unsigned int)attr);
   11758           0 :                 goto out;
   11759             :         }
   11760             : 
   11761           4 :         correct = true;
   11762             : 
   11763           4 :   out:
   11764             : 
   11765           4 :         torture_close_connection(cli);
   11766           4 :         return correct;
   11767             : }
   11768             : 
   11769           0 : static bool run_cli_echo(int dummy)
   11770             : {
   11771           0 :         struct cli_state *cli;
   11772           0 :         NTSTATUS status;
   11773             : 
   11774           0 :         printf("starting cli_echo test\n");
   11775           0 :         if (!torture_open_connection(&cli, 0)) {
   11776           0 :                 return false;
   11777             :         }
   11778           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11779             : 
   11780           0 :         status = cli_echo(cli, 5, data_blob_const("hello", 5));
   11781             : 
   11782           0 :         d_printf("cli_echo returned %s\n", nt_errstr(status));
   11783             : 
   11784           0 :         torture_close_connection(cli);
   11785           0 :         return NT_STATUS_IS_OK(status);
   11786             : }
   11787             : 
   11788          14 : static int splice_status(off_t written, void *priv)
   11789             : {
   11790          14 :         return true;
   11791             : }
   11792             : 
   11793           7 : static bool run_cli_splice(int dummy)
   11794             : {
   11795           7 :         uint8_t *buf = NULL;
   11796           7 :         struct cli_state *cli1 = NULL;
   11797           7 :         bool correct = false;
   11798           7 :         const char *fname_src = "\\splice_src.dat";
   11799           7 :         const char *fname_dst = "\\splice_dst.dat";
   11800           0 :         NTSTATUS status;
   11801           7 :         uint16_t fnum1 = UINT16_MAX;
   11802           7 :         uint16_t fnum2 = UINT16_MAX;
   11803           7 :         size_t file_size = 2*1024*1024;
   11804           7 :         size_t splice_size = 1*1024*1024 + 713;
   11805           0 :         uint8_t digest1[16], digest2[16];
   11806           7 :         off_t written = 0;
   11807           7 :         size_t nread = 0;
   11808           7 :         TALLOC_CTX *frame = talloc_stackframe();
   11809             : 
   11810           7 :         printf("starting cli_splice test\n");
   11811             : 
   11812           7 :         if (!torture_open_connection(&cli1, 0)) {
   11813           0 :                 goto out;
   11814             :         }
   11815             : 
   11816           7 :         cli_unlink(cli1, fname_src,
   11817             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11818           7 :         cli_unlink(cli1, fname_dst,
   11819             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11820             : 
   11821             :         /* Create a file */
   11822           7 :         status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
   11823             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11824             :                         0, 0, &fnum1, NULL);
   11825             : 
   11826           7 :         if (!NT_STATUS_IS_OK(status)) {
   11827           0 :                 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
   11828           0 :                 goto out;
   11829             :         }
   11830             : 
   11831             :         /* Write file_size bytes - must be bigger than splice_size. */
   11832           7 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11833           7 :         if (buf == NULL) {
   11834           0 :                 d_printf("talloc_fail\n");
   11835           0 :                 goto out;
   11836             :         }
   11837             : 
   11838             :         /* Fill it with random numbers. */
   11839           7 :         generate_random_buffer(buf, file_size);
   11840             : 
   11841             :         /* MD5 the first 1MB + 713 bytes. */
   11842           7 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11843             :                          buf,
   11844             :                          splice_size,
   11845             :                          digest1);
   11846             : 
   11847           7 :         status = cli_writeall(cli1,
   11848             :                               fnum1,
   11849             :                               0,
   11850             :                               buf,
   11851             :                               0,
   11852             :                               file_size,
   11853             :                               NULL);
   11854           7 :         if (!NT_STATUS_IS_OK(status)) {
   11855           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11856           0 :                 goto out;
   11857             :         }
   11858             : 
   11859           7 :         status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
   11860             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11861             :                         0, 0, &fnum2, NULL);
   11862             : 
   11863           7 :         if (!NT_STATUS_IS_OK(status)) {
   11864           0 :                 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
   11865           0 :                 goto out;
   11866             :         }
   11867             : 
   11868             :         /* Now splice 1MB + 713 bytes. */
   11869           7 :         status = cli_splice(cli1,
   11870             :                                 cli1,
   11871             :                                 fnum1,
   11872             :                                 fnum2,
   11873             :                                 splice_size,
   11874             :                                 0,
   11875             :                                 0,
   11876             :                                 &written,
   11877             :                                 splice_status,
   11878             :                                 NULL);
   11879             : 
   11880           7 :         if (!NT_STATUS_IS_OK(status)) {
   11881           0 :                 d_printf("cli_splice failed: %s\n", nt_errstr(status));
   11882           0 :                 goto out;
   11883             :         }
   11884             : 
   11885             :         /* Clear the old buffer. */
   11886           7 :         memset(buf, '\0', file_size);
   11887             : 
   11888             :         /* Read the new file. */
   11889           7 :         status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
   11890           7 :         if (!NT_STATUS_IS_OK(status)) {
   11891           0 :                 d_printf("cli_read failed: %s\n", nt_errstr(status));
   11892           0 :                 goto out;
   11893             :         }
   11894           7 :         if (nread != splice_size) {
   11895           0 :                 d_printf("bad read of 0x%x, should be 0x%x\n",
   11896             :                         (unsigned int)nread,
   11897             :                         (unsigned int)splice_size);
   11898           0 :                 goto out;
   11899             :         }
   11900             : 
   11901             :         /* MD5 the first 1MB + 713 bytes. */
   11902           7 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11903             :                          buf,
   11904             :                          splice_size,
   11905             :                          digest2);
   11906             : 
   11907             :         /* Must be the same. */
   11908           7 :         if (memcmp(digest1, digest2, 16) != 0) {
   11909           0 :                 d_printf("bad MD5 compare\n");
   11910           0 :                 goto out;
   11911             :         }
   11912             : 
   11913           7 :         correct = true;
   11914           7 :         printf("Success on cli_splice test\n");
   11915             : 
   11916           7 :   out:
   11917             : 
   11918           7 :         if (cli1) {
   11919           7 :                 if (fnum1 != UINT16_MAX) {
   11920           7 :                         cli_close(cli1, fnum1);
   11921             :                 }
   11922           7 :                 if (fnum2 != UINT16_MAX) {
   11923           7 :                         cli_close(cli1, fnum2);
   11924             :                 }
   11925             : 
   11926           7 :                 cli_unlink(cli1, fname_src,
   11927             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11928           7 :                 cli_unlink(cli1, fname_dst,
   11929             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11930             : 
   11931           7 :                 if (!torture_close_connection(cli1)) {
   11932           0 :                         correct = false;
   11933             :                 }
   11934             :         }
   11935             : 
   11936           7 :         TALLOC_FREE(frame);
   11937           7 :         return correct;
   11938             : }
   11939             : 
   11940           4 : static bool run_uid_regression_test(int dummy)
   11941             : {
   11942           0 :         static struct cli_state *cli;
   11943           0 :         int16_t old_vuid;
   11944           0 :         int32_t old_cnum;
   11945           4 :         bool correct = True;
   11946           4 :         struct smbXcli_tcon *tcon_copy = NULL;
   11947           0 :         NTSTATUS status;
   11948             : 
   11949           4 :         printf("starting uid regression test\n");
   11950             : 
   11951           4 :         if (!torture_open_connection(&cli, 0)) {
   11952           0 :                 return False;
   11953             :         }
   11954             : 
   11955           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11956             : 
   11957             :         /* Ok - now save then logoff our current user. */
   11958           4 :         old_vuid = cli_state_get_uid(cli);
   11959             : 
   11960           4 :         status = cli_ulogoff(cli);
   11961           4 :         if (!NT_STATUS_IS_OK(status)) {
   11962           0 :                 d_printf("(%s) cli_ulogoff failed: %s\n",
   11963             :                          __location__, nt_errstr(status));
   11964           0 :                 correct = false;
   11965           0 :                 goto out;
   11966             :         }
   11967             : 
   11968           4 :         cli_state_set_uid(cli, old_vuid);
   11969             : 
   11970             :         /* Try an operation. */
   11971           4 :         status = cli_mkdir(cli, "\\uid_reg_test");
   11972           4 :         if (NT_STATUS_IS_OK(status)) {
   11973           0 :                 d_printf("(%s) cli_mkdir succeeded\n",
   11974             :                          __location__);
   11975           0 :                 correct = false;
   11976           0 :                 goto out;
   11977             :         } else {
   11978             :                 /* Should be bad uid. */
   11979           4 :                 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
   11980           4 :                                  NT_STATUS_USER_SESSION_DELETED)) {
   11981           0 :                         correct = false;
   11982           0 :                         goto out;
   11983             :                 }
   11984             :         }
   11985             : 
   11986           4 :         old_cnum = cli_state_get_tid(cli);
   11987             :         /*
   11988             :          * This is an SMB1-only test.
   11989             :          * Copy the tcon, not "save/restore".
   11990             :          *
   11991             :          * In SMB1 the cli_tdis() below frees
   11992             :          * cli->smb1.tcon so we need a copy
   11993             :          * of the struct to put back for the
   11994             :          * second tdis call with invalid vuid.
   11995             :          *
   11996             :          * This is a test-only hack. Real client code
   11997             :          * uses cli_state_save_tcon_share()/cli_state_restore_tcon_share().
   11998             :          */
   11999           4 :         tcon_copy = smbXcli_tcon_copy(cli, cli->smb1.tcon);
   12000           4 :         if (tcon_copy == NULL) {
   12001           0 :                 correct = false;
   12002           0 :                 goto out;
   12003             :         }
   12004             : 
   12005             :         /* Now try a SMBtdis with the invalid vuid set to zero. */
   12006           4 :         cli_state_set_uid(cli, 0);
   12007             : 
   12008             :         /* This should succeed. */
   12009           4 :         status = cli_tdis(cli);
   12010             : 
   12011           4 :         if (NT_STATUS_IS_OK(status)) {
   12012           4 :                 d_printf("First tdis with invalid vuid should succeed.\n");
   12013             :         } else {
   12014           0 :                 d_printf("First tdis failed (%s)\n", nt_errstr(status));
   12015           0 :                 correct = false;
   12016           0 :                 cli->smb1.tcon = tcon_copy;
   12017           0 :                 goto out;
   12018             :         }
   12019             : 
   12020           4 :         cli->smb1.tcon = tcon_copy;
   12021           4 :         cli_state_set_uid(cli, old_vuid);
   12022           4 :         cli_state_set_tid(cli, old_cnum);
   12023             : 
   12024             :         /* This should fail. */
   12025           4 :         status = cli_tdis(cli);
   12026           4 :         if (NT_STATUS_IS_OK(status)) {
   12027           0 :                 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
   12028           0 :                 correct = false;
   12029           0 :                 goto out;
   12030             :         } else {
   12031             :                 /* Should be bad tid. */
   12032           4 :                 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
   12033           4 :                                 NT_STATUS_NETWORK_NAME_DELETED)) {
   12034           0 :                         correct = false;
   12035           0 :                         goto out;
   12036             :                 }
   12037             :         }
   12038             : 
   12039           4 :         cli_rmdir(cli, "\\uid_reg_test");
   12040             : 
   12041           4 :   out:
   12042             : 
   12043           4 :         cli_shutdown(cli);
   12044           4 :         return correct;
   12045             : }
   12046             : 
   12047             : 
   12048             : static const char *illegal_chars = "*\\/?<>|\":";
   12049             : static char force_shortname_chars[] = " +,.[];=\177";
   12050             : 
   12051           8 : static NTSTATUS shortname_del_fn(struct file_info *finfo,
   12052             :                              const char *mask, void *state)
   12053             : {
   12054           8 :         struct cli_state *pcli = (struct cli_state *)state;
   12055           0 :         fstring fname;
   12056           8 :         NTSTATUS status = NT_STATUS_OK;
   12057             : 
   12058           8 :         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
   12059             : 
   12060           8 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
   12061           8 :                 return NT_STATUS_OK;
   12062             : 
   12063           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
   12064           0 :                 status = cli_rmdir(pcli, fname);
   12065           0 :                 if (!NT_STATUS_IS_OK(status)) {
   12066           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
   12067             :                 }
   12068             :         } else {
   12069           0 :                 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12070           0 :                 if (!NT_STATUS_IS_OK(status)) {
   12071           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
   12072             :                 }
   12073             :         }
   12074           0 :         return status;
   12075             : }
   12076             : 
   12077             : struct sn_state {
   12078             :         int matched;
   12079             :         int i;
   12080             :         bool val;
   12081             : };
   12082             : 
   12083         348 : static NTSTATUS shortname_list_fn(struct file_info *finfo,
   12084             :                               const char *name, void *state)
   12085             : {
   12086         348 :         struct sn_state *s = (struct sn_state  *)state;
   12087         348 :         int i = s->i;
   12088             : 
   12089             : #if 0
   12090             :         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
   12091             :                 i, finfo->name, finfo->short_name);
   12092             : #endif
   12093             : 
   12094         348 :         if (strchr(force_shortname_chars, i)) {
   12095          36 :                 if (!finfo->short_name) {
   12096             :                         /* Shortname not created when it should be. */
   12097           0 :                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
   12098             :                                 __location__, finfo->name, i);
   12099           0 :                         s->val = true;
   12100             :                 }
   12101         312 :         } else if (finfo->short_name){
   12102             :                 /* Shortname created when it should not be. */
   12103           0 :                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
   12104             :                         __location__, finfo->short_name, finfo->name);
   12105           0 :                 s->val = true;
   12106             :         }
   12107         348 :         s->matched += 1;
   12108         348 :         return NT_STATUS_OK;
   12109             : }
   12110             : 
   12111           4 : static bool run_shortname_test(int dummy)
   12112             : {
   12113           0 :         static struct cli_state *cli;
   12114           4 :         bool correct = True;
   12115           0 :         int i;
   12116           0 :         struct sn_state s;
   12117           0 :         char fname[40];
   12118           0 :         NTSTATUS status;
   12119             : 
   12120           4 :         printf("starting shortname test\n");
   12121             : 
   12122           4 :         if (!torture_open_connection(&cli, 0)) {
   12123           0 :                 return False;
   12124             :         }
   12125             : 
   12126           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12127             : 
   12128           4 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   12129           4 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   12130           4 :         cli_rmdir(cli, "\\shortname");
   12131             : 
   12132           4 :         status = cli_mkdir(cli, "\\shortname");
   12133           4 :         if (!NT_STATUS_IS_OK(status)) {
   12134           0 :                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
   12135             :                         __location__, nt_errstr(status));
   12136           0 :                 correct = false;
   12137           0 :                 goto out;
   12138             :         }
   12139             : 
   12140           4 :         if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
   12141           0 :                 correct = false;
   12142           0 :                 goto out;
   12143             :         }
   12144           4 :         if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
   12145           0 :                 correct = false;
   12146           0 :                 goto out;
   12147             :         }
   12148             : 
   12149           4 :         s.val = false;
   12150             : 
   12151         388 :         for (i = 32; i < 128; i++) {
   12152         384 :                 uint16_t fnum = (uint16_t)-1;
   12153             : 
   12154         384 :                 s.i = i;
   12155             : 
   12156         384 :                 if (strchr(illegal_chars, i)) {
   12157          36 :                         continue;
   12158             :                 }
   12159         348 :                 fname[15] = i;
   12160             : 
   12161         348 :                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
   12162             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
   12163             :                                    FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
   12164         348 :                 if (!NT_STATUS_IS_OK(status)) {
   12165           0 :                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
   12166             :                                 __location__, fname, nt_errstr(status));
   12167           0 :                         correct = false;
   12168           0 :                         goto out;
   12169             :                 }
   12170         348 :                 cli_close(cli, fnum);
   12171             : 
   12172         348 :                 s.matched = 0;
   12173         348 :                 status = cli_list(cli, "\\shortname\\test*.*", 0,
   12174             :                                   shortname_list_fn, &s);
   12175         348 :                 if (s.matched != 1) {
   12176           0 :                         d_printf("(%s) failed to list %s: %s\n",
   12177             :                                 __location__, fname, nt_errstr(status));
   12178           0 :                         correct = false;
   12179           0 :                         goto out;
   12180             :                 }
   12181             : 
   12182         348 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12183         348 :                 if (!NT_STATUS_IS_OK(status)) {
   12184           0 :                         d_printf("(%s) failed to delete %s: %s\n",
   12185             :                                 __location__, fname, nt_errstr(status));
   12186           0 :                         correct = false;
   12187           0 :                         goto out;
   12188             :                 }
   12189             : 
   12190         348 :                 if (s.val) {
   12191           0 :                         correct = false;
   12192           0 :                         goto out;
   12193             :                 }
   12194             :         }
   12195             : 
   12196           4 :   out:
   12197             : 
   12198           4 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   12199           4 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   12200           4 :         cli_rmdir(cli, "\\shortname");
   12201           4 :         torture_close_connection(cli);
   12202           4 :         return correct;
   12203             : }
   12204             : 
   12205             : TLDAPRC callback_code;
   12206             : 
   12207        1912 : static void pagedsearch_cb(struct tevent_req *req)
   12208             : {
   12209           0 :         TLDAPRC rc;
   12210           0 :         struct tldap_message *msg;
   12211           0 :         char *dn;
   12212             : 
   12213        1912 :         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
   12214        1912 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12215           0 :                 d_printf("tldap_search_paged_recv failed: %s\n",
   12216             :                          tldap_rc2string(rc));
   12217           0 :                 callback_code = rc;
   12218           0 :                 return;
   12219             :         }
   12220        1912 :         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
   12221          32 :                 TALLOC_FREE(msg);
   12222          32 :                 return;
   12223             :         }
   12224        1880 :         if (!tldap_entry_dn(msg, &dn)) {
   12225           0 :                 d_printf("tldap_entry_dn failed\n");
   12226           0 :                 return;
   12227             :         }
   12228        1880 :         d_printf("%s\n", dn);
   12229        1880 :         TALLOC_FREE(msg);
   12230             : }
   12231             : 
   12232             : enum tldap_extended_val {
   12233             :         EXTENDED_ZERO = 0,
   12234             :         EXTENDED_ONE = 1,
   12235             :         EXTENDED_NONE = 2,
   12236             : };
   12237             : 
   12238             : /*
   12239             :  * Construct an extended dn control with either no value, 0 or 1
   12240             :  *
   12241             :  * No value and 0 are equivalent (non-hyphenated GUID)
   12242             :  * 1 has the hyphenated GUID
   12243             :  */
   12244             : static struct tldap_control *
   12245          24 : tldap_build_extended_control(enum tldap_extended_val val)
   12246             : {
   12247           0 :         struct tldap_control empty_control;
   12248           0 :         struct asn1_data *data;
   12249             : 
   12250          24 :         ZERO_STRUCT(empty_control);
   12251             : 
   12252          24 :         if (val != EXTENDED_NONE) {
   12253          16 :                 data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
   12254             : 
   12255          16 :                 if (!data) {
   12256           0 :                         return NULL;
   12257             :                 }
   12258             : 
   12259          16 :                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
   12260           0 :                         return NULL;
   12261             :                 }
   12262             : 
   12263          16 :                 if (!asn1_write_Integer(data, (int)val)) {
   12264           0 :                         return NULL;
   12265             :                 }
   12266             : 
   12267          16 :                 if (!asn1_pop_tag(data)) {
   12268           0 :                         return NULL;
   12269             :                 }
   12270             : 
   12271          16 :                 if (!asn1_blob(data, &empty_control.value)) {
   12272           0 :                         return NULL;
   12273             :                 }
   12274             :         }
   12275             : 
   12276          24 :         empty_control.oid = "1.2.840.113556.1.4.529";
   12277          24 :         empty_control.critical = true;
   12278             : 
   12279          24 :         return tldap_add_control(talloc_tos(), NULL, 0, &empty_control);
   12280             : 
   12281             : }
   12282             : 
   12283          24 : static bool tldap_test_dn_guid_format(struct tldap_context *ld, const char *basedn,
   12284             :                                       enum tldap_extended_val control_val)
   12285             : {
   12286          24 :         struct tldap_control *control = tldap_build_extended_control(control_val);
   12287          24 :         char *dn = NULL;
   12288           0 :         struct tldap_message **msg;
   12289           0 :         TLDAPRC rc;
   12290             : 
   12291          24 :         rc = tldap_search(ld, basedn, TLDAP_SCOPE_BASE,
   12292             :                           "(objectClass=*)", NULL, 0, 0,
   12293             :                           control, 1, NULL,
   12294             :                           0, 0, 0, 0, talloc_tos(), &msg);
   12295          24 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12296           0 :                 d_printf("tldap_search for domain DN failed: %s\n",
   12297             :                          tldap_errstr(talloc_tos(), ld, rc));
   12298           0 :                 return false;
   12299             :         }
   12300             : 
   12301          24 :         if (!tldap_entry_dn(msg[0], &dn)) {
   12302           0 :                 d_printf("tldap_search domain DN fetch failed: %s\n",
   12303             :                          tldap_errstr(talloc_tos(), ld, rc));
   12304           0 :                 return false;
   12305             :         }
   12306             : 
   12307          24 :         d_printf("%s\n", dn);
   12308             :         {
   12309           0 :                 uint32_t time_low;
   12310           0 :                 uint32_t time_mid, time_hi_and_version;
   12311           0 :                 uint32_t clock_seq[2];
   12312           0 :                 uint32_t node[6];
   12313           0 :                 char next;
   12314             : 
   12315          24 :                 switch (control_val) {
   12316          16 :                 case EXTENDED_NONE:
   12317             :                 case EXTENDED_ZERO:
   12318             :                         /*
   12319             :                          * When reading GUIDs with hyphens, scanf will treat
   12320             :                          * hyphen as a hex character (and counts as part of the
   12321             :                          * width). This creates leftover GUID string which we
   12322             :                          * check will for with 'next' and closing '>'.
   12323             :                          */
   12324          16 :                         if (12 == sscanf(dn, "<GUID=%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x>%c",
   12325             :                                          &time_low, &time_mid,
   12326             :                                          &time_hi_and_version, &clock_seq[0],
   12327             :                                          &clock_seq[1], &node[0], &node[1],
   12328             :                                          &node[2], &node[3], &node[4],
   12329             :                                          &node[5], &next)) {
   12330             :                                 /* This GUID is good */
   12331             :                         } else {
   12332           0 :                                 d_printf("GUID format in control (no hyphens) doesn't match output\n");
   12333           0 :                                 return false;
   12334             :                         }
   12335             : 
   12336          16 :                         break;
   12337           8 :                 case EXTENDED_ONE:
   12338           8 :                         if (12 == sscanf(dn,
   12339             :                                          "<GUID=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x>%c",
   12340             :                                          &time_low, &time_mid,
   12341             :                                          &time_hi_and_version, &clock_seq[0],
   12342             :                                          &clock_seq[1], &node[0], &node[1],
   12343             :                                          &node[2], &node[3], &node[4],
   12344             :                                          &node[5], &next)) {
   12345             :                                 /* This GUID is good */
   12346             :                         } else {
   12347           0 :                                 d_printf("GUID format in control (with hyphens) doesn't match output\n");
   12348           0 :                                 return false;
   12349             :                         }
   12350             : 
   12351           8 :                         break;
   12352           0 :                 default:
   12353           0 :                         return false;
   12354             :                 }
   12355             :         }
   12356             : 
   12357          24 :         return true;
   12358             : }
   12359             : 
   12360           8 : static bool run_tldap(int dummy)
   12361             : {
   12362           0 :         struct tldap_context *ld;
   12363           0 :         int fd;
   12364           0 :         TLDAPRC rc;
   12365           0 :         NTSTATUS status;
   12366           0 :         struct sockaddr_storage addr;
   12367           0 :         struct tevent_context *ev;
   12368           0 :         struct tevent_req *req;
   12369           0 :         char *basedn;
   12370           0 :         const char *filter;
   12371           8 :         struct loadparm_context *lp_ctx = NULL;
   12372           8 :         int tcp_port = 389;
   12373           8 :         bool use_tls = false;
   12374           8 :         bool use_starttls = false;
   12375           8 :         int wrap_flags = -1;
   12376           8 :         uint32_t gensec_features = 0;
   12377             : 
   12378           8 :         lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
   12379             : 
   12380           8 :         wrap_flags = lpcfg_client_ldap_sasl_wrapping(lp_ctx);
   12381             : 
   12382           8 :         if (wrap_flags & ADS_AUTH_SASL_LDAPS) {
   12383           2 :                 use_tls = true;
   12384           2 :                 tcp_port = 636;
   12385           6 :         } else if (wrap_flags & ADS_AUTH_SASL_STARTTLS) {
   12386           2 :                 use_tls = true;
   12387           2 :                 use_starttls = true;
   12388             :         }
   12389           8 :         if (wrap_flags & ADS_AUTH_SASL_SEAL) {
   12390           2 :                 gensec_features |= GENSEC_FEATURE_SEAL;
   12391             :         }
   12392           8 :         if (wrap_flags & ADS_AUTH_SASL_SIGN) {
   12393           2 :                 gensec_features |= GENSEC_FEATURE_SIGN;
   12394             :         }
   12395             : 
   12396           8 :         if (gensec_features != 0) {
   12397           4 :                 gensec_features |= GENSEC_FEATURE_LDAP_STYLE;
   12398             :         }
   12399             : 
   12400           8 :         if (!resolve_name(host, &addr, 0, false)) {
   12401           0 :                 d_printf("could not find host %s\n", host);
   12402           0 :                 return false;
   12403             :         }
   12404           8 :         status = open_socket_out(&addr, tcp_port, 9999, &fd);
   12405           8 :         if (!NT_STATUS_IS_OK(status)) {
   12406           0 :                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
   12407           0 :                 return false;
   12408             :         }
   12409             : 
   12410           8 :         ld = tldap_context_create(talloc_tos(), fd);
   12411           8 :         if (ld == NULL) {
   12412           0 :                 close(fd);
   12413           0 :                 d_printf("tldap_context_create failed\n");
   12414           0 :                 return false;
   12415             :         }
   12416             : 
   12417           8 :         if (use_tls && !tldap_has_tls_tstream(ld)) {
   12418           4 :                 tldap_set_starttls_needed(ld, use_starttls);
   12419             : 
   12420           4 :                 rc = tldap_tls_connect(ld, lp_ctx, host);
   12421           4 :                 if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12422           0 :                         DBG_ERR("tldap_tls_connect(%s) failed: %s\n",
   12423             :                                 host, tldap_errstr(talloc_tos(), ld, rc));
   12424           0 :                         return false;
   12425             :                 }
   12426             :         }
   12427             : 
   12428           8 :         rc = tldap_fetch_rootdse(ld);
   12429           8 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12430           0 :                 d_printf("tldap_fetch_rootdse failed: %s\n",
   12431             :                          tldap_errstr(talloc_tos(), ld, rc));
   12432           0 :                 return false;
   12433             :         }
   12434             : 
   12435           8 :         basedn = tldap_talloc_single_attribute(
   12436             :                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
   12437           8 :         if (basedn == NULL) {
   12438           0 :                 d_printf("no defaultNamingContext\n");
   12439           0 :                 return false;
   12440             :         }
   12441           8 :         d_printf("defaultNamingContext: %s\n", basedn);
   12442             : 
   12443           8 :         ev = samba_tevent_context_init(talloc_tos());
   12444           8 :         if (ev == NULL) {
   12445           0 :                 d_printf("tevent_context_init failed\n");
   12446           0 :                 return false;
   12447             :         }
   12448             : 
   12449           8 :         rc = tldap_gensec_bind(ld, torture_creds, "ldap", host, NULL,
   12450             :                                lp_ctx, gensec_features);
   12451           8 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12452           0 :                 d_printf("tldap_gensec_bind failed\n");
   12453           0 :                 return false;
   12454             :         }
   12455             : 
   12456           8 :         callback_code = TLDAP_SUCCESS;
   12457             : 
   12458           8 :         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
   12459             :                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
   12460             :                                       NULL, 0, 0,
   12461             :                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
   12462           8 :         if (req == NULL) {
   12463           0 :                 d_printf("tldap_search_paged_send failed\n");
   12464           0 :                 return false;
   12465             :         }
   12466           8 :         tevent_req_set_callback(req, pagedsearch_cb, NULL);
   12467             : 
   12468           8 :         tevent_req_poll(req, ev);
   12469             : 
   12470           8 :         TALLOC_FREE(req);
   12471             : 
   12472           8 :         rc = callback_code;
   12473             : 
   12474           8 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12475           0 :                 d_printf("tldap_search with paging failed: %s\n",
   12476             :                          tldap_errstr(talloc_tos(), ld, rc));
   12477           0 :                 return false;
   12478             :         }
   12479             : 
   12480             :         /* test search filters against rootDSE */
   12481           8 :         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
   12482             :                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
   12483             : 
   12484           8 :         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
   12485             :                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
   12486             :                           talloc_tos(), NULL);
   12487           8 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12488           0 :                 d_printf("tldap_search with complex filter failed: %s\n",
   12489             :                          tldap_errstr(talloc_tos(), ld, rc));
   12490           0 :                 return false;
   12491             :         }
   12492             : 
   12493             :         /*
   12494             :          * Tests to check for regression of:
   12495             :          *
   12496             :          * https://bugzilla.samba.org/show_bug.cgi?id=14029
   12497             :          *
   12498             :          * TLDAP used here to pick apart the original string DN (with GUID)
   12499             :          */
   12500           8 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_NONE)) {
   12501           0 :                 d_printf("tldap_search with extended dn (no val) failed: %s\n",
   12502             :                          tldap_errstr(talloc_tos(), ld, rc));
   12503           0 :                 return false;
   12504             :         }
   12505           8 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ZERO)) {
   12506           0 :                 d_printf("tldap_search with extended dn (0) failed: %s\n",
   12507             :                          tldap_errstr(talloc_tos(), ld, rc));
   12508           0 :                 return false;
   12509             :         }
   12510           8 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ONE)) {
   12511           0 :                 d_printf("tldap_search with extended dn (1) failed: %s\n",
   12512             :                          tldap_errstr(talloc_tos(), ld, rc));
   12513           0 :                 return false;
   12514             :         }
   12515             : 
   12516           8 :         TALLOC_FREE(ld);
   12517           8 :         return true;
   12518             : }
   12519             : 
   12520             : /* Torture test to ensure no regression of :
   12521             : https://bugzilla.samba.org/show_bug.cgi?id=7084
   12522             : */
   12523             : 
   12524           4 : static bool run_dir_createtime(int dummy)
   12525             : {
   12526           0 :         struct cli_state *cli;
   12527           4 :         const char *dname = "\\testdir_createtime";
   12528           4 :         const char *fname = "\\testdir_createtime\\testfile";
   12529           0 :         NTSTATUS status;
   12530           0 :         struct timespec create_time;
   12531           0 :         struct timespec create_time1;
   12532           0 :         uint16_t fnum;
   12533           4 :         bool ret = false;
   12534           0 :         uint64_t ino;
   12535             : 
   12536           4 :         if (!torture_open_connection(&cli, 0)) {
   12537           0 :                 return false;
   12538             :         }
   12539             : 
   12540           4 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12541             :                 /* Ensure ino is zero, SMB2 gets a real one. */
   12542           0 :                 ino = 0;
   12543             :         } else {
   12544             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
   12545           4 :                 ino = (uint64_t)-1;
   12546             :         }
   12547             : 
   12548           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12549           4 :         cli_rmdir(cli, dname);
   12550             : 
   12551           4 :         status = cli_mkdir(cli, dname);
   12552           4 :         if (!NT_STATUS_IS_OK(status)) {
   12553           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12554           0 :                 goto out;
   12555             :         }
   12556             : 
   12557           4 :         status = cli_qpathinfo2(cli,
   12558             :                                 dname,
   12559             :                                 &create_time,
   12560             :                                 NULL,
   12561             :                                 NULL,
   12562             :                                 NULL,
   12563             :                                 NULL,
   12564             :                                 NULL,
   12565             :                                 &ino,
   12566             :                                 NULL);
   12567           4 :         if (!NT_STATUS_IS_OK(status)) {
   12568           0 :                 printf("cli_qpathinfo2 returned %s\n",
   12569             :                        nt_errstr(status));
   12570           0 :                 goto out;
   12571             :         }
   12572             : 
   12573           4 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12574             :                 /* SMB2 should always return an inode. */
   12575           0 :                 if (ino == 0) {
   12576           0 :                         printf("SMB2 bad inode (0)\n");
   12577           0 :                         goto out;
   12578             :                 }
   12579             :         } else {
   12580             :                 /* SMB1 must always return zero here. */
   12581           4 :                 if (ino != 0) {
   12582           0 :                         printf("SMB1 bad inode (!0)\n");
   12583           0 :                         goto out;
   12584             :                 }
   12585             :         }
   12586             : 
   12587             :         /* Sleep 3 seconds, then create a file. */
   12588           4 :         sleep(3);
   12589             : 
   12590           4 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
   12591             :                          DENY_NONE, &fnum);
   12592           4 :         if (!NT_STATUS_IS_OK(status)) {
   12593           0 :                 printf("cli_openx failed: %s\n", nt_errstr(status));
   12594           0 :                 goto out;
   12595             :         }
   12596             : 
   12597           4 :         status = cli_qpathinfo2(cli,
   12598             :                                 dname,
   12599             :                                 &create_time1,
   12600             :                                 NULL,
   12601             :                                 NULL,
   12602             :                                 NULL,
   12603             :                                 NULL,
   12604             :                                 NULL,
   12605             :                                 NULL,
   12606             :                                 NULL);
   12607           4 :         if (!NT_STATUS_IS_OK(status)) {
   12608           0 :                 printf("cli_qpathinfo2 (2) returned %s\n",
   12609             :                        nt_errstr(status));
   12610           0 :                 goto out;
   12611             :         }
   12612             : 
   12613           4 :         if (timespec_compare(&create_time1, &create_time)) {
   12614           0 :                 printf("run_dir_createtime: create time was updated (error)\n");
   12615             :         } else {
   12616           4 :                 printf("run_dir_createtime: create time was not updated (correct)\n");
   12617           4 :                 ret = true;
   12618             :         }
   12619             : 
   12620           4 :   out:
   12621             : 
   12622           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12623           4 :         cli_rmdir(cli, dname);
   12624           4 :         if (!torture_close_connection(cli)) {
   12625           0 :                 ret = false;
   12626             :         }
   12627           4 :         return ret;
   12628             : }
   12629             : 
   12630             : 
   12631           4 : static bool run_streamerror(int dummy)
   12632             : {
   12633           0 :         struct cli_state *cli;
   12634           4 :         const char *dname = "\\testdir_streamerror";
   12635           4 :         const char *streamname =
   12636             :                 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
   12637           0 :         NTSTATUS status;
   12638           0 :         time_t change_time, access_time, write_time;
   12639           0 :         off_t size;
   12640           0 :         uint16_t fnum;
   12641           0 :         uint32_t attr;
   12642           4 :         bool ret = true;
   12643             : 
   12644           4 :         if (!torture_open_connection(&cli, 0)) {
   12645           0 :                 return false;
   12646             :         }
   12647             : 
   12648           4 :         torture_deltree(cli, dname);
   12649             : 
   12650           4 :         status = cli_mkdir(cli, dname);
   12651           4 :         if (!NT_STATUS_IS_OK(status)) {
   12652           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12653           0 :                 return false;
   12654             :         }
   12655             : 
   12656           4 :         status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
   12657             :                                 &write_time, &size, &attr);
   12658           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12659           0 :                 printf("pathinfo returned %s, expected "
   12660             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12661             :                        nt_errstr(status));
   12662           0 :                 ret = false;
   12663             :         }
   12664             : 
   12665           4 :         status = cli_ntcreate(cli, streamname, 0x16,
   12666             :                               FILE_READ_DATA|FILE_READ_EA|
   12667             :                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
   12668             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
   12669             :                               FILE_OPEN, 0, 0, &fnum, NULL);
   12670             : 
   12671           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12672           0 :                 printf("ntcreate returned %s, expected "
   12673             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12674             :                        nt_errstr(status));
   12675           0 :                 ret = false;
   12676             :         }
   12677             : 
   12678             : 
   12679           4 :         cli_rmdir(cli, dname);
   12680           4 :         return ret;
   12681             : }
   12682             : 
   12683             : struct pidtest_state {
   12684             :         bool success;
   12685             :         uint16_t vwv[1];
   12686             :         DATA_BLOB data;
   12687             : };
   12688             : 
   12689             : static void pid_echo_done(struct tevent_req *subreq);
   12690             : 
   12691           4 : static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
   12692             :                         struct tevent_context *ev,
   12693             :                         struct cli_state *cli)
   12694             : {
   12695           0 :         struct tevent_req *req, *subreq;
   12696           0 :         struct pidtest_state *state;
   12697             : 
   12698           4 :         req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
   12699           4 :         if (req == NULL) {
   12700           0 :                 return NULL;
   12701             :         }
   12702             : 
   12703           4 :         SSVAL(state->vwv, 0, 1);
   12704           4 :         state->data = data_blob_const("hello", 5);
   12705             : 
   12706           4 :         subreq = smb1cli_req_send(state,
   12707             :                                 ev,
   12708             :                                 cli->conn,
   12709             :                                 SMBecho,
   12710             :                                 0, 0, /* *_flags */
   12711             :                                 0, 0, /* *_flags2 */
   12712           4 :                                 cli->timeout,
   12713             :                                 0xDEADBEEF, /* pid */
   12714             :                                 NULL, /* tcon */
   12715             :                                 NULL, /* session */
   12716           4 :                                 ARRAY_SIZE(state->vwv), state->vwv,
   12717           4 :                                 state->data.length, state->data.data);
   12718             : 
   12719           4 :         if (tevent_req_nomem(subreq, req)) {
   12720           0 :                 return tevent_req_post(req, ev);
   12721             :         }
   12722           4 :         tevent_req_set_callback(subreq, pid_echo_done, req);
   12723           4 :         return req;
   12724             : }
   12725             : 
   12726           4 : static void pid_echo_done(struct tevent_req *subreq)
   12727             : {
   12728           4 :         struct tevent_req *req = tevent_req_callback_data(
   12729             :                 subreq, struct tevent_req);
   12730           4 :         struct pidtest_state *state = tevent_req_data(
   12731             :                 req, struct pidtest_state);
   12732           0 :         NTSTATUS status;
   12733           0 :         uint32_t num_bytes;
   12734           4 :         uint8_t *bytes = NULL;
   12735           4 :         struct iovec *recv_iov = NULL;
   12736           4 :         uint8_t *phdr = NULL;
   12737           4 :         uint16_t pidlow = 0;
   12738           4 :         uint16_t pidhigh = 0;
   12739           4 :         struct smb1cli_req_expected_response expected[] = {
   12740             :         {
   12741             :                 .status = NT_STATUS_OK,
   12742             :                 .wct    = 1,
   12743             :         },
   12744             :         };
   12745             : 
   12746           4 :         status = smb1cli_req_recv(subreq, state,
   12747             :                                 &recv_iov,
   12748             :                                 &phdr,
   12749             :                                 NULL, /* pwct */
   12750             :                                 NULL, /* pvwv */
   12751             :                                 NULL, /* pvwv_offset */
   12752             :                                 &num_bytes,
   12753             :                                 &bytes,
   12754             :                                 NULL, /* pbytes_offset */
   12755             :                                 NULL, /* pinbuf */
   12756             :                                 expected, ARRAY_SIZE(expected));
   12757             : 
   12758           4 :         TALLOC_FREE(subreq);
   12759             : 
   12760           4 :         if (!NT_STATUS_IS_OK(status)) {
   12761           0 :                 tevent_req_nterror(req, status);
   12762           0 :                 return;
   12763             :         }
   12764             : 
   12765           4 :         if (num_bytes != state->data.length) {
   12766           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12767           0 :                 return;
   12768             :         }
   12769             : 
   12770           4 :         if (memcmp(bytes, state->data.data, num_bytes) != 0) {
   12771           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12772           0 :                 return;
   12773             :         }
   12774             : 
   12775             :         /* Check pid low/high == DEADBEEF */
   12776           4 :         pidlow = SVAL(phdr, HDR_PID);
   12777           4 :         if (pidlow != 0xBEEF){
   12778           0 :                 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
   12779             :                         (unsigned int)pidlow);
   12780           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12781           0 :                 return;
   12782             :         }
   12783           4 :         pidhigh = SVAL(phdr, HDR_PIDHIGH);
   12784           4 :         if (pidhigh != 0xDEAD){
   12785           0 :                 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
   12786             :                         (unsigned int)pidhigh);
   12787           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12788           0 :                 return;
   12789             :         }
   12790             : 
   12791           4 :         tevent_req_done(req);
   12792             : }
   12793             : 
   12794           4 : static NTSTATUS pid_echo_recv(struct tevent_req *req)
   12795             : {
   12796           4 :         return tevent_req_simple_recv_ntstatus(req);
   12797             : }
   12798             : 
   12799           4 : static bool run_pidhigh(int dummy)
   12800             : {
   12801           4 :         bool success = false;
   12802           4 :         struct cli_state *cli = NULL;
   12803           0 :         NTSTATUS status;
   12804           4 :         struct tevent_context *ev = NULL;
   12805           4 :         struct tevent_req *req = NULL;
   12806           4 :         TALLOC_CTX *frame = talloc_stackframe();
   12807             : 
   12808           4 :         printf("starting pid high test\n");
   12809           4 :         if (!torture_open_connection(&cli, 0)) {
   12810           0 :                 return false;
   12811             :         }
   12812           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12813             : 
   12814           4 :         ev = samba_tevent_context_init(frame);
   12815           4 :         if (ev == NULL) {
   12816           0 :                 goto fail;
   12817             :         }
   12818             : 
   12819           4 :         req = pid_echo_send(frame, ev, cli);
   12820           4 :         if (req == NULL) {
   12821           0 :                 goto fail;
   12822             :         }
   12823             : 
   12824           4 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
   12825           0 :                 goto fail;
   12826             :         }
   12827             : 
   12828           4 :         status = pid_echo_recv(req);
   12829           4 :         if (NT_STATUS_IS_OK(status)) {
   12830           4 :                 printf("pid high test ok\n");
   12831           4 :                 success = true;
   12832             :         }
   12833             : 
   12834           0 :  fail:
   12835             : 
   12836           4 :         TALLOC_FREE(frame);
   12837           4 :         torture_close_connection(cli);
   12838           4 :         return success;
   12839             : }
   12840             : 
   12841             : /*
   12842             :   Test Windows open on a bad POSIX symlink.
   12843             :  */
   12844           4 : static bool run_symlink_open_test(int dummy)
   12845             : {
   12846           0 :         static struct cli_state *cli;
   12847           4 :         const char *fname = "non_existant_file";
   12848           4 :         const char *sname = "dangling_symlink";
   12849           4 :         uint16_t fnum = (uint16_t)-1;
   12850           4 :         bool correct = false;
   12851           0 :         NTSTATUS status;
   12852           4 :         TALLOC_CTX *frame = NULL;
   12853             : 
   12854           4 :         frame = talloc_stackframe();
   12855             : 
   12856           4 :         printf("Starting Windows bad symlink open test\n");
   12857             : 
   12858           4 :         if (!torture_open_connection(&cli, 0)) {
   12859           0 :                 TALLOC_FREE(frame);
   12860           0 :                 return false;
   12861             :         }
   12862             : 
   12863           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12864             : 
   12865           4 :         status = torture_setup_unix_extensions(cli);
   12866           4 :         if (!NT_STATUS_IS_OK(status)) {
   12867           0 :                 TALLOC_FREE(frame);
   12868           0 :                 return false;
   12869             :         }
   12870             : 
   12871             :         /* Ensure nothing exists. */
   12872           4 :         cli_setatr(cli, fname, 0, 0);
   12873           4 :         cli_posix_unlink(cli, fname);
   12874           4 :         cli_setatr(cli, sname, 0, 0);
   12875           4 :         cli_posix_unlink(cli, sname);
   12876             : 
   12877             :         /* Create a symlink pointing nowhere. */
   12878           4 :         status = cli_posix_symlink(cli, fname, sname);
   12879           4 :         if (!NT_STATUS_IS_OK(status)) {
   12880           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
   12881             :                         sname,
   12882             :                         fname,
   12883             :                         nt_errstr(status));
   12884           0 :                 goto out;
   12885             :         }
   12886             : 
   12887             :         /* Now ensure that a Windows open doesn't hang. */
   12888           4 :         status = cli_ntcreate(cli,
   12889             :                         sname,
   12890             :                         0,
   12891             :                         FILE_READ_DATA|FILE_WRITE_DATA,
   12892             :                         0,
   12893             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   12894             :                         FILE_OPEN_IF,
   12895             :                         0x0,
   12896             :                         0x0,
   12897             :                         &fnum,
   12898             :                         NULL);
   12899             : 
   12900             :         /*
   12901             :          * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
   12902             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
   12903             :          * we use O_NOFOLLOW on the server or not.
   12904             :          */
   12905           4 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
   12906           0 :             NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
   12907             :         {
   12908           4 :                 correct = true;
   12909             :         } else {
   12910           0 :                 printf("cli_ntcreate of %s returned %s - should return"
   12911             :                                 " either (%s) or (%s)\n",
   12912             :                         sname,
   12913             :                         nt_errstr(status),
   12914           0 :                         nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
   12915           0 :                         nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
   12916           0 :                 goto out;
   12917             :         }
   12918             : 
   12919           4 :         correct = true;
   12920             : 
   12921           4 :   out:
   12922             : 
   12923           4 :         if (fnum != (uint16_t)-1) {
   12924           0 :                 cli_close(cli, fnum);
   12925           0 :                 fnum = (uint16_t)-1;
   12926             :         }
   12927             : 
   12928           4 :         cli_setatr(cli, sname, 0, 0);
   12929           4 :         cli_posix_unlink(cli, sname);
   12930           4 :         cli_setatr(cli, fname, 0, 0);
   12931           4 :         cli_posix_unlink(cli, fname);
   12932             : 
   12933           4 :         if (!torture_close_connection(cli)) {
   12934           0 :                 correct = false;
   12935             :         }
   12936             : 
   12937           4 :         TALLOC_FREE(frame);
   12938           4 :         return correct;
   12939             : }
   12940             : 
   12941          16 : static NTSTATUS smb1_wild_mangle_list_fn(struct file_info *finfo,
   12942             :                                         const char *name,
   12943             :                                         void *state)
   12944             : {
   12945          16 :         char **mangled_name_return = (char **)state;
   12946          16 :         bool is_mangled = strchr(finfo->name, '~');
   12947             : 
   12948          16 :         if (is_mangled) {
   12949           8 :                 *mangled_name_return = talloc_strdup(NULL, finfo->name);
   12950           8 :                 if (*mangled_name_return == NULL) {
   12951           0 :                         return NT_STATUS_NO_MEMORY;
   12952             :                 }
   12953             :         }
   12954          16 :         return NT_STATUS_OK;
   12955             : }
   12956             : 
   12957           4 : static bool run_smb1_wild_mangle_unlink_test(int dummy)
   12958             : {
   12959           0 :         static struct cli_state *cli_posix = NULL;
   12960           0 :         static struct cli_state *cli = NULL;
   12961           4 :         uint16_t fnum = (uint16_t)-1;
   12962           4 :         bool correct = false;
   12963           4 :         const char *dname = "smb1_wild_mangle_unlink";
   12964           4 :         const char *aname = "smb1_wild_mangle_unlink/a";
   12965           4 :         const char *star_name = "smb1_wild_mangle_unlink/*";
   12966           4 :         char *windows_unlink_name = NULL;
   12967           4 :         char *mangled_name = NULL;
   12968           0 :         NTSTATUS status;
   12969             : 
   12970           4 :         printf("Starting SMB1 wild mangle unlink test\n");
   12971             : 
   12972             :         /* Open a Windows connection. */
   12973           4 :         if (!torture_open_connection(&cli, 0)) {
   12974           0 :                 return false;
   12975             :         }
   12976             : 
   12977           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12978             : 
   12979             :         /* Open a POSIX connection. */
   12980           4 :         if (!torture_open_connection(&cli_posix, 0)) {
   12981           0 :                 goto out;
   12982             :         }
   12983             : 
   12984           4 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   12985             : 
   12986           4 :         status = torture_setup_unix_extensions(cli_posix);
   12987           4 :         if (!NT_STATUS_IS_OK(status)) {
   12988           0 :                 printf("server doesn't support POSIX\n");
   12989           0 :                 goto out;
   12990             :         }
   12991             : 
   12992             :         /* Start fresh. */
   12993           4 :         torture_deltree(cli, dname);
   12994             : 
   12995             :         /*
   12996             :          * Create two files - 'a' and '*'.
   12997             :          * We need POSIX extensions for this as '*'
   12998             :          * is not a valid Windows name.
   12999             :          */
   13000             : 
   13001           4 :         status = cli_mkdir(cli, dname);
   13002           4 :         if (!NT_STATUS_IS_OK(status)) {
   13003           0 :                 printf("cli_mkdir of %s returned %s\n",
   13004             :                         dname,
   13005             :                         nt_errstr(status));
   13006           0 :                 goto out;
   13007             :         }
   13008             : 
   13009           4 :         status = cli_posix_open(cli_posix,
   13010             :                                 aname,
   13011             :                                 O_RDWR|O_CREAT|O_EXCL,
   13012             :                                 0660,
   13013             :                                 &fnum);
   13014           4 :         if (!NT_STATUS_IS_OK(status)) {
   13015           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   13016             :                         aname,
   13017             :                         nt_errstr(status));
   13018           0 :                 goto out;
   13019             :         }
   13020           4 :         status = cli_close(cli_posix, fnum);
   13021           4 :         if (!NT_STATUS_IS_OK(status)) {
   13022           0 :                 goto out;
   13023             :         }
   13024           4 :         status = cli_posix_open(cli_posix,
   13025             :                                 star_name,
   13026             :                                 O_RDWR|O_CREAT|O_EXCL,
   13027             :                                 0660,
   13028             :                                 &fnum);
   13029           4 :         if (!NT_STATUS_IS_OK(status)) {
   13030           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   13031             :                         star_name,
   13032             :                         nt_errstr(status));
   13033           0 :                 goto out;
   13034             :         }
   13035           4 :         status = cli_close(cli_posix, fnum);
   13036           4 :         if (!NT_STATUS_IS_OK(status)) {
   13037           0 :                 goto out;
   13038             :         }
   13039             : 
   13040           4 :         status = cli_list(cli,
   13041             :                         star_name,
   13042             :                         0,
   13043             :                         smb1_wild_mangle_list_fn,
   13044             :                         &mangled_name);
   13045           4 :         if (!NT_STATUS_IS_OK(status)) {
   13046           0 :                 printf("cli_list of %s returned %s\n",
   13047             :                         star_name,
   13048             :                         nt_errstr(status));
   13049           0 :                 goto out;
   13050             :         }
   13051             : 
   13052           4 :         if (mangled_name == NULL) {
   13053           0 :                 goto out;
   13054             :         }
   13055             : 
   13056           4 :         printf("mangled_name = %s\n",
   13057             :                 mangled_name);
   13058             : 
   13059             :         /*
   13060             :          * Try a Windows unlink with the mangled name.
   13061             :          * This should *NOT* unlink the 'a' name.
   13062             :          */
   13063             : 
   13064           4 :         windows_unlink_name = talloc_asprintf(cli_posix,
   13065             :                                         "%s\\%s",
   13066             :                                         dname,
   13067             :                                         mangled_name);
   13068             : 
   13069           4 :         status = cli_unlink(cli, windows_unlink_name, 0);
   13070           4 :         if (!NT_STATUS_IS_OK(status)) {
   13071           0 :                 printf("cli_unlink of %s returned %s\n",
   13072             :                         windows_unlink_name,
   13073             :                         nt_errstr(status));
   13074           0 :                 goto out;
   13075             :         }
   13076             : 
   13077             :         /* Does 'a' still exist ? */
   13078           4 :         status = cli_posix_open(cli_posix,
   13079             :                                 aname,
   13080             :                                 O_RDONLY,
   13081             :                                 0,
   13082             :                                 &fnum);
   13083           4 :         if (!NT_STATUS_IS_OK(status)) {
   13084           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   13085             :                         aname,
   13086             :                         nt_errstr(status));
   13087           0 :                 goto out;
   13088             :         }
   13089             : 
   13090           4 :         status = cli_close(cli_posix, fnum);
   13091           4 :         if (!NT_STATUS_IS_OK(status)) {
   13092           0 :                 goto out;
   13093             :         }
   13094             : 
   13095           4 :         correct = true;
   13096             : 
   13097           4 :   out:
   13098             : 
   13099           4 :         TALLOC_FREE(windows_unlink_name);
   13100           4 :         TALLOC_FREE(mangled_name);
   13101             : 
   13102           4 :         if (cli != NULL) {
   13103           4 :                 torture_deltree(cli, dname);
   13104           4 :                 torture_close_connection(cli);
   13105             :         }
   13106             : 
   13107           4 :         if (cli_posix != NULL) {
   13108           4 :                 torture_close_connection(cli_posix);
   13109             :         }
   13110             : 
   13111           4 :         return correct;
   13112             : }
   13113             : 
   13114           4 : static bool run_smb1_wild_mangle_rename_test(int dummy)
   13115             : {
   13116           0 :         static struct cli_state *cli_posix = NULL;
   13117           0 :         static struct cli_state *cli = NULL;
   13118           4 :         uint16_t fnum = (uint16_t)-1;
   13119           4 :         bool correct = false;
   13120           4 :         const char *dname = "smb1_wild_mangle_rename";
   13121           4 :         const char *fooname = "smb1_wild_mangle_rename/foo";
   13122           4 :         const char *foostar_name = "smb1_wild_mangle_rename/fo*";
   13123           4 :         const char *wild_name = "smb1_wild_mangle_rename/*";
   13124           4 :         char *windows_rename_src = NULL;
   13125           4 :         const char *windows_rename_dst = "smb1_wild_mangle_rename\\bar";
   13126           4 :         char *mangled_name = NULL;
   13127           0 :         NTSTATUS status;
   13128             : 
   13129           4 :         printf("Starting SMB1 wild mangle rename test\n");
   13130             : 
   13131           4 :         if (!torture_open_connection(&cli_posix, 0)) {
   13132           0 :                 return false;
   13133             :         }
   13134             : 
   13135           4 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   13136             : 
   13137           4 :         status = torture_setup_unix_extensions(cli_posix);
   13138           4 :         if (!NT_STATUS_IS_OK(status)) {
   13139           0 :                 printf("server doesn't support POSIX\n");
   13140           0 :                 return false;
   13141             :         }
   13142             : 
   13143             :         /* Open a Windows connection. */
   13144           4 :         if (!torture_open_connection(&cli, 0)) {
   13145           0 :                 goto out;
   13146             :         }
   13147             : 
   13148           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   13149             : 
   13150             :         /* Ensure we start from fresh. */
   13151           4 :         torture_deltree(cli, dname);
   13152             : 
   13153             :         /*
   13154             :          * Create two files - 'foo' and 'fo*'.
   13155             :          * We need POSIX extensions for this as 'fo*'
   13156             :          * is not a valid Windows name.
   13157             :          */
   13158             : 
   13159           4 :         status = cli_posix_mkdir(cli_posix, dname, 0770);
   13160           4 :         if (!NT_STATUS_IS_OK(status)) {
   13161           0 :                 printf("cli_posix_mkdir of %s returned %s\n",
   13162             :                         dname,
   13163             :                         nt_errstr(status));
   13164           0 :                 goto out;
   13165             :         }
   13166             : 
   13167           4 :         status = cli_posix_open(cli_posix,
   13168             :                                 fooname,
   13169             :                                 O_RDWR|O_CREAT|O_EXCL,
   13170             :                                 0660,
   13171             :                                 &fnum);
   13172           4 :         if (!NT_STATUS_IS_OK(status)) {
   13173           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   13174             :                         fooname,
   13175             :                         nt_errstr(status));
   13176           0 :                 goto out;
   13177             :         }
   13178           4 :         status = cli_close(cli_posix, fnum);
   13179           4 :         if (!NT_STATUS_IS_OK(status)) {
   13180           0 :                 goto out;
   13181             :         }
   13182           4 :         status = cli_posix_open(cli_posix,
   13183             :                                 foostar_name,
   13184             :                                 O_RDWR|O_CREAT|O_EXCL,
   13185             :                                 0660,
   13186             :                                 &fnum);
   13187           4 :         if (!NT_STATUS_IS_OK(status)) {
   13188           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   13189             :                         foostar_name,
   13190             :                         nt_errstr(status));
   13191           0 :                 goto out;
   13192             :         }
   13193           4 :         status = cli_close(cli_posix, fnum);
   13194           4 :         if (!NT_STATUS_IS_OK(status)) {
   13195           0 :                 goto out;
   13196             :         }
   13197             : 
   13198             :         /*
   13199             :          * Get the mangled name. We can re-use the
   13200             :          * previous smb1_wild_mangle_list_fn for this.
   13201             :          */
   13202             : 
   13203           4 :         status = cli_list(cli,
   13204             :                         wild_name,
   13205             :                         0,
   13206             :                         smb1_wild_mangle_list_fn,
   13207             :                         &mangled_name);
   13208           4 :         if (!NT_STATUS_IS_OK(status)) {
   13209           0 :                 printf("cli_list of %s returned %s\n",
   13210             :                         wild_name,
   13211             :                         nt_errstr(status));
   13212           0 :                 goto out;
   13213             :         }
   13214             : 
   13215           4 :         if (mangled_name == NULL) {
   13216           0 :                 goto out;
   13217             :         }
   13218             : 
   13219           4 :         printf("mangled_name = %s\n",
   13220             :                 mangled_name);
   13221             : 
   13222             :         /*
   13223             :          * Try a Windows rename with the mangled name.
   13224             :          * This should *NOT* rename the 'foo' name.
   13225             :          */
   13226             : 
   13227           4 :         windows_rename_src = talloc_asprintf(cli_posix,
   13228             :                                         "%s\\%s",
   13229             :                                         dname,
   13230             :                                         mangled_name);
   13231             : 
   13232           4 :         status = cli_rename(cli,
   13233             :                         windows_rename_src,
   13234             :                         windows_rename_dst,
   13235             :                         false);
   13236           4 :         if (!NT_STATUS_IS_OK(status)) {
   13237           0 :                 printf("cli_rename of %s -> %s returned %s\n",
   13238             :                         windows_rename_src,
   13239             :                         windows_rename_dst,
   13240             :                         nt_errstr(status));
   13241           0 :                 goto out;
   13242             :         }
   13243             : 
   13244             :         /* Does 'foo' still exist ? */
   13245           4 :         status = cli_posix_open(cli_posix,
   13246             :                                 fooname,
   13247             :                                 O_RDONLY,
   13248             :                                 0,
   13249             :                                 &fnum);
   13250           4 :         if (!NT_STATUS_IS_OK(status)) {
   13251           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   13252             :                         fooname,
   13253             :                         nt_errstr(status));
   13254           0 :                 goto out;
   13255             :         }
   13256             : 
   13257           4 :         status = cli_close(cli_posix, fnum);
   13258           4 :         if (!NT_STATUS_IS_OK(status)) {
   13259           0 :                 goto out;
   13260             :         }
   13261             : 
   13262           4 :         correct = true;
   13263             : 
   13264           4 :   out:
   13265             : 
   13266           4 :         TALLOC_FREE(mangled_name);
   13267           4 :         TALLOC_FREE(windows_rename_src);
   13268             : 
   13269           4 :         if (cli != NULL) {
   13270           4 :                 torture_deltree(cli, dname);
   13271           4 :                 torture_close_connection(cli);
   13272             :         }
   13273             : 
   13274           4 :         torture_close_connection(cli_posix);
   13275             : 
   13276           4 :         return correct;
   13277             : }
   13278             : 
   13279             : /*
   13280             :  * Only testing minimal time strings, as the others
   13281             :  * need (locale-dependent) guessing at what strftime does and
   13282             :  * even may differ in builds.
   13283             :  */
   13284           1 : static bool timesubst_test(void)
   13285             : {
   13286           1 :         TALLOC_CTX *ctx = NULL;
   13287             :         /* Sa 23. Dez 04:33:20 CET 2017 */
   13288           1 :         const struct timeval tv = { 1514000000, 123 };
   13289           1 :         const char* expect_minimal = "20171223_033320";
   13290           1 :         const char* expect_minus   = "20171223_033320_000123";
   13291           1 :         char *s;
   13292           1 :         char *env_tz, *orig_tz = NULL;
   13293           1 :         bool result = true;
   13294             : 
   13295           1 :         ctx = talloc_new(NULL);
   13296             : 
   13297           1 :         env_tz = getenv("TZ");
   13298           1 :         if(env_tz) {
   13299           1 :                 orig_tz = talloc_strdup(ctx, env_tz);
   13300             :         }
   13301           1 :         setenv("TZ", "UTC", 1);
   13302             : 
   13303           1 :         s = minimal_timeval_string(ctx, &tv, false);
   13304             : 
   13305           1 :         if(!s || strcmp(s, expect_minimal)) {
   13306           0 :                 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
   13307             :                        "[%s]\n", s ? s : "<nil>", expect_minimal);
   13308           0 :                 result = false;
   13309             :         }
   13310           1 :         TALLOC_FREE(s);
   13311           1 :         s = minimal_timeval_string(ctx, &tv, true);
   13312           1 :         if(!s || strcmp(s, expect_minus)) {
   13313           0 :                 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
   13314             :                        "[%s]\n", s ? s : "<nil>", expect_minus);
   13315           0 :                 result = false;
   13316             :         }
   13317           1 :         TALLOC_FREE(s);
   13318             : 
   13319           1 :         if(orig_tz) {
   13320           1 :                 setenv("TZ", orig_tz, 1);
   13321             :         }
   13322             : 
   13323           1 :         TALLOC_FREE(ctx);
   13324           1 :         return result;
   13325             : }
   13326             : 
   13327           1 : static bool run_local_substitute(int dummy)
   13328             : {
   13329           1 :         bool ok = true;
   13330             : 
   13331           1 :         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
   13332           1 :         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
   13333           1 :         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
   13334           1 :         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
   13335           1 :         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
   13336           1 :         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
   13337           1 :         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
   13338           1 :         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
   13339           1 :         ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
   13340             :         /* Substitution depends on current time, so better test the underlying
   13341             :            formatting function. At least covers %t. */
   13342           1 :         ok &= timesubst_test();
   13343             : 
   13344             :         /* Different captialization rules in sub_basic... */
   13345             : 
   13346           1 :         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
   13347           1 :                        "blaDOM") == 0);
   13348             : 
   13349           1 :         return ok;
   13350             : }
   13351             : 
   13352           1 : static bool run_local_base64(int dummy)
   13353             : {
   13354           1 :         int i;
   13355           1 :         bool ret = true;
   13356             : 
   13357        2000 :         for (i=1; i<2000; i++) {
   13358        1999 :                 DATA_BLOB blob1, blob2;
   13359        1999 :                 char *b64;
   13360             : 
   13361        1999 :                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
   13362        1999 :                 blob1.length = i;
   13363        1999 :                 generate_random_buffer(blob1.data, blob1.length);
   13364             : 
   13365        1999 :                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
   13366        1999 :                 if (b64 == NULL) {
   13367           0 :                         d_fprintf(stderr, "base64_encode_data_blob failed "
   13368             :                                   "for %d bytes\n", i);
   13369           0 :                         ret = false;
   13370             :                 }
   13371        1999 :                 blob2 = base64_decode_data_blob(b64);
   13372        1999 :                 TALLOC_FREE(b64);
   13373             : 
   13374        1999 :                 if (data_blob_cmp(&blob1, &blob2)) {
   13375           0 :                         d_fprintf(stderr, "data_blob_cmp failed for %d "
   13376             :                                   "bytes\n", i);
   13377           0 :                         ret = false;
   13378             :                 }
   13379        1999 :                 TALLOC_FREE(blob1.data);
   13380        1999 :                 data_blob_free(&blob2);
   13381             :         }
   13382           1 :         return ret;
   13383             : }
   13384             : 
   13385     1000000 : static void parse_fn(const struct gencache_timeout *t,
   13386             :                      DATA_BLOB blob,
   13387             :                      void *private_data)
   13388             : {
   13389     1000000 :         return;
   13390             : }
   13391             : 
   13392           1 : static bool run_local_gencache(int dummy)
   13393             : {
   13394           1 :         char *val;
   13395           1 :         time_t tm;
   13396           1 :         DATA_BLOB blob;
   13397           1 :         char v;
   13398           1 :         struct memcache *mem;
   13399           1 :         int i;
   13400             : 
   13401           1 :         mem = memcache_init(NULL, 0);
   13402           1 :         if (mem == NULL) {
   13403           0 :                 d_printf("%s: memcache_init failed\n", __location__);
   13404           0 :                 return false;
   13405             :         }
   13406           1 :         memcache_set_global(mem);
   13407             : 
   13408           1 :         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
   13409           0 :                 d_printf("%s: gencache_set() failed\n", __location__);
   13410           0 :                 return False;
   13411             :         }
   13412             : 
   13413           1 :         if (!gencache_get("foo", NULL, NULL, NULL)) {
   13414           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13415           0 :                 return False;
   13416             :         }
   13417             : 
   13418     1000001 :         for (i=0; i<1000000; i++) {
   13419     1000000 :                 gencache_parse("foo", parse_fn, NULL);
   13420             :         }
   13421             : 
   13422           1 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13423           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13424           0 :                 return False;
   13425             :         }
   13426           1 :         TALLOC_FREE(val);
   13427             : 
   13428           1 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13429           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13430           0 :                 return False;
   13431             :         }
   13432             : 
   13433           1 :         if (strcmp(val, "bar") != 0) {
   13434           0 :                 d_printf("%s: gencache_get() returned %s, expected %s\n",
   13435             :                          __location__, val, "bar");
   13436           0 :                 TALLOC_FREE(val);
   13437           0 :                 return False;
   13438             :         }
   13439             : 
   13440           1 :         TALLOC_FREE(val);
   13441             : 
   13442           1 :         if (!gencache_del("foo")) {
   13443           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13444           0 :                 return False;
   13445             :         }
   13446           1 :         if (gencache_del("foo")) {
   13447           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13448             :                          __location__);
   13449           0 :                 return False;
   13450             :         }
   13451             : 
   13452           1 :         if (gencache_get("foo", talloc_tos(), &val, &tm)) {
   13453           0 :                 d_printf("%s: gencache_get() on deleted entry "
   13454             :                          "succeeded\n", __location__);
   13455           0 :                 return False;
   13456             :         }
   13457             : 
   13458           1 :         blob = data_blob_string_const_null("bar");
   13459           1 :         tm = time(NULL) + 60;
   13460             : 
   13461           1 :         if (!gencache_set_data_blob("foo", blob, tm)) {
   13462           0 :                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
   13463           0 :                 return False;
   13464             :         }
   13465             : 
   13466           1 :         if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13467           0 :                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
   13468           0 :                 return False;
   13469             :         }
   13470             : 
   13471           1 :         if (strcmp((const char *)blob.data, "bar") != 0) {
   13472           0 :                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
   13473           0 :                          __location__, (const char *)blob.data, "bar");
   13474           0 :                 data_blob_free(&blob);
   13475           0 :                 return False;
   13476             :         }
   13477             : 
   13478           1 :         data_blob_free(&blob);
   13479             : 
   13480           1 :         if (!gencache_del("foo")) {
   13481           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13482           0 :                 return False;
   13483             :         }
   13484           1 :         if (gencache_del("foo")) {
   13485           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13486             :                          __location__);
   13487           0 :                 return False;
   13488             :         }
   13489             : 
   13490           1 :         if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13491           0 :                 d_printf("%s: gencache_get_data_blob() on deleted entry "
   13492             :                          "succeeded\n", __location__);
   13493           0 :                 return False;
   13494             :         }
   13495             : 
   13496           1 :         v = 1;
   13497           1 :         blob.data = (uint8_t *)&v;
   13498           1 :         blob.length = sizeof(v);
   13499             : 
   13500           1 :         if (!gencache_set_data_blob("blob", blob, tm)) {
   13501           0 :                 d_printf("%s: gencache_set_data_blob() failed\n",
   13502             :                          __location__);
   13503           0 :                 return false;
   13504             :         }
   13505           1 :         if (gencache_get("blob", talloc_tos(), &val, &tm)) {
   13506           0 :                 d_printf("%s: gencache_get succeeded\n", __location__);
   13507           0 :                 return false;
   13508             :         }
   13509             : 
   13510           0 :         return True;
   13511             : }
   13512             : 
   13513           1 : static bool rbt_testflags(struct db_context *db, const char *key,
   13514             :                           const char *value)
   13515             : {
   13516           1 :         bool ret = false;
   13517           1 :         NTSTATUS status;
   13518           1 :         struct db_record *rec;
   13519             : 
   13520           1 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13521           1 :         if (rec == NULL) {
   13522           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13523           0 :                 goto done;
   13524             :         }
   13525             : 
   13526           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13527           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   13528           0 :                 d_fprintf(stderr, "store TDB_MODIFY unexpected status: %s\n",
   13529             :                           nt_errstr(status));
   13530           0 :                 goto done;
   13531             :         }
   13532             : 
   13533           1 :         status = dbwrap_record_store(rec, string_tdb_data("overwriteme"),
   13534             :                                      TDB_INSERT);
   13535           1 :         if (!NT_STATUS_IS_OK(status)) {
   13536           0 :                 d_fprintf(stderr, "store TDB_INSERT failed: %s\n",
   13537             :                           nt_errstr(status));
   13538           0 :                 goto done;
   13539             :         }
   13540             : 
   13541           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_INSERT);
   13542           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
   13543           0 :                 d_fprintf(stderr, "store TDB_INSERT unexpected status: %s\n",
   13544             :                           nt_errstr(status));
   13545           0 :                 goto done;
   13546             :         }
   13547             : 
   13548           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13549           1 :         if (!NT_STATUS_IS_OK(status)) {
   13550           0 :                 d_fprintf(stderr, "store TDB_MODIFY failed: %s\n",
   13551             :                           nt_errstr(status));
   13552           0 :                 goto done;
   13553             :         }
   13554             : 
   13555           0 :         ret = true;
   13556           1 : done:
   13557           1 :         TALLOC_FREE(rec);
   13558           1 :         return ret;
   13559             : }
   13560             : 
   13561        1998 : static bool rbt_testval(struct db_context *db, const char *key,
   13562             :                         const char *value)
   13563             : {
   13564        1998 :         struct db_record *rec;
   13565        1998 :         TDB_DATA data = string_tdb_data(value);
   13566        1998 :         bool ret = false;
   13567        1998 :         NTSTATUS status;
   13568        1998 :         TDB_DATA dbvalue;
   13569             : 
   13570        1998 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13571        1998 :         if (rec == NULL) {
   13572           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13573           0 :                 goto done;
   13574             :         }
   13575        1998 :         status = dbwrap_record_store(rec, data, 0);
   13576        1998 :         if (!NT_STATUS_IS_OK(status)) {
   13577           0 :                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
   13578           0 :                 goto done;
   13579             :         }
   13580        1998 :         TALLOC_FREE(rec);
   13581             : 
   13582        1998 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13583        1998 :         if (rec == NULL) {
   13584           0 :                 d_fprintf(stderr, "second fetch_locked failed\n");
   13585           0 :                 goto done;
   13586             :         }
   13587             : 
   13588        1998 :         dbvalue = dbwrap_record_get_value(rec);
   13589        1998 :         if ((dbvalue.dsize != data.dsize)
   13590        1998 :             || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
   13591           0 :                 d_fprintf(stderr, "Got wrong data back\n");
   13592           0 :                 goto done;
   13593             :         }
   13594             : 
   13595           0 :         ret = true;
   13596        1998 :  done:
   13597        1998 :         TALLOC_FREE(rec);
   13598        1998 :         return ret;
   13599             : }
   13600             : 
   13601        1000 : static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
   13602             : {
   13603        1000 :         int *count2 = (int *)private_data;
   13604        1000 :         (*count2)++;
   13605        1000 :         return 0;
   13606             : }
   13607             : 
   13608        1000 : static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
   13609             : {
   13610        1000 :         int *count2 = (int *)private_data;
   13611        1000 :         (*count2)++;
   13612        1000 :         dbwrap_record_delete(rec);
   13613        1000 :         return 0;
   13614             : }
   13615             : 
   13616           1 : static bool run_local_rbtree(int dummy)
   13617             : {
   13618           1 :         struct db_context *db;
   13619           1 :         bool ret = false;
   13620           1 :         int i;
   13621           1 :         NTSTATUS status;
   13622           1 :         int count = 0;
   13623           1 :         int count2 = 0;
   13624             : 
   13625           1 :         db = db_open_rbt(NULL);
   13626             : 
   13627           1 :         if (db == NULL) {
   13628           0 :                 d_fprintf(stderr, "db_open_rbt failed\n");
   13629           0 :                 return false;
   13630             :         }
   13631             : 
   13632           1 :         if (!rbt_testflags(db, "firstkey", "firstval")) {
   13633           0 :                 goto done;
   13634             :         }
   13635             : 
   13636        1000 :         for (i = 0; i < 999; i++) {
   13637         999 :                 char key[sizeof("key-9223372036854775807-1234")];
   13638         999 :                 char value[sizeof("value-9223372036854775807-1234")];
   13639             : 
   13640         999 :                 snprintf(key, sizeof(key), "key%ld-%d", random(), i);
   13641         999 :                 snprintf(value, sizeof(value) ,"value%ld-%d", random(), i);
   13642             : 
   13643         999 :                 if (!rbt_testval(db, key, value)) {
   13644           0 :                         goto done;
   13645             :                 }
   13646             : 
   13647         999 :                 snprintf(value, sizeof(value) ,"value%ld-%d", random(), i + 1);
   13648             : 
   13649         999 :                 if (!rbt_testval(db, key, value)) {
   13650           0 :                         goto done;
   13651             :                 }
   13652             :         }
   13653             : 
   13654           1 :         ret = true;
   13655           1 :         count = 0; count2 = 0;
   13656           1 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13657             :                                       &count2, &count);
   13658           1 :         printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13659           1 :         if ((count != count2) || (count != 1000)) {
   13660           0 :                 ret = false;
   13661             :         }
   13662           1 :         count = 0; count2 = 0;
   13663           1 :         status = dbwrap_traverse(db, local_rbtree_traverse_delete,
   13664             :                                  &count2, &count);
   13665           1 :         printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13666           1 :         if ((count != count2) || (count != 1000)) {
   13667           0 :                 ret = false;
   13668             :         }
   13669           1 :         count = 0; count2 = 0;
   13670           1 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13671             :                                       &count2, &count);
   13672           1 :         printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13673           1 :         if ((count != count2) || (count != 0)) {
   13674           0 :                 ret = false;
   13675             :         }
   13676             : 
   13677           1 :  done:
   13678           1 :         TALLOC_FREE(db);
   13679           1 :         return ret;
   13680             : }
   13681             : 
   13682             : 
   13683             : /*
   13684             :   local test for character set functions
   13685             : 
   13686             :   This is a very simple test for the functionality in convert_string_error()
   13687             :  */
   13688           1 : static bool run_local_convert_string(int dummy)
   13689             : {
   13690           1 :         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
   13691           1 :         const char *test_strings[2] = { "March", "M\303\244rz" };
   13692           1 :         char dst[7];
   13693           1 :         int i;
   13694             : 
   13695           3 :         for (i=0; i<2; i++) {
   13696           2 :                 const char *str = test_strings[i];
   13697           2 :                 int len = strlen(str);
   13698           2 :                 size_t converted_size;
   13699           2 :                 bool ret;
   13700             : 
   13701           2 :                 memset(dst, 'X', sizeof(dst));
   13702             : 
   13703             :                 /* first try with real source length */
   13704           2 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13705             :                                            str, len,
   13706             :                                            dst, sizeof(dst),
   13707             :                                            &converted_size);
   13708           2 :                 if (ret != true) {
   13709           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13710           0 :                         goto failed;
   13711             :                 }
   13712             : 
   13713           2 :                 if (converted_size != len) {
   13714           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13715             :                                   str, len, (int)converted_size);
   13716           0 :                         goto failed;
   13717             :                 }
   13718             : 
   13719           2 :                 if (strncmp(str, dst, converted_size) != 0) {
   13720           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13721           0 :                         goto failed;
   13722             :                 }
   13723             : 
   13724           2 :                 if (strlen(str) != converted_size) {
   13725           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13726           0 :                                   (int)strlen(str), (int)converted_size);
   13727           0 :                         goto failed;
   13728             :                 }
   13729             : 
   13730           2 :                 if (dst[converted_size] != 'X') {
   13731           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13732           0 :                         goto failed;
   13733             :                 }
   13734             : 
   13735             :                 /* now with srclen==-1, this causes the nul to be
   13736             :                  * converted too */
   13737           2 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13738             :                                            str, -1,
   13739             :                                            dst, sizeof(dst),
   13740             :                                            &converted_size);
   13741           2 :                 if (ret != true) {
   13742           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13743           0 :                         goto failed;
   13744             :                 }
   13745             : 
   13746           2 :                 if (converted_size != len+1) {
   13747           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13748             :                                   str, len, (int)converted_size);
   13749           0 :                         goto failed;
   13750             :                 }
   13751             : 
   13752           2 :                 if (strncmp(str, dst, converted_size) != 0) {
   13753           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13754           0 :                         goto failed;
   13755             :                 }
   13756             : 
   13757           2 :                 if (len+1 != converted_size) {
   13758           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13759             :                                   len+1, (int)converted_size);
   13760           0 :                         goto failed;
   13761             :                 }
   13762             : 
   13763           2 :                 if (dst[converted_size] != 'X') {
   13764           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13765           0 :                         goto failed;
   13766             :                 }
   13767             : 
   13768             :         }
   13769             : 
   13770             : 
   13771           1 :         TALLOC_FREE(tmp_ctx);
   13772           0 :         return true;
   13773           0 : failed:
   13774           0 :         TALLOC_FREE(tmp_ctx);
   13775           0 :         return false;
   13776             : }
   13777             : 
   13778           1 : static bool run_local_string_to_sid(int dummy) {
   13779           1 :         struct dom_sid sid;
   13780             : 
   13781           1 :         if (string_to_sid(&sid, "S--1-5-32-545")) {
   13782           0 :                 printf("allowing S--1-5-32-545\n");
   13783           0 :                 return false;
   13784             :         }
   13785           1 :         if (string_to_sid(&sid, "S-1-5-32-+545")) {
   13786           0 :                 printf("allowing S-1-5-32-+545\n");
   13787           0 :                 return false;
   13788             :         }
   13789           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")) {
   13790           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");
   13791           0 :                 return false;
   13792             :         }
   13793           1 :         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
   13794           0 :                 printf("allowing S-1-5-32-545-abc\n");
   13795           0 :                 return false;
   13796             :         }
   13797           1 :         if (string_to_sid(&sid, "S-300-5-32-545")) {
   13798           0 :                 printf("allowing S-300-5-32-545\n");
   13799           0 :                 return false;
   13800             :         }
   13801           1 :         if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
   13802           0 :                 printf("allowing S-1-0xfffffffffffffe-32-545\n");
   13803           0 :                 return false;
   13804             :         }
   13805           1 :         if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
   13806           0 :                 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
   13807           0 :                 return false;
   13808             :         }
   13809           1 :         if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
   13810           0 :                 printf("could not parse S-1-0xfffffffffffe-32-545\n");
   13811           0 :                 return false;
   13812             :         }
   13813           1 :         if (!string_to_sid(&sid, "S-1-5-32-545")) {
   13814           0 :                 printf("could not parse S-1-5-32-545\n");
   13815           0 :                 return false;
   13816             :         }
   13817           1 :         if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
   13818           0 :                 struct dom_sid_buf buf;
   13819           0 :                 printf("mis-parsed S-1-5-32-545 as %s\n",
   13820             :                        dom_sid_str_buf(&sid, &buf));
   13821           0 :                 return false;
   13822             :         }
   13823           0 :         return true;
   13824             : }
   13825             : 
   13826           3 : static bool sid_to_string_test(const char *expected) {
   13827           3 :         char *str;
   13828           3 :         bool res = true;
   13829           3 :         struct dom_sid sid;
   13830             : 
   13831           3 :         if (!string_to_sid(&sid, expected)) {
   13832           0 :                 printf("could not parse %s\n", expected);
   13833           0 :                 return false;
   13834             :         }
   13835             : 
   13836           3 :         str = dom_sid_string(NULL, &sid);
   13837           3 :         if (strcmp(str, expected)) {
   13838           0 :                 printf("Comparison failed (%s != %s)\n", str, expected);
   13839           0 :                 res = false;
   13840             :         }
   13841           3 :         TALLOC_FREE(str);
   13842           3 :         return res;
   13843             : }
   13844             : 
   13845           1 : static bool run_local_sid_to_string(int dummy) {
   13846           1 :         if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
   13847           0 :                 return false;
   13848           1 :         if (!sid_to_string_test("S-1-545"))
   13849           0 :                 return false;
   13850           1 :         if (!sid_to_string_test("S-255-3840-1-1-1-1"))
   13851           0 :                 return false;
   13852           0 :         return true;
   13853             : }
   13854             : 
   13855           1 : static bool run_local_binary_to_sid(int dummy) {
   13856           1 :         ssize_t ret;
   13857           1 :         struct dom_sid *sid = talloc(NULL, struct dom_sid);
   13858           1 :         static const uint8_t good_binary_sid[] = {
   13859             :                 0x1, /* revision number */
   13860             :                 15, /* num auths */
   13861             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13862             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13863             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13864             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13865             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13866             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13867             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13868             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13869             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13870             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13871             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13872             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13873             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13874             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13875             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13876             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13877             :         };
   13878             : 
   13879           1 :         static const uint8_t long_binary_sid[] = {
   13880             :                 0x1, /* revision number */
   13881             :                 15, /* num auths */
   13882             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13883             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13884             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13885             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13886             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13887             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13888             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13889             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13890             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13891             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13892             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13893             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13894             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13895             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13896             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13897             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13898             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13899             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13900             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13901             :         };
   13902             : 
   13903           1 :         static const uint8_t long_binary_sid2[] = {
   13904             :                 0x1, /* revision number */
   13905             :                 32, /* num auths */
   13906             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13907             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13908             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13909             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13910             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13911             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13912             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13913             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13914             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13915             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13916             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13917             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13918             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13919             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13920             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13921             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13922             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13923             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13924             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13925             :                 0x1, 0x1, 0x1, 0x1, /* auth[18] */
   13926             :                 0x1, 0x1, 0x1, 0x1, /* auth[19] */
   13927             :                 0x1, 0x1, 0x1, 0x1, /* auth[20] */
   13928             :                 0x1, 0x1, 0x1, 0x1, /* auth[21] */
   13929             :                 0x1, 0x1, 0x1, 0x1, /* auth[22] */
   13930             :                 0x1, 0x1, 0x1, 0x1, /* auth[23] */
   13931             :                 0x1, 0x1, 0x1, 0x1, /* auth[24] */
   13932             :                 0x1, 0x1, 0x1, 0x1, /* auth[25] */
   13933             :                 0x1, 0x1, 0x1, 0x1, /* auth[26] */
   13934             :                 0x1, 0x1, 0x1, 0x1, /* auth[27] */
   13935             :                 0x1, 0x1, 0x1, 0x1, /* auth[28] */
   13936             :                 0x1, 0x1, 0x1, 0x1, /* auth[29] */
   13937             :                 0x1, 0x1, 0x1, 0x1, /* auth[30] */
   13938             :                 0x1, 0x1, 0x1, 0x1, /* auth[31] */
   13939             :         };
   13940             : 
   13941           1 :         ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid);
   13942           1 :         if (ret == -1) {
   13943           0 :                 return false;
   13944             :         }
   13945           1 :         ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid);
   13946           1 :         if (ret != -1) {
   13947           0 :                 return false;
   13948             :         }
   13949           1 :         ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid);
   13950           1 :         if (ret != -1) {
   13951           0 :                 return false;
   13952             :         }
   13953           0 :         return true;
   13954             : }
   13955             : 
   13956             : /* Split a path name into filename and stream name components. Canonicalise
   13957             :  * such that an implicit $DATA token is always explicit.
   13958             :  *
   13959             :  * The "specification" of this function can be found in the
   13960             :  * run_local_stream_name() function in torture.c, I've tried those
   13961             :  * combinations against a W2k3 server.
   13962             :  */
   13963             : 
   13964           8 : static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
   13965             :                                        char **pbase, char **pstream)
   13966             : {
   13967           8 :         char *base = NULL;
   13968           8 :         char *stream = NULL;
   13969           8 :         char *sname; /* stream name */
   13970           8 :         const char *stype; /* stream type */
   13971             : 
   13972           8 :         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
   13973             : 
   13974           8 :         sname = strchr_m(fname, ':');
   13975             : 
   13976           8 :         if (sname == NULL) {
   13977           1 :                 if (pbase != NULL) {
   13978           1 :                         base = talloc_strdup(mem_ctx, fname);
   13979           1 :                         NT_STATUS_HAVE_NO_MEMORY(base);
   13980             :                 }
   13981           1 :                 goto done;
   13982             :         }
   13983             : 
   13984           7 :         if (pbase != NULL) {
   13985           7 :                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
   13986           7 :                 NT_STATUS_HAVE_NO_MEMORY(base);
   13987             :         }
   13988             : 
   13989           7 :         sname += 1;
   13990             : 
   13991           7 :         stype = strchr_m(sname, ':');
   13992             : 
   13993           7 :         if (stype == NULL) {
   13994           2 :                 sname = talloc_strdup(mem_ctx, sname);
   13995           2 :                 stype = "$DATA";
   13996             :         }
   13997             :         else {
   13998           5 :                 if (strcasecmp_m(stype, ":$DATA") != 0) {
   13999             :                         /*
   14000             :                          * If there is an explicit stream type, so far we only
   14001             :                          * allow $DATA. Is there anything else allowed? -- vl
   14002             :                          */
   14003           3 :                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
   14004           3 :                         TALLOC_FREE(base);
   14005           3 :                         return NT_STATUS_OBJECT_NAME_INVALID;
   14006             :                 }
   14007           2 :                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
   14008           2 :                 stype += 1;
   14009             :         }
   14010             : 
   14011           4 :         if (sname == NULL) {
   14012           0 :                 TALLOC_FREE(base);
   14013           0 :                 return NT_STATUS_NO_MEMORY;
   14014             :         }
   14015             : 
   14016           4 :         if (sname[0] == '\0') {
   14017             :                 /*
   14018             :                  * no stream name, so no stream
   14019             :                  */
   14020           1 :                 goto done;
   14021             :         }
   14022             : 
   14023           3 :         if (pstream != NULL) {
   14024           3 :                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
   14025           3 :                 if (stream == NULL) {
   14026           0 :                         TALLOC_FREE(sname);
   14027           0 :                         TALLOC_FREE(base);
   14028           0 :                         return NT_STATUS_NO_MEMORY;
   14029             :                 }
   14030             :                 /*
   14031             :                  * upper-case the type field
   14032             :                  */
   14033           3 :                 (void)strupper_m(strchr_m(stream, ':')+1);
   14034             :         }
   14035             : 
   14036           0 :  done:
   14037           5 :         if (pbase != NULL) {
   14038           5 :                 *pbase = base;
   14039             :         }
   14040           5 :         if (pstream != NULL) {
   14041           5 :                 *pstream = stream;
   14042             :         }
   14043           5 :         return NT_STATUS_OK;
   14044             : }
   14045             : 
   14046           8 : static bool test_stream_name(const char *fname, const char *expected_base,
   14047             :                              const char *expected_stream,
   14048             :                              NTSTATUS expected_status)
   14049             : {
   14050           8 :         NTSTATUS status;
   14051           8 :         char *base = NULL;
   14052           8 :         char *stream = NULL;
   14053             : 
   14054           8 :         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
   14055           8 :         if (!NT_STATUS_EQUAL(status, expected_status)) {
   14056           0 :                 goto error;
   14057             :         }
   14058             : 
   14059           8 :         if (!NT_STATUS_IS_OK(status)) {
   14060           0 :                 return true;
   14061             :         }
   14062             : 
   14063           5 :         if (base == NULL) goto error;
   14064             : 
   14065           5 :         if (strcmp(expected_base, base) != 0) goto error;
   14066             : 
   14067           5 :         if ((expected_stream != NULL) && (stream == NULL)) goto error;
   14068           5 :         if ((expected_stream == NULL) && (stream != NULL)) goto error;
   14069             : 
   14070           5 :         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
   14071           0 :                 goto error;
   14072             : 
   14073           5 :         TALLOC_FREE(base);
   14074           5 :         TALLOC_FREE(stream);
   14075           0 :         return true;
   14076             : 
   14077           0 :  error:
   14078           0 :         d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
   14079             :                   fname, expected_base ? expected_base : "<NULL>",
   14080             :                   expected_stream ? expected_stream : "<NULL>",
   14081             :                   nt_errstr(expected_status));
   14082           0 :         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
   14083           0 :                   base ? base : "<NULL>", stream ? stream : "<NULL>",
   14084             :                   nt_errstr(status));
   14085           0 :         TALLOC_FREE(base);
   14086           0 :         TALLOC_FREE(stream);
   14087           0 :         return false;
   14088             : }
   14089             : 
   14090           1 : static bool run_local_stream_name(int dummy)
   14091             : {
   14092           1 :         bool ret = true;
   14093             : 
   14094           2 :         ret &= test_stream_name(
   14095           1 :                 "bla", "bla", NULL, NT_STATUS_OK);
   14096           2 :         ret &= test_stream_name(
   14097           1 :                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
   14098           2 :         ret &= test_stream_name(
   14099           1 :                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   14100           2 :         ret &= test_stream_name(
   14101           1 :                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
   14102           2 :         ret &= test_stream_name(
   14103           1 :                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   14104           2 :         ret &= test_stream_name(
   14105           1 :                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
   14106           2 :         ret &= test_stream_name(
   14107           1 :                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
   14108           2 :         ret &= test_stream_name(
   14109           1 :                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
   14110             : 
   14111           1 :         return ret;
   14112             : }
   14113             : 
   14114           2 : static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
   14115             : {
   14116           2 :         if (a.length != b.length) {
   14117           0 :                 printf("a.length=%d != b.length=%d\n",
   14118           0 :                        (int)a.length, (int)b.length);
   14119           0 :                 return false;
   14120             :         }
   14121           2 :         if (memcmp(a.data, b.data, a.length) != 0) {
   14122           0 :                 printf("a.data and b.data differ\n");
   14123           0 :                 return false;
   14124             :         }
   14125           0 :         return true;
   14126             : }
   14127             : 
   14128           1 : static bool run_local_memcache(int dummy)
   14129             : {
   14130           1 :         struct memcache *cache;
   14131           1 :         DATA_BLOB k1, k2, k3, k4, k5;
   14132           1 :         DATA_BLOB d1, d3;
   14133           1 :         DATA_BLOB v1, v3;
   14134             : 
   14135           1 :         TALLOC_CTX *mem_ctx;
   14136           1 :         char *ptr1 = NULL;
   14137           1 :         char *ptr2 = NULL;
   14138           1 :         char *ptr3 = NULL;
   14139             : 
   14140           1 :         char *str1, *str2;
   14141           1 :         size_t size1, size2;
   14142           1 :         bool ret = false;
   14143             : 
   14144           1 :         mem_ctx = talloc_init("foo");
   14145           1 :         if (mem_ctx == NULL) {
   14146           0 :                 return false;
   14147             :         }
   14148             : 
   14149             :         /* STAT_CACHE TESTS */
   14150             : 
   14151           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14152             : 
   14153           1 :         if (cache == NULL) {
   14154           0 :                 printf("memcache_init failed\n");
   14155           0 :                 return false;
   14156             :         }
   14157             : 
   14158           1 :         d1 = data_blob_const("d1", 2);
   14159           1 :         d3 = data_blob_const("d3", 2);
   14160             : 
   14161           1 :         k1 = data_blob_const("d1", 2);
   14162           1 :         k2 = data_blob_const("d2", 2);
   14163           1 :         k3 = data_blob_const("d3", 2);
   14164           1 :         k4 = data_blob_const("d4", 2);
   14165           1 :         k5 = data_blob_const("d5", 2);
   14166             : 
   14167           1 :         memcache_add(cache, STAT_CACHE, k1, d1);
   14168             : 
   14169           1 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
   14170           0 :                 printf("could not find k1\n");
   14171           0 :                 return false;
   14172             :         }
   14173           1 :         if (!data_blob_equal(d1, v1)) {
   14174           0 :                 return false;
   14175             :         }
   14176             : 
   14177           1 :         memcache_add(cache, STAT_CACHE, k1, d3);
   14178             : 
   14179           1 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
   14180           0 :                 printf("could not find replaced k1\n");
   14181           0 :                 return false;
   14182             :         }
   14183           1 :         if (!data_blob_equal(d3, v3)) {
   14184           0 :                 return false;
   14185             :         }
   14186             : 
   14187           1 :         TALLOC_FREE(cache);
   14188             : 
   14189             :         /* GETWD_CACHE TESTS */
   14190           1 :         str1 = talloc_strdup(mem_ctx, "string1");
   14191           1 :         if (str1 == NULL) {
   14192           0 :                 return false;
   14193             :         }
   14194           1 :         ptr2 = str1; /* Keep an alias for comparison. */
   14195             : 
   14196           1 :         str2 = talloc_strdup(mem_ctx, "string2");
   14197           1 :         if (str2 == NULL) {
   14198           0 :                 return false;
   14199             :         }
   14200             : 
   14201           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14202           1 :         if (cache == NULL) {
   14203           0 :                 printf("memcache_init failed\n");
   14204           0 :                 return false;
   14205             :         }
   14206             : 
   14207           1 :         memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
   14208             :         /* str1 == NULL now. */
   14209           1 :         ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   14210           1 :         if (ptr1 == NULL) {
   14211           0 :                 printf("could not find k2\n");
   14212           0 :                 return false;
   14213             :         }
   14214           1 :         if (ptr1 != ptr2) {
   14215           0 :                 printf("fetch of k2 got wrong string\n");
   14216           0 :                 return false;
   14217             :         }
   14218             : 
   14219             :         /* Add a blob to ensure k2 gets purged. */
   14220           1 :         d3 = data_blob_talloc_zero(mem_ctx, 180);
   14221           1 :         memcache_add(cache, STAT_CACHE, k3, d3);
   14222             : 
   14223           1 :         ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   14224           1 :         if (ptr2 != NULL) {
   14225           0 :                 printf("Did find k2, should have been purged\n");
   14226           0 :                 return false;
   14227             :         }
   14228             : 
   14229             :         /*
   14230             :          * Test that talloc size also is accounted in memcache and
   14231             :          * causes purge of other object.
   14232             :          */
   14233             : 
   14234           1 :         str1 = talloc_zero_size(mem_ctx, 100);
   14235           1 :         str2 = talloc_zero_size(mem_ctx, 100);
   14236             : 
   14237           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14238           1 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str1);
   14239             : 
   14240           1 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   14241           1 :         if (ptr3 != NULL) {
   14242           0 :                 printf("Did find k4, should have been purged\n");
   14243           0 :                 return false;
   14244             :         }
   14245             : 
   14246             :         /*
   14247             :          * Test that adding a duplicate non-talloced
   14248             :          * key/value on top of a talloced key/value takes account
   14249             :          * of the talloc_freed value size.
   14250             :          */
   14251           1 :         TALLOC_FREE(cache);
   14252           1 :         TALLOC_FREE(mem_ctx);
   14253             : 
   14254           1 :         mem_ctx = talloc_init("key_replace");
   14255           1 :         if (mem_ctx == NULL) {
   14256           0 :                 return false;
   14257             :         }
   14258             : 
   14259           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   14260           1 :         if (cache == NULL) {
   14261           0 :                 return false;
   14262             :         }
   14263             : 
   14264             :         /*
   14265             :          * Add a 100 byte talloced string. This will
   14266             :          * store a (4 or 8 byte) pointer and record the
   14267             :          * total talloced size.
   14268             :          */
   14269           1 :         str1 = talloc_zero_size(mem_ctx, 100);
   14270           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14271             :         /*
   14272             :          * Now overwrite with a small talloced
   14273             :          * value. This should fit in the existing size
   14274             :          * and the total talloced size should be removed
   14275             :          * from the cache size.
   14276             :          */
   14277           1 :         str1 = talloc_zero_size(mem_ctx, 2);
   14278           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   14279             :         /*
   14280             :          * Now store a 20 byte string. If the
   14281             :          * total talloced size wasn't accounted for
   14282             :          * and removed in the overwrite, then this
   14283             :          * will evict k4.
   14284             :          */
   14285           1 :         str2 = talloc_zero_size(mem_ctx, 20);
   14286           1 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str2);
   14287             : 
   14288           1 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   14289           1 :         if (ptr3 == NULL) {
   14290           0 :                 printf("Did not find k4, should not have been purged\n");
   14291           0 :                 return false;
   14292             :         }
   14293             : 
   14294           1 :         TALLOC_FREE(cache);
   14295           1 :         TALLOC_FREE(mem_ctx);
   14296             : 
   14297           1 :         mem_ctx = talloc_init("foo");
   14298           1 :         if (mem_ctx == NULL) {
   14299           0 :                 return false;
   14300             :         }
   14301             : 
   14302           1 :         cache = memcache_init(NULL, 0);
   14303           1 :         if (cache == NULL) {
   14304           0 :                 return false;
   14305             :         }
   14306             : 
   14307           1 :         str1 = talloc_strdup(mem_ctx, "string1");
   14308           1 :         if (str1 == NULL) {
   14309           0 :                 return false;
   14310             :         }
   14311           1 :         str2 = talloc_strdup(mem_ctx, "string2");
   14312           1 :         if (str2 == NULL) {
   14313           0 :                 return false;
   14314             :         }
   14315           1 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14316             :                             data_blob_string_const("torture"), &str1);
   14317           1 :         size1 = talloc_total_size(cache);
   14318             : 
   14319           1 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14320             :                             data_blob_string_const("torture"), &str2);
   14321           1 :         size2 = talloc_total_size(cache);
   14322             : 
   14323           1 :         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
   14324             : 
   14325           1 :         if (size2 > size1) {
   14326           0 :                 printf("memcache leaks memory!\n");
   14327           0 :                 goto fail;
   14328             :         }
   14329             : 
   14330           0 :         ret = true;
   14331           1 :  fail:
   14332           1 :         TALLOC_FREE(cache);
   14333           1 :         return ret;
   14334             : }
   14335             : 
   14336         200 : static void wbclient_done(struct tevent_req *req)
   14337             : {
   14338           0 :         wbcErr wbc_err;
   14339           0 :         struct winbindd_response *wb_resp;
   14340         200 :         int *i = (int *)tevent_req_callback_data_void(req);
   14341             : 
   14342         200 :         wbc_err = wb_trans_recv(req, req, &wb_resp);
   14343         200 :         TALLOC_FREE(req);
   14344         200 :         *i += 1;
   14345         200 :         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
   14346         200 : }
   14347             : 
   14348           2 : static bool run_wbclient_multi_ping(int dummy)
   14349             : {
   14350           0 :         struct tevent_context *ev;
   14351           0 :         struct wb_context **wb_ctx;
   14352           0 :         struct winbindd_request wb_req;
   14353           2 :         bool result = false;
   14354           0 :         int i, j;
   14355             : 
   14356           2 :         BlockSignals(True, SIGPIPE);
   14357             : 
   14358           2 :         ev = tevent_context_init(talloc_tos());
   14359           2 :         if (ev == NULL) {
   14360           0 :                 goto fail;
   14361             :         }
   14362             : 
   14363           2 :         wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
   14364           2 :         if (wb_ctx == NULL) {
   14365           0 :                 goto fail;
   14366             :         }
   14367             : 
   14368           2 :         ZERO_STRUCT(wb_req);
   14369           2 :         wb_req.cmd = WINBINDD_PING;
   14370             : 
   14371           2 :         d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
   14372             : 
   14373           4 :         for (i=0; i<torture_nprocs; i++) {
   14374           2 :                 wb_ctx[i] = wb_context_init(ev, NULL);
   14375           2 :                 if (wb_ctx[i] == NULL) {
   14376           0 :                         goto fail;
   14377             :                 }
   14378         202 :                 for (j=0; j<torture_numops; j++) {
   14379           0 :                         struct tevent_req *req;
   14380         200 :                         req = wb_trans_send(ev, ev, wb_ctx[i],
   14381         200 :                                             (j % 2) == 0, &wb_req);
   14382         200 :                         if (req == NULL) {
   14383           0 :                                 goto fail;
   14384             :                         }
   14385         200 :                         tevent_req_set_callback(req, wbclient_done, &i);
   14386             :                 }
   14387             :         }
   14388             : 
   14389           2 :         i = 0;
   14390             : 
   14391         818 :         while (i < torture_nprocs * torture_numops) {
   14392         816 :                 tevent_loop_once(ev);
   14393             :         }
   14394             : 
   14395           2 :         result = true;
   14396           2 :  fail:
   14397           2 :         TALLOC_FREE(ev);
   14398           2 :         return result;
   14399             : }
   14400             : 
   14401           0 : static bool dbtrans_inc(struct db_context *db)
   14402             : {
   14403           0 :         struct db_record *rec;
   14404           0 :         uint32_t val;
   14405           0 :         bool ret = false;
   14406           0 :         NTSTATUS status;
   14407           0 :         TDB_DATA value;
   14408             : 
   14409           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14410           0 :         if (rec == NULL) {
   14411           0 :                 printf(__location__ "fetch_lock failed\n");
   14412           0 :                 return false;
   14413             :         }
   14414             : 
   14415           0 :         value = dbwrap_record_get_value(rec);
   14416             : 
   14417           0 :         if (value.dsize != sizeof(uint32_t)) {
   14418           0 :                 printf(__location__ "value.dsize = %d\n",
   14419           0 :                        (int)value.dsize);
   14420           0 :                 goto fail;
   14421             :         }
   14422             : 
   14423           0 :         memcpy(&val, value.dptr, sizeof(val));
   14424           0 :         val += 1;
   14425             : 
   14426           0 :         status = dbwrap_record_store(
   14427             :                 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
   14428           0 :         if (!NT_STATUS_IS_OK(status)) {
   14429           0 :                 printf(__location__ "store failed: %s\n",
   14430             :                        nt_errstr(status));
   14431           0 :                 goto fail;
   14432             :         }
   14433             : 
   14434           0 :         ret = true;
   14435           0 : fail:
   14436           0 :         TALLOC_FREE(rec);
   14437           0 :         return ret;
   14438             : }
   14439             : 
   14440           0 : static bool run_local_dbtrans(int dummy)
   14441             : {
   14442           0 :         struct db_context *db;
   14443           0 :         struct db_record *rec;
   14444           0 :         NTSTATUS status;
   14445           0 :         uint32_t initial;
   14446           0 :         int res;
   14447           0 :         TDB_DATA value;
   14448             : 
   14449           0 :         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
   14450             :                      O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
   14451             :                      DBWRAP_FLAG_NONE);
   14452           0 :         if (db == NULL) {
   14453           0 :                 printf("Could not open transtest.db\n");
   14454           0 :                 return false;
   14455             :         }
   14456             : 
   14457           0 :         res = dbwrap_transaction_start(db);
   14458           0 :         if (res != 0) {
   14459           0 :                 printf(__location__ "transaction_start failed\n");
   14460           0 :                 return false;
   14461             :         }
   14462             : 
   14463           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14464           0 :         if (rec == NULL) {
   14465           0 :                 printf(__location__ "fetch_lock failed\n");
   14466           0 :                 return false;
   14467             :         }
   14468             : 
   14469           0 :         value = dbwrap_record_get_value(rec);
   14470             : 
   14471           0 :         if (value.dptr == NULL) {
   14472           0 :                 initial = 0;
   14473           0 :                 status = dbwrap_record_store(
   14474             :                         rec, make_tdb_data((uint8_t *)&initial,
   14475             :                                            sizeof(initial)),
   14476             :                         0);
   14477           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14478           0 :                         printf(__location__ "store returned %s\n",
   14479             :                                nt_errstr(status));
   14480           0 :                         return false;
   14481             :                 }
   14482             :         }
   14483             : 
   14484           0 :         TALLOC_FREE(rec);
   14485             : 
   14486           0 :         res = dbwrap_transaction_commit(db);
   14487           0 :         if (res != 0) {
   14488           0 :                 printf(__location__ "transaction_commit failed\n");
   14489           0 :                 return false;
   14490             :         }
   14491             : 
   14492           0 :         while (true) {
   14493           0 :                 uint32_t val, val2;
   14494           0 :                 int i;
   14495             : 
   14496           0 :                 res = dbwrap_transaction_start(db);
   14497           0 :                 if (res != 0) {
   14498           0 :                         printf(__location__ "transaction_start failed\n");
   14499           0 :                         break;
   14500             :                 }
   14501             : 
   14502           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
   14503           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14504           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14505             :                                nt_errstr(status));
   14506           0 :                         break;
   14507             :                 }
   14508             : 
   14509           0 :                 for (i=0; i<10; i++) {
   14510           0 :                         if (!dbtrans_inc(db)) {
   14511           0 :                                 return false;
   14512             :                         }
   14513             :                 }
   14514             : 
   14515           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
   14516           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14517           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14518             :                                nt_errstr(status));
   14519           0 :                         break;
   14520             :                 }
   14521             : 
   14522           0 :                 if (val2 != val + 10) {
   14523           0 :                         printf(__location__ "val=%d, val2=%d\n",
   14524             :                                (int)val, (int)val2);
   14525           0 :                         break;
   14526             :                 }
   14527             : 
   14528           0 :                 printf("val2=%d\r", val2);
   14529             : 
   14530           0 :                 res = dbwrap_transaction_commit(db);
   14531           0 :                 if (res != 0) {
   14532           0 :                         printf(__location__ "transaction_commit failed\n");
   14533           0 :                         break;
   14534             :                 }
   14535             :         }
   14536             : 
   14537           0 :         TALLOC_FREE(db);
   14538           0 :         return true;
   14539             : }
   14540             : 
   14541             : /*
   14542             :  * Just a dummy test to be run under a debugger. There's no real way
   14543             :  * to inspect the tevent_poll specific function from outside of
   14544             :  * tevent_poll.c.
   14545             :  */
   14546             : 
   14547           1 : static bool run_local_tevent_poll(int dummy)
   14548             : {
   14549           1 :         struct tevent_context *ev;
   14550           1 :         struct tevent_fd *fd1, *fd2;
   14551           1 :         bool result = false;
   14552             : 
   14553           1 :         ev = tevent_context_init_byname(NULL, "poll");
   14554           1 :         if (ev == NULL) {
   14555           0 :                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
   14556           0 :                 goto fail;
   14557             :         }
   14558             : 
   14559           1 :         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
   14560           1 :         if (fd1 == NULL) {
   14561           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14562           0 :                 goto fail;
   14563             :         }
   14564           1 :         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
   14565           1 :         if (fd2 == NULL) {
   14566           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14567           0 :                 goto fail;
   14568             :         }
   14569           1 :         TALLOC_FREE(fd2);
   14570             : 
   14571           1 :         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
   14572           1 :         if (fd2 == NULL) {
   14573           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14574           0 :                 goto fail;
   14575             :         }
   14576             : 
   14577           0 :         result = true;
   14578           1 : fail:
   14579           1 :         TALLOC_FREE(ev);
   14580           1 :         return result;
   14581             : }
   14582             : 
   14583           1 : static bool run_local_hex_encode_buf(int dummy)
   14584             : {
   14585           1 :         char buf[17];
   14586           1 :         uint8_t src[8];
   14587           1 :         size_t i;
   14588             : 
   14589           9 :         for (i=0; i<sizeof(src); i++) {
   14590           8 :                 src[i] = i;
   14591             :         }
   14592           1 :         hex_encode_buf(buf, src, sizeof(src));
   14593           1 :         if (strcmp(buf, "0001020304050607") != 0) {
   14594           0 :                 return false;
   14595             :         }
   14596           1 :         hex_encode_buf(buf, NULL, 0);
   14597           1 :         if (buf[0] != '\0') {
   14598           0 :                 return false;
   14599             :         }
   14600           0 :         return true;
   14601             : }
   14602             : 
   14603             : static const char *remove_duplicate_addrs2_test_strings_vector[] = {
   14604             :         "0.0.0.0",
   14605             :         "::0",
   14606             :         "1.2.3.1",
   14607             :         "0.0.0.0",
   14608             :         "0.0.0.0",
   14609             :         "1.2.3.2",
   14610             :         "1.2.3.3",
   14611             :         "1.2.3.4",
   14612             :         "1.2.3.5",
   14613             :         "::0",
   14614             :         "1.2.3.6",
   14615             :         "1.2.3.7",
   14616             :         "::0",
   14617             :         "::0",
   14618             :         "::0",
   14619             :         "1.2.3.8",
   14620             :         "1.2.3.9",
   14621             :         "1.2.3.10",
   14622             :         "1.2.3.11",
   14623             :         "1.2.3.12",
   14624             :         "1.2.3.13",
   14625             :         "1001:1111:1111:1000:0:1111:1111:1111",
   14626             :         "1.2.3.1",
   14627             :         "1.2.3.2",
   14628             :         "1.2.3.3",
   14629             :         "1.2.3.12",
   14630             :         "::0",
   14631             :         "::0"
   14632             : };
   14633             : 
   14634             : static const char *remove_duplicate_addrs2_test_strings_result[] = {
   14635             :         "1.2.3.1",
   14636             :         "1.2.3.2",
   14637             :         "1.2.3.3",
   14638             :         "1.2.3.4",
   14639             :         "1.2.3.5",
   14640             :         "1.2.3.6",
   14641             :         "1.2.3.7",
   14642             :         "1.2.3.8",
   14643             :         "1.2.3.9",
   14644             :         "1.2.3.10",
   14645             :         "1.2.3.11",
   14646             :         "1.2.3.12",
   14647             :         "1.2.3.13",
   14648             :         "1001:1111:1111:1000:0:1111:1111:1111"
   14649             : };
   14650             : 
   14651           1 : static bool run_local_remove_duplicate_addrs2(int dummy)
   14652             : {
   14653           1 :         struct samba_sockaddr test_vector[28];
   14654           1 :         size_t count, i;
   14655             : 
   14656             :         /* Construct the sockaddr_storage test vector. */
   14657          29 :         for (i = 0; i < 28; i++) {
   14658          28 :                 struct addrinfo hints;
   14659          28 :                 struct addrinfo *res = NULL;
   14660          28 :                 int ret;
   14661             : 
   14662          28 :                 memset(&hints, '\0', sizeof(hints));
   14663          28 :                 hints.ai_flags = AI_NUMERICHOST;
   14664          28 :                 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
   14665             :                                 NULL,
   14666             :                                 &hints,
   14667             :                                 &res);
   14668          28 :                 if (ret) {
   14669           0 :                         fprintf(stderr, "getaddrinfo failed on [%s]\n",
   14670             :                                 remove_duplicate_addrs2_test_strings_vector[i]);
   14671           0 :                         return false;
   14672             :                 }
   14673          28 :                 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
   14674          28 :                 memcpy(&test_vector[i].u.ss,
   14675          28 :                         res->ai_addr,
   14676          28 :                         res->ai_addrlen);
   14677          28 :                 freeaddrinfo(res);
   14678             :         }
   14679             : 
   14680           1 :         count = remove_duplicate_addrs2(test_vector, i);
   14681             : 
   14682           1 :         if (count != 14) {
   14683           0 :                 fprintf(stderr, "count wrong (%zu) should be 14\n",
   14684             :                         count);
   14685           0 :                 return false;
   14686             :         }
   14687             : 
   14688          15 :         for (i = 0; i < count; i++) {
   14689          14 :                 char addr[INET6_ADDRSTRLEN];
   14690             : 
   14691          14 :                 print_sockaddr(addr, sizeof(addr), &test_vector[i].u.ss);
   14692             : 
   14693          14 :                 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
   14694           0 :                         fprintf(stderr, "mismatch on [%zu] [%s] [%s]\n",
   14695             :                                 i,
   14696             :                                 addr,
   14697             :                                 remove_duplicate_addrs2_test_strings_result[i]);
   14698           0 :                         return false;
   14699             :                 }
   14700             :         }
   14701             : 
   14702           1 :         printf("run_local_remove_duplicate_addrs2: success\n");
   14703           1 :         return true;
   14704             : }
   14705             : 
   14706           0 : static bool run_local_tdb_opener(int dummy)
   14707             : {
   14708           0 :         TDB_CONTEXT *t;
   14709           0 :         unsigned v = 0;
   14710             : 
   14711           0 :         while (1) {
   14712           0 :                 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
   14713             :                              O_RDWR|O_CREAT, 0755);
   14714           0 :                 if (t == NULL) {
   14715           0 :                         perror("tdb_open failed");
   14716           0 :                         return false;
   14717             :                 }
   14718           0 :                 tdb_close(t);
   14719             : 
   14720           0 :                 v += 1;
   14721           0 :                 printf("\r%u", v);
   14722             :         }
   14723             :         return true;
   14724             : }
   14725             : 
   14726           0 : static bool run_local_tdb_writer(int dummy)
   14727             : {
   14728           0 :         TDB_CONTEXT *t;
   14729           0 :         unsigned v = 0;
   14730           0 :         TDB_DATA val;
   14731             : 
   14732           0 :         t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
   14733           0 :         if (t == 0) {
   14734           0 :                 perror("tdb_open failed");
   14735           0 :                 return 1;
   14736             :         }
   14737             : 
   14738           0 :         val.dptr = (uint8_t *)&v;
   14739           0 :         val.dsize = sizeof(v);
   14740             : 
   14741           0 :         while (1) {
   14742           0 :                 TDB_DATA data;
   14743           0 :                 int ret;
   14744             : 
   14745           0 :                 ret = tdb_store(t, val, val, 0);
   14746           0 :                 if (ret != 0) {
   14747           0 :                         printf("%s\n", tdb_errorstr(t));
   14748             :                 }
   14749           0 :                 v += 1;
   14750           0 :                 printf("\r%u", v);
   14751             : 
   14752           0 :                 data = tdb_fetch(t, val);
   14753           0 :                 if (data.dptr != NULL) {
   14754           0 :                         SAFE_FREE(data.dptr);
   14755             :                 }
   14756             :         }
   14757             :         return true;
   14758             : }
   14759             : 
   14760           1 : static bool run_local_canonicalize_path(int dummy)
   14761             : {
   14762           1 :         const char *src[] = {
   14763             :                         "/foo/..",
   14764             :                         "/..",
   14765             :                         "/foo/bar/../baz",
   14766             :                         "/foo/././",
   14767             :                         "/../foo",
   14768             :                         ".././././",
   14769             :                         ".././././../../../boo",
   14770             :                         "./..",
   14771             :                         "/",
   14772             :                         "/../../",
   14773             :                         "/foo/../",
   14774             :                         "/./././",
   14775             :                         "/./././.",
   14776             :                         "/.../././.",
   14777             :                         "/./././.foo",
   14778             :                         "/./././.foo.",
   14779             :                         "/./././foo.",
   14780             :                         "/foo/bar/..",
   14781             :                         "/foo/bar/../baz/",
   14782             :                         "////////////////",
   14783             :                         "/////////./././././.",
   14784             :                         "/./.././../.boo/../baz",
   14785             :                         "/a/component/path",
   14786             :                         "/a/component/path/",
   14787             :                         "/a/component/path/..",
   14788             :                         "/a/component/../path/",
   14789             :                         "///a/./././///component/../////path/",
   14790             :                         NULL
   14791             :                         };
   14792           1 :         const char *dst[] = {
   14793             :                         "/",
   14794             :                         "/",
   14795             :                         "/foo/baz",
   14796             :                         "/foo",
   14797             :                         "/foo",
   14798             :                         "/",
   14799             :                         "/boo",
   14800             :                         "/",
   14801             :                         "/",
   14802             :                         "/",
   14803             :                         "/",
   14804             :                         "/",
   14805             :                         "/",
   14806             :                         "/...",
   14807             :                         "/.foo",
   14808             :                         "/.foo.",
   14809             :                         "/foo.",
   14810             :                         "/foo",
   14811             :                         "/foo/baz",
   14812             :                         "/",
   14813             :                         "/",
   14814             :                         "/baz",
   14815             :                         "/a/component/path",
   14816             :                         "/a/component/path",
   14817             :                         "/a/component",
   14818             :                         "/a/path",
   14819             :                         "/a/path",
   14820             :                         NULL
   14821             :                         };
   14822           1 :         unsigned int i;
   14823             : 
   14824          28 :         for (i = 0; src[i] != NULL; i++) {
   14825          27 :                 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
   14826          27 :                 if (d == NULL) {
   14827           0 :                         perror("talloc fail\n");
   14828           0 :                         return false;
   14829             :                 }
   14830          27 :                 if (strcmp(d, dst[i]) != 0) {
   14831           0 :                         d_fprintf(stderr,
   14832             :                                 "canonicalize mismatch %s -> %s != %s",
   14833             :                                 src[i], d, dst[i]);
   14834           0 :                         return false;
   14835             :                 }
   14836          27 :                 talloc_free(d);
   14837             :         }
   14838           0 :         return true;
   14839             : }
   14840             : struct session_setup_nt1_truncated_state {
   14841             :         uint16_t vwv[13];
   14842             :         uint8_t bytes[20];
   14843             : };
   14844             : 
   14845             : static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq);
   14846             : 
   14847           2 : static struct tevent_req *smb1_session_setup_nt1_truncated_send(
   14848             :                 TALLOC_CTX *mem_ctx,
   14849             :                 struct tevent_context *ev,
   14850             :                 struct smbXcli_conn *conn)
   14851             : {
   14852           2 :         uint16_t *vwv = NULL;
   14853           2 :         uint8_t *bytes = NULL;
   14854           2 :         const char *pass = "12345678";
   14855           2 :         const char *uname = "z";
   14856           2 :         struct session_setup_nt1_truncated_state *state = NULL;
   14857           2 :         struct tevent_req *req = NULL;
   14858           2 :         struct tevent_req *subreq = NULL;
   14859             : 
   14860           2 :         req = tevent_req_create(mem_ctx,
   14861             :                                 &state,
   14862             :                                 struct session_setup_nt1_truncated_state);
   14863           2 :         if (req == NULL) {
   14864           0 :                 return NULL;
   14865             :         }
   14866           2 :         vwv = &state->vwv[0];
   14867           2 :         bytes = &state->bytes[0];
   14868             : 
   14869           2 :         SCVAL(vwv+0,  0, 0xff);
   14870           2 :         SCVAL(vwv+0,  1, 0);
   14871           2 :         SSVAL(vwv+1,  0, 0);
   14872           2 :         SSVAL(vwv+2,  0, 8192);
   14873           2 :         SSVAL(vwv+3,  0, 2);
   14874           2 :         SSVAL(vwv+4,  0, 1);
   14875           2 :         SIVAL(vwv+5,  0, 0);
   14876           2 :         SSVAL(vwv+7,  0, strlen(pass)); /* OEMPasswordLen */
   14877           2 :         SSVAL(vwv+8,  0, 0); /* UnicodePasswordLen */
   14878           2 :         SSVAL(vwv+9,  0, 0); /* reserved */
   14879           2 :         SSVAL(vwv+10, 0, 0); /* reserved */
   14880           2 :         SIVAL(vwv+11, 0, CAP_STATUS32);
   14881             : 
   14882           2 :         memcpy(bytes, pass, strlen(pass));
   14883           2 :         bytes += strlen(pass);
   14884           2 :         memcpy(bytes, uname, strlen(uname)+1);
   14885             : 
   14886           2 :         subreq = smb1cli_req_send(state, ev, conn,
   14887             :                                   SMBsesssetupX,
   14888             :                                   0, /*  additional_flags */
   14889             :                                   0, /*  clear_flags */
   14890             :                                   0, /*  additional_flags2 */
   14891             :                                   0, /*  clear_flags2 */
   14892             :                                   10000, /* timeout_msec */
   14893           2 :                                   getpid(),
   14894             :                                   NULL, /* tcon */
   14895             :                                   NULL, /* session */
   14896             :                                   13, /* wct */
   14897           2 :                                   state->vwv,
   14898           2 :                                   strlen(pass), /* Truncate length at password. */
   14899           2 :                                   state->bytes);
   14900           2 :         if (tevent_req_nomem(subreq, req)) {
   14901           0 :                 return tevent_req_post(req, ev);
   14902             :         }
   14903           2 :         tevent_req_set_callback(subreq,
   14904             :                                 smb1_session_setup_nt1_truncated_done,
   14905             :                                 req);
   14906           2 :         return req;
   14907             : }
   14908             : 
   14909           2 : static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq)
   14910             : {
   14911           0 :         struct tevent_req *req =
   14912           2 :                 tevent_req_callback_data(subreq,
   14913             :                 struct tevent_req);
   14914           0 :         struct session_setup_nt1_truncated_state *state =
   14915           2 :                 tevent_req_data(req,
   14916             :                 struct session_setup_nt1_truncated_state);
   14917           0 :         NTSTATUS status;
   14918           2 :         struct smb1cli_req_expected_response expected[] = {
   14919             :         {
   14920             :                 .status = NT_STATUS_OK,
   14921             :                 .wct    = 3,
   14922             :         },
   14923             :         };
   14924             : 
   14925           2 :         status = smb1cli_req_recv(subreq, state,
   14926             :                                   NULL,
   14927             :                                   NULL,
   14928             :                                   NULL,
   14929             :                                   NULL,
   14930             :                                   NULL, /* pvwv_offset */
   14931             :                                   NULL,
   14932             :                                   NULL,
   14933             :                                   NULL, /* pbytes_offset */
   14934             :                                   NULL,
   14935             :                                   expected, ARRAY_SIZE(expected));
   14936           2 :         TALLOC_FREE(subreq);
   14937           2 :         if (tevent_req_nterror(req, status)) {
   14938           0 :                 return;
   14939             :         }
   14940           2 :         tevent_req_done(req);
   14941             : }
   14942             : 
   14943           2 : static NTSTATUS smb1_session_setup_nt1_truncated_recv(struct tevent_req *req)
   14944             : {
   14945           2 :         return tevent_req_simple_recv_ntstatus(req);
   14946             : }
   14947             : 
   14948           2 : static bool run_smb1_truncated_sesssetup(int dummy)
   14949             : {
   14950           0 :         struct tevent_context *ev;
   14951           0 :         struct tevent_req *req;
   14952           0 :         struct smbXcli_conn *conn;
   14953           0 :         struct sockaddr_storage ss;
   14954           0 :         NTSTATUS status;
   14955           0 :         int fd;
   14956           0 :         bool ok;
   14957             : 
   14958           2 :         printf("Starting send truncated SMB1 sesssetup.\n");
   14959             : 
   14960           2 :         ok = resolve_name(host, &ss, 0x20, true);
   14961           2 :         if (!ok) {
   14962           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   14963           0 :                 return false;
   14964             :         }
   14965             : 
   14966           2 :         status = open_socket_out(&ss, 445, 10000, &fd);
   14967           2 :         if (!NT_STATUS_IS_OK(status)) {
   14968           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   14969             :                           nt_errstr(status));
   14970           0 :                 return false;
   14971             :         }
   14972             : 
   14973           2 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   14974             :                                    NULL, 0, NULL);
   14975           2 :         if (conn == NULL) {
   14976           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   14977           0 :                 return false;
   14978             :         }
   14979             : 
   14980           2 :         status = smbXcli_negprot(conn,
   14981             :                                  0,
   14982             :                                  PROTOCOL_NT1,
   14983             :                                  PROTOCOL_NT1,
   14984             :                                  NULL,
   14985             :                                  NULL,
   14986             :                                  NULL);
   14987           2 :         if (!NT_STATUS_IS_OK(status)) {
   14988           0 :                 d_fprintf(stderr, "smbXcli_negprot failed!\n");
   14989           0 :                 return false;
   14990             :         }
   14991             : 
   14992           2 :         ev = samba_tevent_context_init(talloc_tos());
   14993           2 :         if (ev == NULL) {
   14994           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   14995           0 :                 return false;
   14996             :         }
   14997             : 
   14998           2 :         req = smb1_session_setup_nt1_truncated_send(ev, ev, conn);
   14999           2 :         if (req == NULL) {
   15000           0 :                 d_fprintf(stderr, "smb1_session_setup_nt1_truncated_send failed\n");
   15001           0 :                 return false;
   15002             :         }
   15003             : 
   15004           2 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   15005           2 :         if (!ok) {
   15006           0 :                 d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
   15007             :                         nt_errstr(status));
   15008           0 :                 return false;
   15009             :         }
   15010             : 
   15011           2 :         status = smb1_session_setup_nt1_truncated_recv(req);
   15012           2 :         if (!NT_STATUS_IS_OK(status)) {
   15013           0 :                 d_fprintf(stderr, "smb1_session_setup_nt1_truncated_recv returned "
   15014             :                           "%s, expected NT_STATUS_OK\n",
   15015             :                           nt_errstr(status));
   15016           0 :                 return false;
   15017             :         }
   15018             : 
   15019           2 :         TALLOC_FREE(conn);
   15020           2 :         return true;
   15021             : }
   15022             : 
   15023             : struct smb1_negotiate_exit_state {
   15024             :         int dummy;
   15025             : };
   15026             : 
   15027             : static void smb1_negotiate_exit_done(struct tevent_req *subreq);
   15028             : 
   15029           4 : static struct tevent_req *smb1_negotiate_exit_send(
   15030             :                 TALLOC_CTX *mem_ctx,
   15031             :                 struct tevent_context *ev,
   15032             :                 struct smbXcli_conn *conn)
   15033             : {
   15034           4 :         struct smb1_negotiate_exit_state *state = NULL;
   15035           4 :         struct tevent_req *req = NULL;
   15036           4 :         struct tevent_req *subreq = NULL;
   15037             : 
   15038           4 :         req = tevent_req_create(mem_ctx,
   15039             :                                 &state,
   15040             :                                 struct smb1_negotiate_exit_state);
   15041           4 :         if (req == NULL) {
   15042           0 :                 return NULL;
   15043             :         }
   15044           4 :         subreq = smb1cli_req_send(state, ev, conn,
   15045             :                                   SMBexit,
   15046             :                                   0, /*  additional_flags */
   15047             :                                   0, /*  clear_flags */
   15048             :                                   0, /*  additional_flags2 */
   15049             :                                   0, /*  clear_flags2 */
   15050             :                                   10000, /* timeout_msec */
   15051           4 :                                   getpid(),
   15052             :                                   NULL, /* tcon */
   15053             :                                   NULL, /* session */
   15054             :                                   0, /* wct */
   15055             :                                   NULL,
   15056             :                                   0,
   15057             :                                   NULL);
   15058           4 :         if (tevent_req_nomem(subreq, req)) {
   15059           0 :                 return tevent_req_post(req, ev);
   15060             :         }
   15061           4 :         tevent_req_set_callback(subreq,
   15062             :                                 smb1_negotiate_exit_done,
   15063             :                                 req);
   15064           4 :         return req;
   15065             : }
   15066             : 
   15067           4 : static void smb1_negotiate_exit_done(struct tevent_req *subreq)
   15068             : {
   15069           0 :         struct tevent_req *req =
   15070           4 :                 tevent_req_callback_data(subreq,
   15071             :                 struct tevent_req);
   15072           0 :         struct smb1_negotiate_exit_state *state =
   15073           4 :                 tevent_req_data(req,
   15074             :                 struct smb1_negotiate_exit_state);
   15075           0 :         NTSTATUS status;
   15076           4 :         struct smb1cli_req_expected_response expected[] = {
   15077             :         {
   15078             :                 .status = NT_STATUS_OK,
   15079             :                 .wct    = 0,
   15080             :         },
   15081             :         };
   15082             : 
   15083           4 :         status = smb1cli_req_recv(subreq, state,
   15084             :                                   NULL,
   15085             :                                   NULL,
   15086             :                                   NULL,
   15087             :                                   NULL,
   15088             :                                   NULL, /* pvwv_offset */
   15089             :                                   NULL,
   15090             :                                   NULL,
   15091             :                                   NULL, /* pbytes_offset */
   15092             :                                   NULL,
   15093             :                                   expected, ARRAY_SIZE(expected));
   15094           4 :         TALLOC_FREE(subreq);
   15095           4 :         if (tevent_req_nterror(req, status)) {
   15096           4 :                 return;
   15097             :         }
   15098           0 :         tevent_req_done(req);
   15099             : }
   15100             : 
   15101           4 : static NTSTATUS smb1_negotiate_exit_recv(struct tevent_req *req)
   15102             : {
   15103           4 :         return tevent_req_simple_recv_ntstatus(req);
   15104             : }
   15105             : 
   15106           4 : static bool do_smb1_exit(TALLOC_CTX *mem_ctx,
   15107             :                          struct tevent_context *ev,
   15108             :                          struct smbXcli_conn *conn)
   15109             : {
   15110           0 :         struct tevent_req *req;
   15111           0 :         bool ok;
   15112           0 :         NTSTATUS status;
   15113           4 :         NTSTATUS expected_status = NT_STATUS_DOS(ERRSRV, ERRinvnid);;
   15114             : 
   15115           4 :         req = smb1_negotiate_exit_send(ev, ev, conn);
   15116           4 :         if (req == NULL) {
   15117           0 :                 d_fprintf(stderr, "smb1_negotiate_exit_send failed\n");
   15118           0 :                 return false;
   15119             :         }
   15120             : 
   15121           4 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   15122           4 :         if (!ok) {
   15123           0 :                 d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
   15124             :                         nt_errstr(status));
   15125           0 :                 return false;
   15126             :         }
   15127             : 
   15128           4 :         status = smb1_negotiate_exit_recv(req);
   15129           4 :         if (!NT_STATUS_EQUAL(status, expected_status)) {
   15130           0 :                 d_fprintf(stderr, "smb1_negotiate_exit_recv returned "
   15131             :                           "%s, expected ERRSRV, ERRinvnid\n",
   15132             :                           nt_errstr(status));
   15133           0 :                 return false;
   15134             :         }
   15135           4 :         return true;
   15136             : }
   15137             : 
   15138           2 : static bool run_smb1_negotiate_exit(int dummy)
   15139             : {
   15140           0 :         struct tevent_context *ev;
   15141           0 :         struct smbXcli_conn *conn;
   15142           0 :         struct sockaddr_storage ss;
   15143           0 :         NTSTATUS status;
   15144           0 :         int fd;
   15145           0 :         bool ok;
   15146             : 
   15147           2 :         printf("Starting send SMB1 negotiate+exit.\n");
   15148             : 
   15149           2 :         ok = resolve_name(host, &ss, 0x20, true);
   15150           2 :         if (!ok) {
   15151           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   15152           0 :                 return false;
   15153             :         }
   15154             : 
   15155           2 :         status = open_socket_out(&ss, 445, 10000, &fd);
   15156           2 :         if (!NT_STATUS_IS_OK(status)) {
   15157           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   15158             :                           nt_errstr(status));
   15159           0 :                 return false;
   15160             :         }
   15161             : 
   15162           2 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   15163             :                                    NULL, 0, NULL);
   15164           2 :         if (conn == NULL) {
   15165           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   15166           0 :                 return false;
   15167             :         }
   15168             : 
   15169           2 :         status = smbXcli_negprot(conn,
   15170             :                                  0,
   15171             :                                  PROTOCOL_NT1,
   15172             :                                  PROTOCOL_NT1,
   15173             :                                  NULL,
   15174             :                                  NULL,
   15175             :                                  NULL);
   15176           2 :         if (!NT_STATUS_IS_OK(status)) {
   15177           0 :                 d_fprintf(stderr, "smbXcli_negprot failed!\n");
   15178           0 :                 return false;
   15179             :         }
   15180             : 
   15181           2 :         ev = samba_tevent_context_init(talloc_tos());
   15182           2 :         if (ev == NULL) {
   15183           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   15184           0 :                 return false;
   15185             :         }
   15186             : 
   15187             :         /*
   15188             :          * Call do_smb1_exit twice to catch a server crash, the
   15189             :          * server sends the first return code then crashes.
   15190             :          */
   15191           2 :         ok = do_smb1_exit(ev, ev, conn);
   15192           2 :         if (!ok) {
   15193           0 :                 d_fprintf(stderr, "do_smb1_exit (1) failed\n");
   15194           0 :                 return false;
   15195             :         }
   15196           2 :         ok = do_smb1_exit(ev, ev, conn);
   15197           2 :         if (!ok) {
   15198           0 :                 d_fprintf(stderr, "do_smb1_exit (2) failed\n");
   15199           0 :                 return false;
   15200             :         }
   15201             : 
   15202           2 :         TALLOC_FREE(conn);
   15203           2 :         return true;
   15204             : }
   15205             : 
   15206           2 : static bool run_smb1_negotiate_tcon(int dummy)
   15207             : {
   15208           2 :         struct cli_state *cli = NULL;
   15209           2 :         uint16_t cnum = 0;
   15210           2 :         uint16_t max_xmit = 0;
   15211           0 :         NTSTATUS status;
   15212             : 
   15213           2 :         printf("Starting send SMB1 negotiate+tcon.\n");
   15214           2 :         cli = open_nbt_connection();
   15215           2 :         if (cli == NULL) {
   15216           0 :                 d_fprintf(stderr, "open_nbt_connection failed!\n");
   15217           0 :                 return false;
   15218             :         }
   15219           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   15220             : 
   15221           2 :         status = smbXcli_negprot(cli->conn,
   15222             :                                  0,
   15223             :                                  PROTOCOL_NT1,
   15224             :                                  PROTOCOL_NT1,
   15225             :                                  NULL,
   15226             :                                  NULL,
   15227             :                                  NULL);
   15228           2 :         if (!NT_STATUS_IS_OK(status)) {
   15229           0 :                 d_fprintf(stderr, "smbXcli_negprot failed %s!\n",
   15230             :                         nt_errstr(status));
   15231           0 :                 return false;
   15232             :         }
   15233           2 :         status = cli_raw_tcon(cli,
   15234             :                               share,
   15235             :                               "",
   15236             :                               "?????",
   15237             :                               &max_xmit,
   15238             :                               &cnum);
   15239           2 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
   15240           0 :                 d_fprintf(stderr, "cli_raw_tcon failed - got %s "
   15241             :                         "(should get NT_STATUS_ACCESS_DENIED)!\n",
   15242             :                         nt_errstr(status));
   15243           0 :                 return false;
   15244             :         }
   15245           2 :         return true;
   15246             : }
   15247             : 
   15248           0 : static bool run_ign_bad_negprot(int dummy)
   15249             : {
   15250           0 :         struct tevent_context *ev;
   15251           0 :         struct tevent_req *req;
   15252           0 :         struct smbXcli_conn *conn;
   15253           0 :         struct sockaddr_storage ss;
   15254           0 :         NTSTATUS status;
   15255           0 :         int fd;
   15256           0 :         bool ok;
   15257             : 
   15258           0 :         printf("starting ignore bad negprot\n");
   15259             : 
   15260           0 :         ok = resolve_name(host, &ss, 0x20, true);
   15261           0 :         if (!ok) {
   15262           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   15263           0 :                 return false;
   15264             :         }
   15265             : 
   15266           0 :         status = open_socket_out(&ss, 445, 10000, &fd);
   15267           0 :         if (!NT_STATUS_IS_OK(status)) {
   15268           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   15269             :                           nt_errstr(status));
   15270           0 :                 return false;
   15271             :         }
   15272             : 
   15273           0 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   15274             :                                    NULL, 0, NULL);
   15275           0 :         if (conn == NULL) {
   15276           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   15277           0 :                 return false;
   15278             :         }
   15279             : 
   15280           0 :         status = smbXcli_negprot(conn,
   15281             :                                  0,
   15282             :                                  PROTOCOL_CORE,
   15283             :                                  PROTOCOL_CORE,
   15284             :                                  NULL,
   15285             :                                  NULL,
   15286             :                                  NULL);
   15287           0 :         if (NT_STATUS_IS_OK(status)) {
   15288           0 :                 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
   15289           0 :                 return false;
   15290             :         }
   15291             : 
   15292           0 :         ev = samba_tevent_context_init(talloc_tos());
   15293           0 :         if (ev == NULL) {
   15294           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   15295           0 :                 return false;
   15296             :         }
   15297             : 
   15298           0 :         req = smb1cli_session_setup_nt1_send(
   15299           0 :                 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
   15300             :                 data_blob_null, data_blob_null, 0x40,
   15301             :                 "Windows 2000 2195", "Windows 2000 5.0");
   15302           0 :         if (req == NULL) {
   15303           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
   15304           0 :                 return false;
   15305             :         }
   15306             : 
   15307           0 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   15308           0 :         if (!ok) {
   15309           0 :                 d_fprintf(stderr, "tevent_req_poll failed\n");
   15310           0 :                 return false;
   15311             :         }
   15312             : 
   15313           0 :         status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
   15314             :                                                 NULL, NULL);
   15315           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
   15316           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
   15317             :                           "%s, expected NT_STATUS_CONNECTION_RESET\n",
   15318             :                           nt_errstr(status));
   15319           0 :                 return false;
   15320             :         }
   15321             : 
   15322           0 :         TALLOC_FREE(conn);
   15323             : 
   15324           0 :         printf("starting ignore bad negprot\n");
   15325             : 
   15326           0 :         return true;
   15327             : }
   15328             : 
   15329             : 
   15330          16 : static double create_procs(bool (*fn)(int), bool *result)
   15331             : {
   15332           0 :         int i, status;
   15333           0 :         volatile pid_t *child_status;
   15334           0 :         volatile bool *child_status_out;
   15335           0 :         int synccount;
   15336          16 :         int tries = 8;
   15337           0 :         struct timeval start;
   15338             : 
   15339          16 :         synccount = 0;
   15340             : 
   15341          16 :         child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
   15342          16 :         if (!child_status) {
   15343           0 :                 printf("Failed to setup shared memory\n");
   15344           0 :                 return -1;
   15345             :         }
   15346             : 
   15347          16 :         child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
   15348          16 :         if (!child_status_out) {
   15349           0 :                 printf("Failed to setup result status shared memory\n");
   15350           0 :                 return -1;
   15351             :         }
   15352             : 
   15353          32 :         for (i = 0; i < torture_nprocs; i++) {
   15354          16 :                 child_status[i] = 0;
   15355          16 :                 child_status_out[i] = True;
   15356             :         }
   15357             : 
   15358          16 :         start = timeval_current();
   15359             : 
   15360          32 :         for (i=0;i<torture_nprocs;i++) {
   15361          16 :                 procnum = i;
   15362          16 :                 if (fork() == 0) {
   15363           0 :                         pid_t mypid = getpid();
   15364           0 :                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
   15365             : 
   15366           0 :                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
   15367             : 
   15368           0 :                         while (1) {
   15369           0 :                                 if (torture_open_connection(&current_cli, i)) break;
   15370           0 :                                 if (tries-- == 0) {
   15371           0 :                                         printf("pid %d failed to start\n", (int)getpid());
   15372           0 :                                         _exit(1);
   15373             :                                 }
   15374           0 :                                 smb_msleep(10);
   15375             :                         }
   15376             : 
   15377           0 :                         child_status[i] = getpid();
   15378             : 
   15379           0 :                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
   15380             : 
   15381           0 :                         child_status_out[i] = fn(i);
   15382           0 :                         _exit(0);
   15383             :                 }
   15384             :         }
   15385             : 
   15386           0 :         do {
   15387          75 :                 synccount = 0;
   15388         150 :                 for (i=0;i<torture_nprocs;i++) {
   15389          75 :                         if (child_status[i]) synccount++;
   15390             :                 }
   15391          75 :                 if (synccount == torture_nprocs) break;
   15392          59 :                 smb_msleep(10);
   15393          59 :         } while (timeval_elapsed(&start) < 30);
   15394             : 
   15395          16 :         if (synccount != torture_nprocs) {
   15396           0 :                 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
   15397           0 :                 *result = False;
   15398           0 :                 return timeval_elapsed(&start);
   15399             :         }
   15400             : 
   15401             :         /* start the client load */
   15402          16 :         start = timeval_current();
   15403             : 
   15404          32 :         for (i=0;i<torture_nprocs;i++) {
   15405          16 :                 child_status[i] = 0;
   15406             :         }
   15407             : 
   15408          16 :         printf("%d clients started\n", torture_nprocs);
   15409             : 
   15410          32 :         for (i=0;i<torture_nprocs;i++) {
   15411          16 :                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
   15412             :         }
   15413             : 
   15414          16 :         printf("\n");
   15415             : 
   15416          32 :         for (i=0;i<torture_nprocs;i++) {
   15417          16 :                 if (!child_status_out[i]) {
   15418           2 :                         *result = False;
   15419             :                 }
   15420             :         }
   15421          16 :         return timeval_elapsed(&start);
   15422             : }
   15423             : 
   15424             : #define FLAG_MULTIPROC 1
   15425             : 
   15426             : static struct {
   15427             :         const char *name;
   15428             :         bool (*fn)(int);
   15429             :         unsigned flags;
   15430             : } torture_ops[] = {
   15431             :         {
   15432             :                 .name = "FDPASS",
   15433             :                 .fn   = run_fdpasstest,
   15434             :         },
   15435             :         {
   15436             :                 .name = "LOCK1",
   15437             :                 .fn   = run_locktest1,
   15438             :         },
   15439             :         {
   15440             :                 .name = "LOCK2",
   15441             :                 .fn   =  run_locktest2,
   15442             :         },
   15443             :         {
   15444             :                 .name = "LOCK3",
   15445             :                 .fn   =  run_locktest3,
   15446             :         },
   15447             :         {
   15448             :                 .name = "LOCK4",
   15449             :                 .fn   =  run_locktest4,
   15450             :         },
   15451             :         {
   15452             :                 .name = "LOCK5",
   15453             :                 .fn   =  run_locktest5,
   15454             :         },
   15455             :         {
   15456             :                 .name = "LOCK6",
   15457             :                 .fn   =  run_locktest6,
   15458             :         },
   15459             :         {
   15460             :                 .name = "LOCK7",
   15461             :                 .fn   =  run_locktest7,
   15462             :         },
   15463             :         {
   15464             :                 .name = "LOCK8",
   15465             :                 .fn   =  run_locktest8,
   15466             :         },
   15467             :         {
   15468             :                 .name = "LOCK9A",
   15469             :                 .fn   =  run_locktest9a,
   15470             :         },
   15471             :         {
   15472             :                 .name = "LOCK9B",
   15473             :                 .fn   =  run_locktest9b,
   15474             :         },
   15475             :         {
   15476             :                 .name = "LOCK10",
   15477             :                 .fn   =  run_locktest10,
   15478             :         },
   15479             :         {
   15480             :                 .name = "LOCK11",
   15481             :                 .fn   =  run_locktest11,
   15482             :         },
   15483             :         {
   15484             :                 .name = "LOCK12",
   15485             :                 .fn   =  run_locktest12,
   15486             :         },
   15487             :         {
   15488             :                 .name = "LOCK13",
   15489             :                 .fn   =  run_locktest13,
   15490             :         },
   15491             :         {
   15492             :                 .name = "UNLINK",
   15493             :                 .fn   = run_unlinktest,
   15494             :         },
   15495             :         {
   15496             :                 .name = "BROWSE",
   15497             :                 .fn   = run_browsetest,
   15498             :         },
   15499             :         {
   15500             :                 .name = "ATTR",
   15501             :                 .fn   =   run_attrtest,
   15502             :         },
   15503             :         {
   15504             :                 .name = "TRANS2",
   15505             :                 .fn   = run_trans2test,
   15506             :         },
   15507             :         {
   15508             :                 .name  = "MAXFID",
   15509             :                 .fn    = run_maxfidtest,
   15510             :                 .flags = FLAG_MULTIPROC,
   15511             :         },
   15512             :         {
   15513             :                 .name  = "TORTURE",
   15514             :                 .fn    = run_torture,
   15515             :                 .flags = FLAG_MULTIPROC,
   15516             :         },
   15517             :         {
   15518             :                 .name  = "RANDOMIPC",
   15519             :                 .fn    = run_randomipc,
   15520             :         },
   15521             :         {
   15522             :                 .name  = "NEGNOWAIT",
   15523             :                 .fn    = run_negprot_nowait,
   15524             :         },
   15525             :         {
   15526             :                 .name  = "NBENCH",
   15527             :                 .fn    =  run_nbench,
   15528             :         },
   15529             :         {
   15530             :                 .name  = "NBENCH2",
   15531             :                 .fn    = run_nbench2,
   15532             :         },
   15533             :         {
   15534             :                 .name  = "OPLOCK1",
   15535             :                 .fn    =  run_oplock1,
   15536             :         },
   15537             :         {
   15538             :                 .name  = "OPLOCK2",
   15539             :                 .fn    =  run_oplock2,
   15540             :         },
   15541             :         {
   15542             :                 .name  = "OPLOCK4",
   15543             :                 .fn    =  run_oplock4,
   15544             :         },
   15545             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
   15546             :         {
   15547             :                 .name  = "OPLOCK5",
   15548             :                 .fn    =  run_oplock5,
   15549             :         },
   15550             : #endif
   15551             :         {
   15552             :                 .name  = "DIR",
   15553             :                 .fn    =  run_dirtest,
   15554             :         },
   15555             :         {
   15556             :                 .name  = "DIR1",
   15557             :                 .fn    =  run_dirtest1,
   15558             :         },
   15559             :         {
   15560             :                 .name  = "DIR-CREATETIME",
   15561             :                 .fn    =  run_dir_createtime,
   15562             :         },
   15563             :         {
   15564             :                 .name  = "DENY1",
   15565             :                 .fn    =  torture_denytest1,
   15566             :         },
   15567             :         {
   15568             :                 .name  = "DENY2",
   15569             :                 .fn    =  torture_denytest2,
   15570             :         },
   15571             :         {
   15572             :                 .name  = "TCON",
   15573             :                 .fn    =  run_tcon_test,
   15574             :         },
   15575             :         {
   15576             :                 .name  = "TCONDEV",
   15577             :                 .fn    =  run_tcon_devtype_test,
   15578             :         },
   15579             :         {
   15580             :                 .name  = "RW1",
   15581             :                 .fn    =  run_readwritetest,
   15582             :         },
   15583             :         {
   15584             :                 .name  = "RW2",
   15585             :                 .fn    =  run_readwritemulti,
   15586             :                 .flags = FLAG_MULTIPROC
   15587             :         },
   15588             :         {
   15589             :                 .name  = "RW3",
   15590             :                 .fn    =  run_readwritelarge,
   15591             :         },
   15592             :         {
   15593             :                 .name  = "RW-SIGNING",
   15594             :                 .fn    =  run_readwritelarge_signtest,
   15595             :         },
   15596             :         {
   15597             :                 .name  = "OPEN",
   15598             :                 .fn    = run_opentest,
   15599             :         },
   15600             :         {
   15601             :                 .name  = "POSIX",
   15602             :                 .fn    = run_simple_posix_open_test,
   15603             :         },
   15604             :         {
   15605             :                 .name  = "POSIX-APPEND",
   15606             :                 .fn    = run_posix_append,
   15607             :         },
   15608             :         {
   15609             :                 .name  = "POSIX-SYMLINK-ACL",
   15610             :                 .fn    = run_acl_symlink_test,
   15611             :         },
   15612             :         {
   15613             :                 .name  = "POSIX-SYMLINK-EA",
   15614             :                 .fn    = run_ea_symlink_test,
   15615             :         },
   15616             :         {
   15617             :                 .name  = "POSIX-STREAM-DELETE",
   15618             :                 .fn    = run_posix_stream_delete,
   15619             :         },
   15620             :         {
   15621             :                 .name  = "POSIX-OFD-LOCK",
   15622             :                 .fn    = run_posix_ofd_lock_test,
   15623             :         },
   15624             :         {
   15625             :                 .name  = "POSIX-BLOCKING-LOCK",
   15626             :                 .fn    = run_posix_blocking_lock,
   15627             :         },
   15628             :         {
   15629             :                 .name  = "POSIX-MKDIR",
   15630             :                 .fn    = run_posix_mkdir_test,
   15631             :         },
   15632             :         {
   15633             :                 .name  = "POSIX-ACL-OPLOCK",
   15634             :                 .fn    = run_posix_acl_oplock_test,
   15635             :         },
   15636             :         {
   15637             :                 .name  = "POSIX-ACL-SHAREROOT",
   15638             :                 .fn    = run_posix_acl_shareroot_test,
   15639             :         },
   15640             :         {
   15641             :                 .name  = "POSIX-LS-WILDCARD",
   15642             :                 .fn    = run_posix_ls_wildcard_test,
   15643             :         },
   15644             :         {
   15645             :                 .name  = "POSIX-LS-SINGLE",
   15646             :                 .fn    = run_posix_ls_single_test,
   15647             :         },
   15648             :         {
   15649             :                 .name  = "POSIX-READLINK",
   15650             :                 .fn    = run_posix_readlink_test,
   15651             :         },
   15652             :         {
   15653             :                 .name  = "POSIX-STAT",
   15654             :                 .fn    = run_posix_stat_test,
   15655             :         },
   15656             :         {
   15657             :                 .name  = "POSIX-SYMLINK-PARENT",
   15658             :                 .fn    = run_posix_symlink_parent_test,
   15659             :         },
   15660             :         {
   15661             :                 .name  = "POSIX-SYMLINK-CHMOD",
   15662             :                 .fn    = run_posix_symlink_chmod_test,
   15663             :         },
   15664             :         {
   15665             :                 .name  = "POSIX-SYMLINK-RENAME",
   15666             :                 .fn    = run_posix_symlink_rename_test,
   15667             :         },
   15668             :         {
   15669             :                 .name  = "POSIX-DIR-DEFAULT-ACL",
   15670             :                 .fn    = run_posix_dir_default_acl_test,
   15671             :         },
   15672             :         {
   15673             :                 .name  = "POSIX-SYMLINK-GETPATHINFO",
   15674             :                 .fn    = run_posix_symlink_getpathinfo_test,
   15675             :         },
   15676             :         {
   15677             :                 .name  = "POSIX-SYMLINK-SETPATHINFO",
   15678             :                 .fn    = run_posix_symlink_setpathinfo_test,
   15679             :         },
   15680             :         {
   15681             :                 .name  = "WINDOWS-BAD-SYMLINK",
   15682             :                 .fn    = run_symlink_open_test,
   15683             :         },
   15684             :         {
   15685             :                 .name  = "SMB1-WILD-MANGLE-UNLINK",
   15686             :                 .fn    = run_smb1_wild_mangle_unlink_test,
   15687             :         },
   15688             :         {
   15689             :                 .name  = "SMB1-WILD-MANGLE-RENAME",
   15690             :                 .fn    = run_smb1_wild_mangle_rename_test,
   15691             :         },
   15692             :         {
   15693             :                 .name  = "CASE-INSENSITIVE-CREATE",
   15694             :                 .fn    = run_case_insensitive_create,
   15695             :         },
   15696             :         {
   15697             :                 .name  = "ASYNC-ECHO",
   15698             :                 .fn    = run_async_echo,
   15699             :         },
   15700             :         {
   15701             :                 .name  = "UID-REGRESSION-TEST",
   15702             :                 .fn    = run_uid_regression_test,
   15703             :         },
   15704             :         {
   15705             :                 .name  = "SHORTNAME-TEST",
   15706             :                 .fn    = run_shortname_test,
   15707             :         },
   15708             :         {
   15709             :                 .name  = "ADDRCHANGE",
   15710             :                 .fn    = run_addrchange,
   15711             :         },
   15712             : #if 1
   15713             :         {
   15714             :                 .name  = "OPENATTR",
   15715             :                 .fn    = run_openattrtest,
   15716             :         },
   15717             : #endif
   15718             :         {
   15719             :                 .name  = "XCOPY",
   15720             :                 .fn    = run_xcopy,
   15721             :         },
   15722             :         {
   15723             :                 .name  = "RENAME",
   15724             :                 .fn    = run_rename,
   15725             :         },
   15726             :         {
   15727             :                 .name  = "RENAME-ACCESS",
   15728             :                 .fn    = run_rename_access,
   15729             :         },
   15730             :         {
   15731             :                 .name  = "OWNER-RIGHTS",
   15732             :                 .fn    = run_owner_rights,
   15733             :         },
   15734             :         {
   15735             :                 .name  = "DELETE",
   15736             :                 .fn    = run_deletetest,
   15737             :         },
   15738             :         {
   15739             :                 .name  = "DELETE-STREAM",
   15740             :                 .fn    = run_delete_stream,
   15741             :         },
   15742             :         {
   15743             :                 .name  = "DELETE-PRINT",
   15744             :                 .fn    = run_delete_print_test,
   15745             :         },
   15746             :         {
   15747             :                 .name  = "DELETE-LN",
   15748             :                 .fn    = run_deletetest_ln,
   15749             :         },
   15750             :         {
   15751             :                 .name  = "PROPERTIES",
   15752             :                 .fn    = run_properties,
   15753             :         },
   15754             :         {
   15755             :                 .name  = "MANGLE",
   15756             :                 .fn    = torture_mangle,
   15757             :         },
   15758             :         {
   15759             :                 .name  = "MANGLE1",
   15760             :                 .fn    = run_mangle1,
   15761             :         },
   15762             :         {
   15763             :                 .name  = "MANGLE-ILLEGAL",
   15764             :                 .fn    = run_mangle_illegal,
   15765             :         },
   15766             :         {
   15767             :                 .name  = "W2K",
   15768             :                 .fn    = run_w2ktest,
   15769             :         },
   15770             :         {
   15771             :                 .name  = "TRANS2SCAN",
   15772             :                 .fn    = torture_trans2_scan,
   15773             :         },
   15774             :         {
   15775             :                 .name  = "NTTRANSSCAN",
   15776             :                 .fn    = torture_nttrans_scan,
   15777             :         },
   15778             :         {
   15779             :                 .name  = "UTABLE",
   15780             :                 .fn    = torture_utable,
   15781             :         },
   15782             :         {
   15783             :                 .name  = "CASETABLE",
   15784             :                 .fn    = torture_casetable,
   15785             :         },
   15786             :         {
   15787             :                 .name  = "ERRMAPEXTRACT",
   15788             :                 .fn    = run_error_map_extract,
   15789             :         },
   15790             :         {
   15791             :                 .name  = "PIPE_NUMBER",
   15792             :                 .fn    = run_pipe_number,
   15793             :         },
   15794             :         {
   15795             :                 .name  = "TCON2",
   15796             :                 .fn    =  run_tcon2_test,
   15797             :         },
   15798             :         {
   15799             :                 .name  = "IOCTL",
   15800             :                 .fn    =  torture_ioctl_test,
   15801             :         },
   15802             :         {
   15803             :                 .name  = "CHKPATH",
   15804             :                 .fn    =  torture_chkpath_test,
   15805             :         },
   15806             :         {
   15807             :                 .name  = "FDSESS",
   15808             :                 .fn    = run_fdsesstest,
   15809             :         },
   15810             :         {
   15811             :                 .name  = "EATEST",
   15812             :                 .fn    = run_eatest,
   15813             :         },
   15814             :         {
   15815             :                 .name  = "SESSSETUP_BENCH",
   15816             :                 .fn    = run_sesssetup_bench,
   15817             :         },
   15818             :         {
   15819             :                 .name  = "CHAIN1",
   15820             :                 .fn    = run_chain1,
   15821             :         },
   15822             :         {
   15823             :                 .name  = "CHAIN2",
   15824             :                 .fn    = run_chain2,
   15825             :         },
   15826             :         {
   15827             :                 .name  = "CHAIN3",
   15828             :                 .fn    = run_chain3,
   15829             :         },
   15830             :         {
   15831             :                 .name  = "WINDOWS-WRITE",
   15832             :                 .fn    = run_windows_write,
   15833             :         },
   15834             :         {
   15835             :                 .name  = "LARGE_READX",
   15836             :                 .fn    = run_large_readx,
   15837             :         },
   15838             :         {
   15839             :                 .name  = "MSDFS-ATTRIBUTE",
   15840             :                 .fn    = run_msdfs_attribute,
   15841             :         },
   15842             :         {
   15843             :                 .name  = "NTTRANS-CREATE",
   15844             :                 .fn    = run_nttrans_create,
   15845             :         },
   15846             :         {
   15847             :                 .name  = "NTTRANS-FSCTL",
   15848             :                 .fn    = run_nttrans_fsctl,
   15849             :         },
   15850             :         {
   15851             :                 .name  = "CLI_ECHO",
   15852             :                 .fn    = run_cli_echo,
   15853             :         },
   15854             :         {
   15855             :                 .name  = "CLI_SPLICE",
   15856             :                 .fn    = run_cli_splice,
   15857             :         },
   15858             :         {
   15859             :                 .name  = "TLDAP",
   15860             :                 .fn    = run_tldap,
   15861             :         },
   15862             :         {
   15863             :                 .name  = "STREAMERROR",
   15864             :                 .fn    = run_streamerror,
   15865             :         },
   15866             :         {
   15867             :                 .name  = "NOTIFY-BENCH",
   15868             :                 .fn    = run_notify_bench,
   15869             :         },
   15870             :         {
   15871             :                 .name  = "NOTIFY-BENCH2",
   15872             :                 .fn    = run_notify_bench2,
   15873             :         },
   15874             :         {
   15875             :                 .name  = "NOTIFY-BENCH3",
   15876             :                 .fn    = run_notify_bench3,
   15877             :         },
   15878             :         {
   15879             :                 .name  = "BAD-NBT-SESSION",
   15880             :                 .fn    = run_bad_nbt_session,
   15881             :         },
   15882             :         {
   15883             :                 .name  = "IGN-BAD-NEGPROT",
   15884             :                 .fn    = run_ign_bad_negprot,
   15885             :         },
   15886             :         {
   15887             :                 .name  = "SMB-ANY-CONNECT",
   15888             :                 .fn    = run_smb_any_connect,
   15889             :         },
   15890             :         {
   15891             :                 .name  = "NOTIFY-ONLINE",
   15892             :                 .fn    = run_notify_online,
   15893             :         },
   15894             :         {
   15895             :                 .name  = "SMB2-BASIC",
   15896             :                 .fn    = run_smb2_basic,
   15897             :         },
   15898             :         {
   15899             :                 .name  = "SMB2-NEGPROT",
   15900             :                 .fn    = run_smb2_negprot,
   15901             :         },
   15902             :         {
   15903             :                 .name  = "SMB2-ANONYMOUS",
   15904             :                 .fn    = run_smb2_anonymous,
   15905             :         },
   15906             :         {
   15907             :                 .name  = "SMB2-SESSION-RECONNECT",
   15908             :                 .fn    = run_smb2_session_reconnect,
   15909             :         },
   15910             :         {
   15911             :                 .name  = "SMB2-TCON-DEPENDENCE",
   15912             :                 .fn    = run_smb2_tcon_dependence,
   15913             :         },
   15914             :         {
   15915             :                 .name  = "SMB2-MULTI-CHANNEL",
   15916             :                 .fn    = run_smb2_multi_channel,
   15917             :         },
   15918             :         {
   15919             :                 .name  = "SMB2-SESSION-REAUTH",
   15920             :                 .fn    = run_smb2_session_reauth,
   15921             :         },
   15922             :         {
   15923             :                 .name  = "SMB2-FTRUNCATE",
   15924             :                 .fn    = run_smb2_ftruncate,
   15925             :         },
   15926             :         {
   15927             :                 .name  = "SMB2-DIR-FSYNC",
   15928             :                 .fn    = run_smb2_dir_fsync,
   15929             :         },
   15930             :         {
   15931             :                 .name  = "SMB2-PATH-SLASH",
   15932             :                 .fn    = run_smb2_path_slash,
   15933             :         },
   15934             :         {
   15935             :                 .name  = "SMB1-SYSTEM-SECURITY",
   15936             :                 .fn    = run_smb1_system_security,
   15937             :         },
   15938             :         {
   15939             :                 .name  = "SMB2-SACL",
   15940             :                 .fn    = run_smb2_sacl,
   15941             :         },
   15942             :         {
   15943             :                 .name  = "SMB2-QUOTA1",
   15944             :                 .fn    = run_smb2_quota1,
   15945             :         },
   15946             :         {
   15947             :                 .name  = "SMB2-INVALID-PIPENAME",
   15948             :                 .fn    = run_smb2_invalid_pipename,
   15949             :         },
   15950             :         {
   15951             :                 .name  = "SMB2-STREAM-ACL",
   15952             :                 .fn    = run_smb2_stream_acl,
   15953             :         },
   15954             :         {
   15955             :                 .name  = "SMB2-LIST-DIR-ASYNC",
   15956             :                 .fn    = run_list_dir_async_test,
   15957             :         },
   15958             :         {
   15959             :                 .name  = "SMB2-DEL-ON-CLOSE-NONEMPTY",
   15960             :                 .fn    = run_delete_on_close_non_empty,
   15961             :         },
   15962             :         {
   15963             :                 .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-YES",
   15964             :                 .fn    = run_delete_on_close_nonwrite_delete_yes_test,
   15965             :         },
   15966             :         {
   15967             :                 .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-NO",
   15968             :                 .fn    = run_delete_on_close_nonwrite_delete_no_test,
   15969             :         },
   15970             :         {
   15971             :                 .name  = "SMB2-DFS-PATHS",
   15972             :                 .fn    = run_smb2_dfs_paths,
   15973             :         },
   15974             :         {
   15975             :                 .name  = "SMB2-NON-DFS-SHARE",
   15976             :                 .fn    = run_smb2_non_dfs_share,
   15977             :         },
   15978             :         {
   15979             :                 .name  = "SMB2-DFS-SHARE-NON-DFS-PATH",
   15980             :                 .fn    = run_smb2_dfs_share_non_dfs_path,
   15981             :         },
   15982             :         {
   15983             :                 .name  = "SMB2-DFS-FILENAME-LEADING-BACKSLASH",
   15984             :                 .fn    = run_smb2_dfs_filename_leading_backslash,
   15985             :         },
   15986             :         {
   15987             :                 .name  = "SMB2-PIPE-READ-ASYNC-DISCONNECT",
   15988             :                 .fn    = run_smb2_pipe_read_async_disconnect,
   15989             :         },
   15990             :         {
   15991             :                 .name  = "SMB1-TRUNCATED-SESSSETUP",
   15992             :                 .fn    = run_smb1_truncated_sesssetup,
   15993             :         },
   15994             :         {
   15995             :                 .name  = "SMB1-NEGOTIATE-EXIT",
   15996             :                 .fn    = run_smb1_negotiate_exit,
   15997             :         },
   15998             :         {
   15999             :                 .name  = "SMB1-NEGOTIATE-TCON",
   16000             :                 .fn    = run_smb1_negotiate_tcon,
   16001             :         },
   16002             :         {
   16003             :                 .name  = "SMB1-DFS-PATHS",
   16004             :                 .fn    = run_smb1_dfs_paths,
   16005             :         },
   16006             :         {
   16007             :                 .name  = "SMB1-DFS-SEARCH-PATHS",
   16008             :                 .fn    = run_smb1_dfs_search_paths,
   16009             :         },
   16010             :         {
   16011             :                 .name  = "SMB1-DFS-OPERATIONS",
   16012             :                 .fn    = run_smb1_dfs_operations,
   16013             :         },
   16014             :         {
   16015             :                 .name  = "SMB1-DFS-BADPATH",
   16016             :                 .fn    = run_smb1_dfs_check_badpath,
   16017             :         },
   16018             :         {
   16019             :                 .name  = "CLEANUP1",
   16020             :                 .fn    = run_cleanup1,
   16021             :         },
   16022             :         {
   16023             :                 .name  = "CLEANUP2",
   16024             :                 .fn    = run_cleanup2,
   16025             :         },
   16026             :         {
   16027             :                 .name  = "CLEANUP4",
   16028             :                 .fn    = run_cleanup4,
   16029             :         },
   16030             :         {
   16031             :                 .name  = "OPLOCK-CANCEL",
   16032             :                 .fn    = run_oplock_cancel,
   16033             :         },
   16034             :         {
   16035             :                 .name  = "PIDHIGH",
   16036             :                 .fn    = run_pidhigh,
   16037             :         },
   16038             :         {
   16039             :                 .name  = "LOCAL-SUBSTITUTE",
   16040             :                 .fn    = run_local_substitute,
   16041             :         },
   16042             :         {
   16043             :                 .name  = "LOCAL-GENCACHE",
   16044             :                 .fn    = run_local_gencache,
   16045             :         },
   16046             :         {
   16047             :                 .name  = "LOCAL-DBWRAP-WATCH1",
   16048             :                 .fn    = run_dbwrap_watch1,
   16049             :         },
   16050             :         {
   16051             :                 .name  = "LOCAL-DBWRAP-WATCH2",
   16052             :                 .fn    = run_dbwrap_watch2,
   16053             :         },
   16054             :         {
   16055             :                 .name  = "LOCAL-DBWRAP-WATCH3",
   16056             :                 .fn    = run_dbwrap_watch3,
   16057             :         },
   16058             :         {
   16059             :                 .name  = "LOCAL-DBWRAP-WATCH4",
   16060             :                 .fn    = run_dbwrap_watch4,
   16061             :         },
   16062             :         {
   16063             :                 .name  = "LOCAL-DBWRAP-DO-LOCKED1",
   16064             :                 .fn    = run_dbwrap_do_locked1,
   16065             :         },
   16066             :         {
   16067             :                 .name  = "LOCAL-MESSAGING-READ1",
   16068             :                 .fn    = run_messaging_read1,
   16069             :         },
   16070             :         {
   16071             :                 .name  = "LOCAL-MESSAGING-READ2",
   16072             :                 .fn    = run_messaging_read2,
   16073             :         },
   16074             :         {
   16075             :                 .name  = "LOCAL-MESSAGING-READ3",
   16076             :                 .fn    = run_messaging_read3,
   16077             :         },
   16078             :         {
   16079             :                 .name  = "LOCAL-MESSAGING-READ4",
   16080             :                 .fn    = run_messaging_read4,
   16081             :         },
   16082             :         {
   16083             :                 .name  = "LOCAL-MESSAGING-FDPASS1",
   16084             :                 .fn    = run_messaging_fdpass1,
   16085             :         },
   16086             :         {
   16087             :                 .name  = "LOCAL-MESSAGING-FDPASS2",
   16088             :                 .fn    = run_messaging_fdpass2,
   16089             :         },
   16090             :         {
   16091             :                 .name  = "LOCAL-MESSAGING-FDPASS2a",
   16092             :                 .fn    = run_messaging_fdpass2a,
   16093             :         },
   16094             :         {
   16095             :                 .name  = "LOCAL-MESSAGING-FDPASS2b",
   16096             :                 .fn    = run_messaging_fdpass2b,
   16097             :         },
   16098             :         {
   16099             :                 .name  = "LOCAL-MESSAGING-SEND-ALL",
   16100             :                 .fn    = run_messaging_send_all,
   16101             :         },
   16102             :         {
   16103             :                 .name  = "LOCAL-BASE64",
   16104             :                 .fn    = run_local_base64,
   16105             :         },
   16106             :         {
   16107             :                 .name  = "LOCAL-RBTREE",
   16108             :                 .fn    = run_local_rbtree,
   16109             :         },
   16110             :         {
   16111             :                 .name  = "LOCAL-MEMCACHE",
   16112             :                 .fn    = run_local_memcache,
   16113             :         },
   16114             :         {
   16115             :                 .name  = "LOCAL-STREAM-NAME",
   16116             :                 .fn    = run_local_stream_name,
   16117             :         },
   16118             :         {
   16119             :                 .name  = "LOCAL-STR-MATCH-MSWILD",
   16120             :                 .fn    = run_str_match_mswild,
   16121             :         },
   16122             :         {
   16123             :                 .name  = "LOCAL-STR-MATCH-REGEX-SUB1",
   16124             :                 .fn    = run_str_match_regex_sub1,
   16125             :         },
   16126             :         {
   16127             :                 .name  = "WBCLIENT-MULTI-PING",
   16128             :                 .fn    = run_wbclient_multi_ping,
   16129             :         },
   16130             :         {
   16131             :                 .name  = "LOCAL-string_to_sid",
   16132             :                 .fn    = run_local_string_to_sid,
   16133             :         },
   16134             :         {
   16135             :                 .name  = "LOCAL-sid_to_string",
   16136             :                 .fn    = run_local_sid_to_string,
   16137             :         },
   16138             :         {
   16139             :                 .name  = "LOCAL-binary_to_sid",
   16140             :                 .fn    = run_local_binary_to_sid,
   16141             :         },
   16142             :         {
   16143             :                 .name  = "LOCAL-DBTRANS",
   16144             :                 .fn    = run_local_dbtrans,
   16145             :         },
   16146             :         {
   16147             :                 .name  = "LOCAL-TEVENT-POLL",
   16148             :                 .fn    = run_local_tevent_poll,
   16149             :         },
   16150             :         {
   16151             :                 .name  = "LOCAL-CONVERT-STRING",
   16152             :                 .fn    = run_local_convert_string,
   16153             :         },
   16154             :         {
   16155             :                 .name  = "LOCAL-CONV-AUTH-INFO",
   16156             :                 .fn    = run_local_conv_auth_info,
   16157             :         },
   16158             :         {
   16159             :                 .name  = "LOCAL-hex_encode_buf",
   16160             :                 .fn    = run_local_hex_encode_buf,
   16161             :         },
   16162             :         {
   16163             :                 .name  = "LOCAL-IDMAP-TDB-COMMON",
   16164             :                 .fn    = run_idmap_tdb_common_test,
   16165             :         },
   16166             :         {
   16167             :                 .name  = "LOCAL-remove_duplicate_addrs2",
   16168             :                 .fn    = run_local_remove_duplicate_addrs2,
   16169             :         },
   16170             :         {
   16171             :                 .name  = "local-tdb-opener",
   16172             :                 .fn    = run_local_tdb_opener,
   16173             :         },
   16174             :         {
   16175             :                 .name  = "local-tdb-writer",
   16176             :                 .fn    = run_local_tdb_writer,
   16177             :         },
   16178             :         {
   16179             :                 .name  = "LOCAL-DBWRAP-CTDB1",
   16180             :                 .fn    = run_local_dbwrap_ctdb1,
   16181             :         },
   16182             :         {
   16183             :                 .name  = "LOCAL-BENCH-PTHREADPOOL",
   16184             :                 .fn    = run_bench_pthreadpool,
   16185             :         },
   16186             :         {
   16187             :                 .name  = "LOCAL-PTHREADPOOL-TEVENT",
   16188             :                 .fn    = run_pthreadpool_tevent,
   16189             :         },
   16190             :         {
   16191             :                 .name  = "LOCAL-G-LOCK1",
   16192             :                 .fn    = run_g_lock1,
   16193             :         },
   16194             :         {
   16195             :                 .name  = "LOCAL-G-LOCK2",
   16196             :                 .fn    = run_g_lock2,
   16197             :         },
   16198             :         {
   16199             :                 .name  = "LOCAL-G-LOCK3",
   16200             :                 .fn    = run_g_lock3,
   16201             :         },
   16202             :         {
   16203             :                 .name  = "LOCAL-G-LOCK4",
   16204             :                 .fn    = run_g_lock4,
   16205             :         },
   16206             :         {
   16207             :                 .name  = "LOCAL-G-LOCK4A",
   16208             :                 .fn    = run_g_lock4a,
   16209             :         },
   16210             :         {
   16211             :                 .name  = "LOCAL-G-LOCK5",
   16212             :                 .fn    = run_g_lock5,
   16213             :         },
   16214             :         {
   16215             :                 .name  = "LOCAL-G-LOCK6",
   16216             :                 .fn    = run_g_lock6,
   16217             :         },
   16218             :         {
   16219             :                 .name  = "LOCAL-G-LOCK7",
   16220             :                 .fn    = run_g_lock7,
   16221             :         },
   16222             :         {
   16223             :                 .name  = "LOCAL-G-LOCK8",
   16224             :                 .fn    = run_g_lock8,
   16225             :         },
   16226             :         {
   16227             :                 .name  = "LOCAL-G-LOCK-PING-PONG",
   16228             :                 .fn    = run_g_lock_ping_pong,
   16229             :         },
   16230             :         {
   16231             :                 .name  = "LOCAL-CANONICALIZE-PATH",
   16232             :                 .fn    = run_local_canonicalize_path,
   16233             :         },
   16234             :         {
   16235             :                 .name  = "LOCAL-NAMEMAP-CACHE1",
   16236             :                 .fn    = run_local_namemap_cache1,
   16237             :         },
   16238             :         {
   16239             :                 .name  = "LOCAL-IDMAP-CACHE1",
   16240             :                 .fn    = run_local_idmap_cache1,
   16241             :         },
   16242             :         {
   16243             :                 .name  = "qpathinfo-bufsize",
   16244             :                 .fn    = run_qpathinfo_bufsize,
   16245             :         },
   16246             :         {
   16247             :                 .name  = "hide-new-files-timeout",
   16248             :                 .fn    = run_hidenewfiles,
   16249             :         },
   16250             :         {
   16251             :                 .name  = "hide-new-files-timeout-showdirs",
   16252             :                 .fn    = run_hidenewfiles_showdirs,
   16253             :         },
   16254             : #ifdef CLUSTER_SUPPORT
   16255             :         {
   16256             :                 .name  = "ctdbd-conn1",
   16257             :                 .fn    = run_ctdbd_conn1,
   16258             :         },
   16259             : #endif
   16260             :         {
   16261             :                 .name  = "readdir-timestamp",
   16262             :                 .fn    = run_readdir_timestamp,
   16263             :         },
   16264             :         {
   16265             :                 .name  = "rpc-scale",
   16266             :                 .fn    = run_rpc_scale,
   16267             :         },
   16268             :         {
   16269             :                 .name  = "LOCAL-TDB-VALIDATE",
   16270             :                 .fn    = run_tdb_validate,
   16271             :         },
   16272             :         {
   16273             :                 .name = NULL,
   16274             :         },
   16275             : };
   16276             : 
   16277             : /****************************************************************************
   16278             : run a specified test or "ALL"
   16279             : ****************************************************************************/
   16280         552 : static bool run_test(const char *name)
   16281             : {
   16282         552 :         bool ret = True;
   16283         552 :         bool result = True;
   16284         552 :         bool found = False;
   16285          45 :         int i;
   16286          45 :         double t;
   16287         552 :         if (strequal(name,"ALL")) {
   16288           0 :                 for (i=0;torture_ops[i].name;i++) {
   16289           0 :                         run_test(torture_ops[i].name);
   16290             :                 }
   16291           0 :                 found = True;
   16292             :         }
   16293             : 
   16294      114995 :         for (i=0;torture_ops[i].name;i++) {
   16295      114439 :                 fstr_sprintf(randomfname, "\\XX%x",
   16296      114439 :                          (unsigned)random());
   16297             : 
   16298      114439 :                 if (strequal(name, torture_ops[i].name)) {
   16299         552 :                         found = True;
   16300         552 :                         printf("Running %s\n", name);
   16301         552 :                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
   16302          16 :                                 t = create_procs(torture_ops[i].fn, &result);
   16303          16 :                                 if (!result) {
   16304           2 :                                         ret = False;
   16305           2 :                                         printf("TEST %s FAILED!\n", name);
   16306             :                                 }
   16307             :                         } else {
   16308          45 :                                 struct timeval start;
   16309         536 :                                 start = timeval_current();
   16310         536 :                                 if (!torture_ops[i].fn(0)) {
   16311          14 :                                         ret = False;
   16312          14 :                                         printf("TEST %s FAILED!\n", name);
   16313             :                                 }
   16314         540 :                                 t = timeval_elapsed(&start);
   16315             :                         }
   16316       10001 :                         printf("%s took %g secs\n\n", name, t);
   16317             :                 }
   16318             :         }
   16319             : 
   16320         556 :         if (!found) {
   16321           0 :                 printf("Did not find a test named %s\n", name);
   16322           0 :                 ret = False;
   16323             :         }
   16324             : 
   16325         556 :         return ret;
   16326             : }
   16327             : 
   16328             : 
   16329           0 : static void usage(void)
   16330             : {
   16331           0 :         int i;
   16332             : 
   16333           0 :         printf("WARNING samba4 test suite is much more complete nowadays.\n");
   16334           0 :         printf("Please use samba4 torture.\n\n");
   16335             : 
   16336           0 :         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
   16337             : 
   16338           0 :         printf("\t-d debuglevel\n");
   16339           0 :         printf("\t-U user%%pass\n");
   16340           0 :         printf("\t-k                    use kerberos\n");
   16341           0 :         printf("\t-N numprocs\n");
   16342           0 :         printf("\t-n my_netbios_name\n");
   16343           0 :         printf("\t-W workgroup\n");
   16344           0 :         printf("\t-o num_operations\n");
   16345           0 :         printf("\t-O socket_options\n");
   16346           0 :         printf("\t-m maximum protocol\n");
   16347           0 :         printf("\t-L use oplocks\n");
   16348           0 :         printf("\t-c CLIENT.TXT         specify client load file for NBENCH\n");
   16349           0 :         printf("\t-A showall\n");
   16350           0 :         printf("\t-p port\n");
   16351           0 :         printf("\t-s seed\n");
   16352           0 :         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
   16353           0 :         printf("\t-f filename           filename to test\n");
   16354           0 :         printf("\t-e                    encrypt\n");
   16355           0 :         printf("\t-T 'OPTION=VALUE'     smb.conf option line\n");
   16356           0 :         printf("\n\n");
   16357             : 
   16358           0 :         printf("tests are:");
   16359           0 :         for (i=0;torture_ops[i].name;i++) {
   16360           0 :                 printf(" %s", torture_ops[i].name);
   16361             :         }
   16362           0 :         printf("\n");
   16363             : 
   16364           0 :         printf("default test is ALL\n");
   16365             : 
   16366           0 :         exit(1);
   16367             : }
   16368             : 
   16369             : /****************************************************************************
   16370             :   main program
   16371             : ****************************************************************************/
   16372         552 :  int main(int argc,char *argv[])
   16373             : {
   16374          45 :         int opt, i;
   16375          45 :         char *p;
   16376         552 :         int gotuser = 0;
   16377         552 :         int gotpass = 0;
   16378         552 :         bool correct = True;
   16379         552 :         TALLOC_CTX *frame = talloc_stackframe();
   16380         552 :         int seed = time(NULL);
   16381         552 :         struct loadparm_context *lp_ctx = NULL;
   16382             : 
   16383             : #ifdef HAVE_SETBUFFER
   16384         552 :         setbuffer(stdout, NULL, 0);
   16385             : #endif
   16386             : 
   16387         552 :         setup_logging("smbtorture", DEBUG_STDOUT);
   16388             : 
   16389         552 :         smb_init_locale();
   16390         552 :         fault_setup();
   16391             : 
   16392         552 :         lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
   16393         552 :         if (lp_ctx == NULL) {
   16394           0 :                 fprintf(stderr,
   16395             :                         "Failed to initialise the global parameter structure.\n");
   16396           0 :                 return 1;
   16397             :         }
   16398             : 
   16399         552 :         if (is_default_dyn_CONFIGFILE()) {
   16400         552 :                 if(getenv("SMB_CONF_PATH")) {
   16401         552 :                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
   16402             :                 }
   16403             :         }
   16404         552 :         lp_load_global(get_dyn_CONFIGFILE());
   16405         552 :         load_interfaces();
   16406             : 
   16407         552 :         if (argc < 2) {
   16408           0 :                 usage();
   16409             :         }
   16410             : 
   16411       11131 :         for(p = argv[1]; *p; p++)
   16412       10579 :           if(*p == '\\')
   16413           0 :             *p = '/';
   16414             : 
   16415         552 :         if (strncmp(argv[1], "//", 2)) {
   16416           0 :                 usage();
   16417             :         }
   16418             : 
   16419         552 :         fstrcpy(host, &argv[1][2]);
   16420         552 :         p = strchr_m(&host[2],'/');
   16421         552 :         if (!p) {
   16422           0 :                 usage();
   16423             :         }
   16424         552 :         *p = 0;
   16425         552 :         fstrcpy(share, p+1);
   16426             : 
   16427         552 :         fstrcpy(myname, get_myname(talloc_tos()));
   16428         552 :         if (!*myname) {
   16429           0 :                 fprintf(stderr, "Failed to get my hostname.\n");
   16430           0 :                 return 1;
   16431             :         }
   16432             : 
   16433         552 :         if (*username == 0 && getenv("LOGNAME")) {
   16434           0 :           fstrcpy(username,getenv("LOGNAME"));
   16435             :         }
   16436             : 
   16437         552 :         argc--;
   16438         552 :         argv++;
   16439             : 
   16440         552 :         fstrcpy(workgroup, lp_workgroup());
   16441             : 
   16442        1755 :         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:T:"))
   16443        1800 :                != EOF) {
   16444        1248 :                 switch (opt) {
   16445           0 :                 case 'p':
   16446           0 :                         port_to_use = atoi(optarg);
   16447           0 :                         break;
   16448           0 :                 case 's':
   16449           0 :                         seed = atoi(optarg);
   16450           0 :                         break;
   16451           0 :                 case 'W':
   16452           0 :                         fstrcpy(workgroup,optarg);
   16453           0 :                         break;
   16454          33 :                 case 'm':
   16455          33 :                         lpcfg_set_cmdline(lp_ctx, "client max protocol", optarg);
   16456          33 :                         break;
   16457           0 :                 case 'N':
   16458           0 :                         torture_nprocs = atoi(optarg);
   16459           0 :                         break;
   16460           0 :                 case 'o':
   16461           0 :                         torture_numops = atoi(optarg);
   16462           0 :                         break;
   16463           0 :                 case 'd':
   16464           0 :                         lpcfg_set_cmdline(lp_ctx, "log level", optarg);
   16465           0 :                         break;
   16466           0 :                 case 'O':
   16467           0 :                         sockops = optarg;
   16468           0 :                         break;
   16469           0 :                 case 'L':
   16470           0 :                         use_oplocks = True;
   16471           0 :                         break;
   16472         469 :                 case 'l':
   16473         469 :                         local_path = optarg;
   16474         469 :                         break;
   16475           0 :                 case 'A':
   16476           0 :                         torture_showall = True;
   16477           0 :                         break;
   16478           0 :                 case 'n':
   16479           0 :                         fstrcpy(myname, optarg);
   16480           0 :                         break;
   16481           0 :                 case 'c':
   16482           0 :                         client_txt = optarg;
   16483           0 :                         break;
   16484         182 :                 case 'e':
   16485         182 :                         do_encrypt = true;
   16486         182 :                         break;
   16487           0 :                 case 'k':
   16488             : #ifdef HAVE_KRB5
   16489           0 :                         use_kerberos = True;
   16490             : #else
   16491             :                         d_printf("No kerberos support compiled in\n");
   16492             :                         exit(1);
   16493             : #endif
   16494           0 :                         break;
   16495         552 :                 case 'U':
   16496         552 :                         gotuser = 1;
   16497         552 :                         fstrcpy(username,optarg);
   16498         552 :                         p = strchr_m(username,'%');
   16499         552 :                         if (p) {
   16500         552 :                                 *p = 0;
   16501         552 :                                 fstrcpy(password, p+1);
   16502         552 :                                 gotpass = 1;
   16503             :                         }
   16504         507 :                         break;
   16505           0 :                 case 'b':
   16506           0 :                         fstrcpy(multishare_conn_fname, optarg);
   16507           0 :                         use_multishare_conn = True;
   16508           0 :                         break;
   16509           0 :                 case 'B':
   16510           0 :                         torture_blocksize = atoi(optarg);
   16511           0 :                         break;
   16512           4 :                 case 'f':
   16513           4 :                         test_filename = SMB_STRDUP(optarg);
   16514           4 :                         break;
   16515           8 :                 case 'T':
   16516           8 :                         lpcfg_set_option(lp_ctx, optarg);
   16517           8 :                         break;
   16518           0 :                 default:
   16519           0 :                         printf("Unknown option %c (%d)\n", (char)opt, opt);
   16520           0 :                         usage();
   16521             :                 }
   16522             :         }
   16523             : 
   16524         552 :         d_printf("using seed %d\n", seed);
   16525             : 
   16526         552 :         srandom(seed);
   16527             : 
   16528         552 :         if(use_kerberos && !gotuser) gotpass = True;
   16529             : 
   16530         552 :         while (!gotpass) {
   16531           0 :                 char pwd[256] = {0};
   16532           0 :                 int rc;
   16533             : 
   16534           0 :                 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
   16535           0 :                 if (rc == 0) {
   16536           0 :                         fstrcpy(password, pwd);
   16537           0 :                         gotpass = 1;
   16538             :                 }
   16539             :         }
   16540             : 
   16541         552 :         printf("host=%s share=%s user=%s myname=%s\n",
   16542             :                host, share, username, myname);
   16543             : 
   16544         552 :         torture_creds = cli_session_creds_init(frame,
   16545             :                                                username,
   16546             :                                                workgroup,
   16547             :                                                NULL, /* realm */
   16548             :                                                password,
   16549             :                                                use_kerberos,
   16550             :                                                false, /* fallback_after_kerberos */
   16551             :                                                false, /* use_ccache */
   16552             :                                                false); /* password_is_nt_hash */
   16553         552 :         if (torture_creds == NULL) {
   16554           0 :                 d_printf("cli_session_creds_init() failed.\n");
   16555           0 :                 exit(1);
   16556             :         }
   16557             : 
   16558         552 :         if (argc == optind) {
   16559           0 :                 correct = run_test("ALL");
   16560             :         } else {
   16561        1108 :                 for (i=optind;i<argc;i++) {
   16562         552 :                         if (!run_test(argv[i])) {
   16563          16 :                                 correct = False;
   16564             :                         }
   16565             :                 }
   16566             :         }
   16567             : 
   16568         556 :         TALLOC_FREE(frame);
   16569             : 
   16570         556 :         if (correct) {
   16571         491 :                 return(0);
   16572             :         } else {
   16573          16 :                 return(1);
   16574             :         }
   16575             : }

Generated by: LCOV version 1.14