LCOV - code coverage report
Current view: top level - source3/torture - torture.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 4203 7330 57.3 %
Date: 2021-09-23 10:06:22 Functions: 179 228 78.5 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB torture tester
       4             :    Copyright (C) Andrew Tridgell 1997-1998
       5             :    Copyright (C) Jeremy Allison 2009
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "system/shmem.h"
      23             : #include "libsmb/namequery.h"
      24             : #include "wbc_async.h"
      25             : #include "torture/proto.h"
      26             : #include "libcli/security/security.h"
      27             : #include "tldap.h"
      28             : #include "tldap_util.h"
      29             : #include "tldap_gensec_bind.h"
      30             : #include "../librpc/gen_ndr/svcctl.h"
      31             : #include "../lib/util/memcache.h"
      32             : #include "nsswitch/winbind_client.h"
      33             : #include "dbwrap/dbwrap.h"
      34             : #include "dbwrap/dbwrap_open.h"
      35             : #include "dbwrap/dbwrap_rbt.h"
      36             : #include "async_smb.h"
      37             : #include "libsmb/libsmb.h"
      38             : #include "libsmb/clirap.h"
      39             : #include "trans2.h"
      40             : #include "libsmb/nmblib.h"
      41             : #include "../lib/util/tevent_ntstatus.h"
      42             : #include "util_tdb.h"
      43             : #include "../libcli/smb/read_smb.h"
      44             : #include "../libcli/smb/smbXcli_base.h"
      45             : #include "lib/util/sys_rw_data.h"
      46             : #include "lib/util/base64.h"
      47             : #include "lib/util/time.h"
      48             : #include "lib/gencache.h"
      49             : #include "lib/util/sys_rw.h"
      50             : #include "lib/util/asn1.h"
      51             : #include "lib/param/param.h"
      52             : #include "auth/gensec/gensec.h"
      53             : #include "lib/util/string_wrappers.h"
      54             : 
      55             : #include <gnutls/gnutls.h>
      56             : #include <gnutls/crypto.h>
      57             : 
      58             : extern char *optarg;
      59             : extern int optind;
      60             : 
      61             : fstring host, workgroup, share, password, username, myname;
      62             : struct cli_credentials *torture_creds;
      63             : static const char *sockops="TCP_NODELAY";
      64             : int torture_nprocs=1;
      65             : static int port_to_use=0;
      66             : int torture_numops=100;
      67             : int torture_blocksize=1024*1024;
      68             : static int procnum; /* records process count number when forking */
      69             : static struct cli_state *current_cli;
      70             : static fstring randomfname;
      71             : static bool use_oplocks;
      72             : static bool use_level_II_oplocks;
      73             : static const char *client_txt = "client_oplocks.txt";
      74             : static bool disable_spnego;
      75             : static bool use_kerberos;
      76             : static bool force_dos_errors;
      77             : static fstring multishare_conn_fname;
      78             : static bool use_multishare_conn = False;
      79             : static bool do_encrypt;
      80             : static const char *local_path = NULL;
      81             : static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
      82             : char *test_filename;
      83             : 
      84             : bool torture_showall = False;
      85             : 
      86             : static double create_procs(bool (*fn)(int), bool *result);
      87             : 
      88             : /********************************************************************
      89             :  Ensure a connection is encrypted.
      90             : ********************************************************************/
      91             : 
      92         202 : static bool force_cli_encryption(struct cli_state *c,
      93             :                         const char *sharename)
      94             : {
      95             :         uint16_t major, minor;
      96             :         uint32_t caplow, caphigh;
      97             :         NTSTATUS status;
      98             : 
      99         202 :         if (!SERVER_HAS_UNIX_CIFS(c)) {
     100           0 :                 d_printf("Encryption required and "
     101             :                         "server that doesn't support "
     102             :                         "UNIX extensions - failing connect\n");
     103           0 :                         return false;
     104             :         }
     105             : 
     106         202 :         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
     107             :                                              &caphigh);
     108         202 :         if (!NT_STATUS_IS_OK(status)) {
     109           0 :                 d_printf("Encryption required and "
     110             :                         "can't get UNIX CIFS extensions "
     111             :                         "version from server: %s\n", nt_errstr(status));
     112           0 :                 return false;
     113             :         }
     114             : 
     115         202 :         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
     116           0 :                 d_printf("Encryption required and "
     117             :                         "share %s doesn't support "
     118             :                         "encryption.\n", sharename);
     119           0 :                 return false;
     120             :         }
     121             : 
     122         202 :         status = cli_smb1_setup_encryption(c, torture_creds);
     123         202 :         if (!NT_STATUS_IS_OK(status)) {
     124           0 :                 d_printf("Encryption required and "
     125             :                         "setup failed with error %s.\n",
     126             :                         nt_errstr(status));
     127           0 :                 return false;
     128             :         }
     129             : 
     130         202 :         return true;
     131             : }
     132             : 
     133             : 
     134          76 : static struct cli_state *open_nbt_connection(void)
     135             : {
     136             :         struct cli_state *c;
     137             :         NTSTATUS status;
     138          76 :         int flags = 0;
     139             : 
     140          76 :         if (disable_spnego) {
     141           0 :                 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
     142             :         }
     143             : 
     144          76 :         if (use_oplocks) {
     145           0 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     146             :         }
     147             : 
     148          76 :         if (use_level_II_oplocks) {
     149           0 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     150             :         }
     151             : 
     152          76 :         if (force_dos_errors) {
     153           0 :                 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
     154             :         }
     155             : 
     156          76 :         status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
     157             :                                 signing_state, flags, &c);
     158          76 :         if (!NT_STATUS_IS_OK(status)) {
     159           0 :                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
     160           0 :                 return NULL;
     161             :         }
     162             : 
     163          76 :         cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
     164             : 
     165          76 :         return c;
     166             : }
     167             : 
     168             : /****************************************************************************
     169             :  Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
     170             : ****************************************************************************/
     171             : 
     172           4 : static bool cli_bad_session_request(int fd,
     173             :                          struct nmb_name *calling, struct nmb_name *called)
     174             : {
     175             :         TALLOC_CTX *frame;
     176             :         uint8_t len_buf[4];
     177             :         struct iovec iov[3];
     178             :         ssize_t len;
     179             :         uint8_t *inbuf;
     180             :         int err;
     181           4 :         bool ret = false;
     182             :         uint8_t message_type;
     183             :         uint8_t error;
     184             :         struct tevent_context *ev;
     185             :         struct tevent_req *req;
     186             : 
     187           4 :         frame = talloc_stackframe();
     188             : 
     189           4 :         iov[0].iov_base = len_buf;
     190           4 :         iov[0].iov_len  = sizeof(len_buf);
     191             : 
     192             :         /* put in the destination name */
     193             : 
     194           4 :         iov[1].iov_base = name_mangle(talloc_tos(), called->name,
     195           4 :                                       called->name_type);
     196           4 :         if (iov[1].iov_base == NULL) {
     197           0 :                 goto fail;
     198             :         }
     199           4 :         iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
     200           4 :                                   talloc_get_size(iov[1].iov_base));
     201             : 
     202             :         /* and my name */
     203             : 
     204           4 :         iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
     205           4 :                                       calling->name_type);
     206           4 :         if (iov[2].iov_base == NULL) {
     207           0 :                 goto fail;
     208             :         }
     209           4 :         iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
     210           4 :                                   talloc_get_size(iov[2].iov_base));
     211             : 
     212             :         /* Deliberately corrupt the name len (first byte) */
     213           4 :         *((uint8_t *)iov[2].iov_base) = 100;
     214             : 
     215             :         /* send a session request (RFC 1002) */
     216             :         /* setup the packet length
     217             :          * Remove four bytes from the length count, since the length
     218             :          * field in the NBT Session Service header counts the number
     219             :          * of bytes which follow.  The cli_send_smb() function knows
     220             :          * about this and accounts for those four bytes.
     221             :          * CRH.
     222             :          */
     223             : 
     224           4 :         _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
     225           4 :         SCVAL(len_buf,0,0x81);
     226             : 
     227           4 :         len = write_data_iov(fd, iov, 3);
     228           4 :         if (len == -1) {
     229           0 :                 goto fail;
     230             :         }
     231             : 
     232           4 :         ev = samba_tevent_context_init(frame);
     233           4 :         if (ev == NULL) {
     234           0 :                 goto fail;
     235             :         }
     236           4 :         req = read_smb_send(frame, ev, fd);
     237           4 :         if (req == NULL) {
     238           0 :                 goto fail;
     239             :         }
     240           4 :         if (!tevent_req_poll(req, ev)) {
     241           0 :                 goto fail;
     242             :         }
     243           4 :         len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
     244           4 :         if (len == -1) {
     245           0 :                 errno = err;
     246           0 :                 goto fail;
     247             :         }
     248           4 :         TALLOC_FREE(ev);
     249             : 
     250           4 :         message_type = CVAL(inbuf, 0);
     251           4 :         if (message_type != 0x83) {
     252           0 :                 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
     253             :                           message_type);
     254           0 :                 goto fail;
     255             :         }
     256             : 
     257           4 :         if (smb_len(inbuf) != 1) {
     258           0 :                 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
     259           0 :                           (int)smb_len(inbuf));
     260           0 :                 goto fail;
     261             :         }
     262             : 
     263           4 :         error = CVAL(inbuf, 4);
     264           4 :         if (error !=  0x82) {
     265           0 :                 d_fprintf(stderr, "Expected error 0x82, got %d\n",
     266             :                           (int)error);
     267           0 :                 goto fail;
     268             :         }
     269             : 
     270           4 :         ret = true;
     271           4 : fail:
     272           4 :         TALLOC_FREE(frame);
     273           4 :         return ret;
     274             : }
     275             : 
     276             : /* Insert a NULL at the first separator of the given path and return a pointer
     277             :  * to the remainder of the string.
     278             :  */
     279             : static char *
     280           0 : terminate_path_at_separator(char * path)
     281             : {
     282             :         char * p;
     283             : 
     284           0 :         if (!path) {
     285           0 :                 return NULL;
     286             :         }
     287             : 
     288           0 :         if ((p = strchr_m(path, '/'))) {
     289           0 :                 *p = '\0';
     290           0 :                 return p + 1;
     291             :         }
     292             : 
     293           0 :         if ((p = strchr_m(path, '\\'))) {
     294           0 :                 *p = '\0';
     295           0 :                 return p + 1;
     296             :         }
     297             : 
     298             :         /* No separator. */
     299           0 :         return NULL;
     300             : }
     301             : 
     302             : /*
     303             :   parse a //server/share type UNC name
     304             : */
     305           0 : bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
     306             :                       char **hostname, char **sharename)
     307             : {
     308             :         char *p;
     309             : 
     310           0 :         *hostname = *sharename = NULL;
     311             : 
     312           0 :         if (strncmp(unc_name, "\\\\", 2) &&
     313           0 :             strncmp(unc_name, "//", 2)) {
     314           0 :                 return False;
     315             :         }
     316             : 
     317           0 :         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
     318           0 :         p = terminate_path_at_separator(*hostname);
     319             : 
     320           0 :         if (p && *p) {
     321           0 :                 *sharename = talloc_strdup(mem_ctx, p);
     322           0 :                 terminate_path_at_separator(*sharename);
     323             :         }
     324             : 
     325           0 :         if (*hostname && *sharename) {
     326           0 :                 return True;
     327             :         }
     328             : 
     329           0 :         TALLOC_FREE(*hostname);
     330           0 :         TALLOC_FREE(*sharename);
     331           0 :         return False;
     332             : }
     333             : 
     334         492 : static bool torture_open_connection_share(struct cli_state **c,
     335             :                                    const char *hostname, 
     336             :                                    const char *sharename,
     337             :                                    int flags)
     338             : {
     339             :         NTSTATUS status;
     340             : 
     341         492 :         status = cli_full_connection_creds(c,
     342             :                                            myname,
     343             :                                            hostname,
     344             :                                            NULL, /* dest_ss */
     345             :                                            port_to_use,
     346             :                                            sharename,
     347             :                                            "?????",
     348             :                                            torture_creds,
     349             :                                            flags);
     350         492 :         if (!NT_STATUS_IS_OK(status)) {
     351           2 :                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
     352             :                         hostname, sharename, port_to_use, nt_errstr(status));
     353           2 :                 return False;
     354             :         }
     355             : 
     356         490 :         cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
     357             : 
     358         490 :         if (do_encrypt) {
     359         200 :                 return force_cli_encryption(*c,
     360             :                                         sharename);
     361             :         }
     362         290 :         return True;
     363             : }
     364             : 
     365         492 : bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
     366             : {
     367         492 :         char **unc_list = NULL;
     368         492 :         int num_unc_names = 0;
     369             :         bool result;
     370             : 
     371         492 :         if (use_multishare_conn==True) {
     372             :                 char *h, *s;
     373           0 :                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
     374           0 :                 if (!unc_list || num_unc_names <= 0) {
     375           0 :                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
     376           0 :                         exit(1);
     377             :                 }
     378             : 
     379           0 :                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
     380             :                                       NULL, &h, &s)) {
     381           0 :                         printf("Failed to parse UNC name %s\n",
     382           0 :                                unc_list[conn_index % num_unc_names]);
     383           0 :                         TALLOC_FREE(unc_list);
     384           0 :                         exit(1);
     385             :                 }
     386             : 
     387           0 :                 result = torture_open_connection_share(c, h, s, flags);
     388             : 
     389             :                 /* h, s were copied earlier */
     390           0 :                 TALLOC_FREE(unc_list);
     391           0 :                 return result;
     392             :         }
     393             : 
     394         492 :         return torture_open_connection_share(c, host, share, flags);
     395             : }
     396             : 
     397         484 : bool torture_open_connection(struct cli_state **c, int conn_index)
     398             : {
     399         484 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
     400             : 
     401         484 :         if (use_oplocks) {
     402           8 :                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
     403             :         }
     404         484 :         if (use_level_II_oplocks) {
     405           8 :                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
     406             :         }
     407             : 
     408         484 :         return torture_open_connection_flags(c, conn_index, flags);
     409             : }
     410             : 
     411          68 : bool torture_init_connection(struct cli_state **pcli)
     412             : {
     413             :         struct cli_state *cli;
     414             : 
     415          68 :         cli = open_nbt_connection();
     416          68 :         if (cli == NULL) {
     417           0 :                 return false;
     418             :         }
     419             : 
     420          68 :         *pcli = cli;
     421          68 :         return true;
     422             : }
     423             : 
     424           5 : bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
     425             : {
     426           5 :         uint16_t old_vuid = cli_state_get_uid(cli);
     427             :         NTSTATUS status;
     428             :         bool ret;
     429             : 
     430           5 :         cli_state_set_uid(cli, 0);
     431           5 :         status = cli_session_setup_creds(cli, torture_creds);
     432           5 :         ret = NT_STATUS_IS_OK(status);
     433           5 :         *new_vuid = cli_state_get_uid(cli);
     434           5 :         cli_state_set_uid(cli, old_vuid);
     435           5 :         return ret;
     436             : }
     437             : 
     438             : 
     439         426 : bool torture_close_connection(struct cli_state *c)
     440             : {
     441         426 :         bool ret = True;
     442             :         NTSTATUS status;
     443             : 
     444         426 :         status = cli_tdis(c);
     445         426 :         if (!NT_STATUS_IS_OK(status)) {
     446           5 :                 printf("tdis failed (%s)\n", nt_errstr(status));
     447           5 :                 ret = False;
     448             :         }
     449             : 
     450         426 :         cli_shutdown(c);
     451             : 
     452         426 :         return ret;
     453             : }
     454             : 
     455          48 : void torture_conn_set_sockopt(struct cli_state *cli)
     456             : {
     457          48 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     458          48 : }
     459             : 
     460             : /* check if the server produced the expected dos or nt error code */
     461          53 : static bool check_both_error(int line, NTSTATUS status,
     462             :                              uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     463             : {
     464          53 :         if (NT_STATUS_IS_DOS(status)) {
     465             :                 uint8_t cclass;
     466             :                 uint32_t num;
     467             : 
     468             :                 /* Check DOS error */
     469           0 :                 cclass = NT_STATUS_DOS_CLASS(status);
     470           0 :                 num = NT_STATUS_DOS_CODE(status);
     471             : 
     472           0 :                 if (eclass != cclass || ecode != num) {
     473           0 :                         printf("unexpected error code class=%d code=%d\n",
     474             :                                (int)cclass, (int)num);
     475           0 :                         printf(" expected %d/%d %s (line=%d)\n",
     476             :                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
     477           0 :                         return false;
     478             :                 }
     479             :         } else {
     480             :                 /* Check NT error */
     481          53 :                 if (!NT_STATUS_EQUAL(nterr, status)) {
     482           0 :                         printf("unexpected error code %s\n",
     483             :                                 nt_errstr(status));
     484           0 :                         printf(" expected %s (line=%d)\n",
     485             :                                 nt_errstr(nterr), line);
     486           0 :                         return false;
     487             :                 }
     488             :         }
     489             : 
     490          53 :         return true;
     491             : }
     492             : 
     493             : 
     494             : /* check if the server produced the expected error code */
     495          38 : static bool check_error(int line, NTSTATUS status,
     496             :                         uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
     497             : {
     498          38 :         if (NT_STATUS_IS_DOS(status)) {
     499             :                 uint8_t cclass;
     500             :                 uint32_t num;
     501             : 
     502             :                 /* Check DOS error */
     503             : 
     504           0 :                 cclass = NT_STATUS_DOS_CLASS(status);
     505           0 :                 num = NT_STATUS_DOS_CODE(status);
     506             : 
     507           0 :                 if (eclass != cclass || ecode != num) {
     508           0 :                         printf("unexpected error code class=%d code=%d\n", 
     509             :                                (int)cclass, (int)num);
     510           0 :                         printf(" expected %d/%d %s (line=%d)\n", 
     511             :                                (int)eclass, (int)ecode, nt_errstr(nterr),
     512             :                                line);
     513           0 :                         return False;
     514             :                 }
     515             : 
     516             :         } else {
     517             :                 /* Check NT error */
     518             : 
     519          38 :                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
     520           1 :                         printf("unexpected error code %s\n",
     521             :                                nt_errstr(status));
     522           1 :                         printf(" expected %s (line=%d)\n", nt_errstr(nterr),
     523             :                                line);
     524           1 :                         return False;
     525             :                 }
     526             :         }
     527             : 
     528          37 :         return True;
     529             : }
     530             : 
     531             : 
     532           0 : static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
     533             : {
     534             :         NTSTATUS status;
     535             : 
     536           0 :         status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     537             : 
     538           0 :         while (!NT_STATUS_IS_OK(status)) {
     539           0 :                 if (!check_both_error(__LINE__, status, ERRDOS,
     540           0 :                                       ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
     541           0 :                         return false;
     542             :                 }
     543             : 
     544           0 :                 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
     545             :         }
     546             : 
     547           0 :         return true;
     548             : }
     549             : 
     550             : 
     551           0 : static bool rw_torture(struct cli_state *c)
     552             : {
     553           0 :         const char *lockfname = "\\torture.lck";
     554             :         fstring fname;
     555             :         uint16_t fnum;
     556             :         uint16_t fnum2;
     557           0 :         pid_t pid2, pid = getpid();
     558             :         int i, j;
     559             :         char buf[1024];
     560           0 :         bool correct = True;
     561           0 :         size_t nread = 0;
     562             :         NTSTATUS status;
     563             : 
     564           0 :         memset(buf, '\0', sizeof(buf));
     565             : 
     566           0 :         status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
     567             :                          DENY_NONE, &fnum2);
     568           0 :         if (!NT_STATUS_IS_OK(status)) {
     569           0 :                 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
     570             :         }
     571           0 :         if (!NT_STATUS_IS_OK(status)) {
     572           0 :                 printf("open of %s failed (%s)\n",
     573             :                        lockfname, nt_errstr(status));
     574           0 :                 return False;
     575             :         }
     576             : 
     577           0 :         for (i=0;i<torture_numops;i++) {
     578           0 :                 unsigned n = (unsigned)sys_random()%10;
     579             : 
     580           0 :                 if (i % 10 == 0) {
     581           0 :                         printf("%d\r", i); fflush(stdout);
     582             :                 }
     583           0 :                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
     584             : 
     585           0 :                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
     586           0 :                         return False;
     587             :                 }
     588             : 
     589           0 :                 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
     590             :                                   DENY_ALL, &fnum);
     591           0 :                 if (!NT_STATUS_IS_OK(status)) {
     592           0 :                         printf("open failed (%s)\n", nt_errstr(status));
     593           0 :                         correct = False;
     594           0 :                         break;
     595             :                 }
     596             : 
     597           0 :                 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
     598             :                                       sizeof(pid), NULL);
     599           0 :                 if (!NT_STATUS_IS_OK(status)) {
     600           0 :                         printf("write failed (%s)\n", nt_errstr(status));
     601           0 :                         correct = False;
     602             :                 }
     603             : 
     604           0 :                 for (j=0;j<50;j++) {
     605           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
     606           0 :                                               sizeof(pid)+(j*sizeof(buf)),
     607             :                                               sizeof(buf), NULL);
     608           0 :                         if (!NT_STATUS_IS_OK(status)) {
     609           0 :                                 printf("write failed (%s)\n",
     610             :                                        nt_errstr(status));
     611           0 :                                 correct = False;
     612             :                         }
     613             :                 }
     614             : 
     615           0 :                 pid2 = 0;
     616             : 
     617           0 :                 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
     618             :                                   &nread);
     619           0 :                 if (!NT_STATUS_IS_OK(status)) {
     620           0 :                         printf("read failed (%s)\n", nt_errstr(status));
     621           0 :                         correct = false;
     622           0 :                 } else if (nread != sizeof(pid)) {
     623           0 :                         printf("read/write compare failed: "
     624             :                                "recv %ld req %ld\n", (unsigned long)nread,
     625             :                                (unsigned long)sizeof(pid));
     626           0 :                         correct = false;
     627             :                 }
     628             : 
     629           0 :                 if (pid2 != pid) {
     630           0 :                         printf("data corruption!\n");
     631           0 :                         correct = False;
     632             :                 }
     633             : 
     634           0 :                 status = cli_close(c, fnum);
     635           0 :                 if (!NT_STATUS_IS_OK(status)) {
     636           0 :                         printf("close failed (%s)\n", nt_errstr(status));
     637           0 :                         correct = False;
     638             :                 }
     639             : 
     640           0 :                 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     641           0 :                 if (!NT_STATUS_IS_OK(status)) {
     642           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
     643           0 :                         correct = False;
     644             :                 }
     645             : 
     646           0 :                 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
     647           0 :                 if (!NT_STATUS_IS_OK(status)) {
     648           0 :                         printf("unlock failed (%s)\n", nt_errstr(status));
     649           0 :                         correct = False;
     650             :                 }
     651             :         }
     652             : 
     653           0 :         cli_close(c, fnum2);
     654           0 :         cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     655             : 
     656           0 :         printf("%d\n", i);
     657             : 
     658           0 :         return correct;
     659             : }
     660             : 
     661           0 : static bool run_torture(int dummy)
     662             : {
     663             :         struct cli_state *cli;
     664             :         bool ret;
     665             : 
     666           0 :         cli = current_cli;
     667             : 
     668           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     669             : 
     670           0 :         ret = rw_torture(cli);
     671             : 
     672           0 :         if (!torture_close_connection(cli)) {
     673           0 :                 ret = False;
     674             :         }
     675             : 
     676           0 :         return ret;
     677             : }
     678             : 
     679           0 : static bool rw_torture3(struct cli_state *c, char *lockfname)
     680             : {
     681           0 :         uint16_t fnum = (uint16_t)-1;
     682           0 :         unsigned int i = 0;
     683             :         char buf[131072];
     684             :         char buf_rd[131072];
     685             :         unsigned count;
     686           0 :         unsigned countprev = 0;
     687           0 :         size_t sent = 0;
     688           0 :         bool correct = True;
     689           0 :         NTSTATUS status = NT_STATUS_OK;
     690             : 
     691           0 :         srandom(1);
     692           0 :         for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
     693             :         {
     694           0 :                 SIVAL(buf, i, sys_random());
     695             :         }
     696             : 
     697           0 :         if (procnum == 0)
     698             :         {
     699           0 :                 status = cli_unlink(
     700             :                         c, lockfname,
     701             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     702           0 :                 if (!NT_STATUS_IS_OK(status)) {
     703           0 :                         printf("unlink failed (%s) (normal, this file should "
     704             :                                "not exist)\n", nt_errstr(status));
     705             :                 }
     706             : 
     707           0 :                 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
     708             :                                   DENY_NONE, &fnum);
     709           0 :                 if (!NT_STATUS_IS_OK(status)) {
     710           0 :                         printf("first open read/write of %s failed (%s)\n",
     711             :                                         lockfname, nt_errstr(status));
     712           0 :                         return False;
     713             :                 }
     714             :         }
     715             :         else
     716             :         {
     717           0 :                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
     718             :                 {
     719           0 :                         status = cli_openx(c, lockfname, O_RDONLY, 
     720             :                                          DENY_NONE, &fnum);
     721           0 :                         if (NT_STATUS_IS_OK(status)) {
     722           0 :                                 break;
     723             :                         }
     724           0 :                         smb_msleep(10);
     725             :                 }
     726           0 :                 if (!NT_STATUS_IS_OK(status)) {
     727           0 :                         printf("second open read-only of %s failed (%s)\n",
     728             :                                         lockfname, nt_errstr(status));
     729           0 :                         return False;
     730             :                 }
     731             :         }
     732             : 
     733           0 :         i = 0;
     734           0 :         for (count = 0; count < sizeof(buf); count += sent)
     735             :         {
     736           0 :                 if (count >= countprev) {
     737           0 :                         printf("%d %8d\r", i, count);
     738           0 :                         fflush(stdout);
     739           0 :                         i++;
     740           0 :                         countprev += (sizeof(buf) / 20);
     741             :                 }
     742             : 
     743           0 :                 if (procnum == 0)
     744             :                 {
     745           0 :                         sent = ((unsigned)sys_random()%(20))+ 1;
     746           0 :                         if (sent > sizeof(buf) - count)
     747             :                         {
     748           0 :                                 sent = sizeof(buf) - count;
     749             :                         }
     750             : 
     751           0 :                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
     752             :                                               count, sent, NULL);
     753           0 :                         if (!NT_STATUS_IS_OK(status)) {
     754           0 :                                 printf("write failed (%s)\n",
     755             :                                        nt_errstr(status));
     756           0 :                                 correct = False;
     757             :                         }
     758             :                 }
     759             :                 else
     760             :                 {
     761           0 :                         status = cli_read(c, fnum, buf_rd+count, count,
     762             :                                           sizeof(buf)-count, &sent);
     763           0 :                         if(!NT_STATUS_IS_OK(status)) {
     764           0 :                                 printf("read failed offset:%d size:%ld (%s)\n",
     765             :                                        count, (unsigned long)sizeof(buf)-count,
     766             :                                        nt_errstr(status));
     767           0 :                                 correct = False;
     768           0 :                                 sent = 0;
     769           0 :                         } else if (sent > 0) {
     770           0 :                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
     771             :                                 {
     772           0 :                                         printf("read/write compare failed\n");
     773           0 :                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
     774           0 :                                         correct = False;
     775           0 :                                         break;
     776             :                                 }
     777             :                         }
     778             :                 }
     779             : 
     780             :         }
     781             : 
     782           0 :         status = cli_close(c, fnum);
     783           0 :         if (!NT_STATUS_IS_OK(status)) {
     784           0 :                 printf("close failed (%s)\n", nt_errstr(status));
     785           0 :                 correct = False;
     786             :         }
     787             : 
     788           0 :         return correct;
     789             : }
     790             : 
     791          18 : static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
     792             : {
     793          18 :         const char *lockfname = "\\torture2.lck";
     794             :         uint16_t fnum1;
     795             :         uint16_t fnum2;
     796             :         int i;
     797             :         char buf[131072];
     798             :         char buf_rd[131072];
     799          18 :         bool correct = True;
     800             :         size_t bytes_read;
     801             :         NTSTATUS status;
     802             : 
     803          18 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     804          18 :         if (!NT_STATUS_IS_OK(status)) {
     805          18 :                 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
     806             :         }
     807             : 
     808          18 :         status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
     809             :                           DENY_NONE, &fnum1);
     810          18 :         if (!NT_STATUS_IS_OK(status)) {
     811           0 :                 printf("first open read/write of %s failed (%s)\n",
     812             :                                 lockfname, nt_errstr(status));
     813           0 :                 return False;
     814             :         }
     815             : 
     816          18 :         status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
     817          18 :         if (!NT_STATUS_IS_OK(status)) {
     818           0 :                 printf("second open read-only of %s failed (%s)\n",
     819             :                                 lockfname, nt_errstr(status));
     820           0 :                 cli_close(c1, fnum1);
     821           0 :                 return False;
     822             :         }
     823             : 
     824        1818 :         for (i = 0; i < torture_numops; i++)
     825             :         {
     826        1800 :                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
     827        1800 :                 if (i % 10 == 0) {
     828         180 :                         printf("%d\r", i); fflush(stdout);
     829             :                 }
     830             : 
     831        1800 :                 generate_random_buffer((unsigned char *)buf, buf_size);
     832             : 
     833        1800 :                 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
     834             :                                       buf_size, NULL);
     835        1800 :                 if (!NT_STATUS_IS_OK(status)) {
     836           0 :                         printf("write failed (%s)\n", nt_errstr(status));
     837           0 :                         correct = False;
     838           0 :                         break;
     839             :                 }
     840             : 
     841        1800 :                 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
     842        1800 :                 if(!NT_STATUS_IS_OK(status)) {
     843           0 :                         printf("read failed (%s)\n", nt_errstr(status));
     844           0 :                         correct = false;
     845           0 :                         break;
     846        1800 :                 } else if (bytes_read != buf_size) {
     847           0 :                         printf("read failed\n");
     848           0 :                         printf("read %ld, expected %ld\n",
     849             :                                (unsigned long)bytes_read,
     850             :                                (unsigned long)buf_size); 
     851           0 :                         correct = False;
     852           0 :                         break;
     853             :                 }
     854             : 
     855        1800 :                 if (memcmp(buf_rd, buf, buf_size) != 0)
     856             :                 {
     857           0 :                         printf("read/write compare failed\n");
     858           0 :                         correct = False;
     859           0 :                         break;
     860             :                 }
     861             :         }
     862             : 
     863          18 :         status = cli_close(c2, fnum2);
     864          18 :         if (!NT_STATUS_IS_OK(status)) {
     865           0 :                 printf("close failed (%s)\n", nt_errstr(status));
     866           0 :                 correct = False;
     867             :         }
     868             : 
     869          18 :         status = cli_close(c1, fnum1);
     870          18 :         if (!NT_STATUS_IS_OK(status)) {
     871           0 :                 printf("close failed (%s)\n", nt_errstr(status));
     872           0 :                 correct = False;
     873             :         }
     874             : 
     875          18 :         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     876          18 :         if (!NT_STATUS_IS_OK(status)) {
     877           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
     878           0 :                 correct = False;
     879             :         }
     880             : 
     881          18 :         return correct;
     882             : }
     883             : 
     884           9 : static bool run_readwritetest(int dummy)
     885             : {
     886             :         struct cli_state *cli1, *cli2;
     887           9 :         bool test1, test2 = False;
     888             : 
     889           9 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
     890           0 :                 return False;
     891             :         }
     892           9 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
     893           9 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
     894             : 
     895           9 :         printf("starting readwritetest\n");
     896             : 
     897           9 :         test1 = rw_torture2(cli1, cli2);
     898           9 :         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
     899             : 
     900           9 :         if (test1) {
     901           9 :                 test2 = rw_torture2(cli1, cli1);
     902           9 :                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
     903             :         }
     904             : 
     905           9 :         if (!torture_close_connection(cli1)) {
     906           0 :                 test1 = False;
     907             :         }
     908             : 
     909           9 :         if (!torture_close_connection(cli2)) {
     910           0 :                 test2 = False;
     911             :         }
     912             : 
     913           9 :         return (test1 && test2);
     914             : }
     915             : 
     916           0 : static bool run_readwritemulti(int dummy)
     917             : {
     918             :         struct cli_state *cli;
     919             :         bool test;
     920             : 
     921           0 :         cli = current_cli;
     922             : 
     923           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
     924             : 
     925           0 :         printf("run_readwritemulti: fname %s\n", randomfname);
     926           0 :         test = rw_torture3(cli, randomfname);
     927             : 
     928           0 :         if (!torture_close_connection(cli)) {
     929           0 :                 test = False;
     930             :         }
     931             : 
     932           0 :         return test;
     933             : }
     934             : 
     935          14 : static bool run_readwritelarge_internal(void)
     936             : {
     937             :         static struct cli_state *cli1;
     938             :         uint16_t fnum1;
     939          14 :         const char *lockfname = "\\large.dat";
     940             :         off_t fsize;
     941             :         char buf[126*1024];
     942          14 :         bool correct = True;
     943             :         NTSTATUS status;
     944             : 
     945          14 :         if (!torture_open_connection(&cli1, 0)) {
     946           0 :                 return False;
     947             :         }
     948          14 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
     949          14 :         memset(buf,'\0',sizeof(buf));
     950             : 
     951          14 :         printf("starting readwritelarge_internal\n");
     952             : 
     953          14 :         cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     954             : 
     955          14 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
     956             :                           DENY_NONE, &fnum1);
     957          14 :         if (!NT_STATUS_IS_OK(status)) {
     958           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
     959           0 :                 return False;
     960             :         }
     961             : 
     962          14 :         cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
     963             : 
     964          14 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
     965             :                                      NULL, NULL, NULL);
     966          14 :         if (!NT_STATUS_IS_OK(status)) {
     967           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
     968           0 :                 correct = False;
     969             :         }
     970             : 
     971          14 :         if (fsize == sizeof(buf))
     972          14 :                 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
     973             :                        (unsigned long)fsize);
     974             :         else {
     975           0 :                 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
     976             :                        (unsigned long)fsize);
     977           0 :                 correct = False;
     978             :         }
     979             : 
     980          14 :         status = cli_close(cli1, fnum1);
     981          14 :         if (!NT_STATUS_IS_OK(status)) {
     982           0 :                 printf("close failed (%s)\n", nt_errstr(status));
     983           0 :                 correct = False;
     984             :         }
     985             : 
     986          14 :         status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
     987          14 :         if (!NT_STATUS_IS_OK(status)) {
     988           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
     989           0 :                 correct = False;
     990             :         }
     991             : 
     992          14 :         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
     993             :                           DENY_NONE, &fnum1);
     994          14 :         if (!NT_STATUS_IS_OK(status)) {
     995           0 :                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
     996           0 :                 return False;
     997             :         }
     998             : 
     999          14 :         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
    1000             : 
    1001          14 :         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
    1002             :                                      NULL, NULL, NULL);
    1003          14 :         if (!NT_STATUS_IS_OK(status)) {
    1004           0 :                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
    1005           0 :                 correct = False;
    1006             :         }
    1007             : 
    1008          14 :         if (fsize == sizeof(buf))
    1009          14 :                 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
    1010             :                        (unsigned long)fsize);
    1011             :         else {
    1012           0 :                 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
    1013             :                        (unsigned long)fsize);
    1014           0 :                 correct = False;
    1015             :         }
    1016             : 
    1017          14 :         status = cli_close(cli1, fnum1);
    1018          14 :         if (!NT_STATUS_IS_OK(status)) {
    1019           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1020           0 :                 correct = False;
    1021             :         }
    1022             : 
    1023          14 :         if (!torture_close_connection(cli1)) {
    1024           0 :                 correct = False;
    1025             :         }
    1026          14 :         return correct;
    1027             : }
    1028             : 
    1029           9 : static bool run_readwritelarge(int dummy)
    1030             : {
    1031           9 :         return run_readwritelarge_internal();
    1032             : }
    1033             : 
    1034           5 : static bool run_readwritelarge_signtest(int dummy)
    1035             : {
    1036             :         bool ret;
    1037           5 :         signing_state = SMB_SIGNING_REQUIRED;
    1038           5 :         ret = run_readwritelarge_internal();
    1039           5 :         signing_state = SMB_SIGNING_DEFAULT;
    1040           5 :         return ret;
    1041             : }
    1042             : 
    1043             : int line_count = 0;
    1044             : int nbio_id;
    1045             : 
    1046             : #define ival(s) strtol(s, NULL, 0)
    1047             : 
    1048             : /* run a test that simulates an approximate netbench client load */
    1049           0 : static bool run_netbench(int client)
    1050             : {
    1051             :         struct cli_state *cli;
    1052             :         int i;
    1053             :         char line[1024];
    1054             :         char cname[20];
    1055             :         FILE *f;
    1056             :         const char *params[20];
    1057           0 :         bool correct = True;
    1058             : 
    1059           0 :         cli = current_cli;
    1060             : 
    1061           0 :         nbio_id = client;
    1062             : 
    1063           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1064             : 
    1065           0 :         nb_setup(cli);
    1066             : 
    1067           0 :         slprintf(cname,sizeof(cname)-1, "client%d", client);
    1068             : 
    1069           0 :         f = fopen(client_txt, "r");
    1070             : 
    1071           0 :         if (!f) {
    1072           0 :                 perror(client_txt);
    1073           0 :                 return False;
    1074             :         }
    1075             : 
    1076           0 :         while (fgets(line, sizeof(line)-1, f)) {
    1077             :                 char *saveptr;
    1078           0 :                 line_count++;
    1079             : 
    1080           0 :                 line[strlen(line)-1] = 0;
    1081             : 
    1082             :                 /* printf("[%d] %s\n", line_count, line); */
    1083             : 
    1084           0 :                 all_string_sub(line,"client1", cname, sizeof(line));
    1085             : 
    1086             :                 /* parse the command parameters */
    1087           0 :                 params[0] = strtok_r(line, " ", &saveptr);
    1088           0 :                 i = 0;
    1089           0 :                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
    1090             : 
    1091           0 :                 params[i] = "";
    1092             : 
    1093           0 :                 if (i < 2) continue;
    1094             : 
    1095           0 :                 if (!strncmp(params[0],"SMB", 3)) {
    1096           0 :                         printf("ERROR: You are using a dbench 1 load file\n");
    1097           0 :                         exit(1);
    1098             :                 }
    1099             : 
    1100           0 :                 if (!strcmp(params[0],"NTCreateX")) {
    1101           0 :                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
    1102           0 :                                    ival(params[4]));
    1103           0 :                 } else if (!strcmp(params[0],"Close")) {
    1104           0 :                         nb_close(ival(params[1]));
    1105           0 :                 } else if (!strcmp(params[0],"Rename")) {
    1106           0 :                         nb_rename(params[1], params[2]);
    1107           0 :                 } else if (!strcmp(params[0],"Unlink")) {
    1108           0 :                         nb_unlink(params[1]);
    1109           0 :                 } else if (!strcmp(params[0],"Deltree")) {
    1110           0 :                         nb_deltree(params[1]);
    1111           0 :                 } else if (!strcmp(params[0],"Rmdir")) {
    1112           0 :                         nb_rmdir(params[1]);
    1113           0 :                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
    1114           0 :                         nb_qpathinfo(params[1]);
    1115           0 :                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
    1116           0 :                         nb_qfileinfo(ival(params[1]));
    1117           0 :                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
    1118           0 :                         nb_qfsinfo(ival(params[1]));
    1119           0 :                 } else if (!strcmp(params[0],"FIND_FIRST")) {
    1120           0 :                         nb_findfirst(params[1]);
    1121           0 :                 } else if (!strcmp(params[0],"WriteX")) {
    1122           0 :                         nb_writex(ival(params[1]), 
    1123           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1124           0 :                 } else if (!strcmp(params[0],"ReadX")) {
    1125           0 :                         nb_readx(ival(params[1]), 
    1126           0 :                                   ival(params[2]), ival(params[3]), ival(params[4]));
    1127           0 :                 } else if (!strcmp(params[0],"Flush")) {
    1128           0 :                         nb_flush(ival(params[1]));
    1129             :                 } else {
    1130           0 :                         printf("Unknown operation %s\n", params[0]);
    1131           0 :                         exit(1);
    1132             :                 }
    1133             :         }
    1134           0 :         fclose(f);
    1135             : 
    1136           0 :         nb_cleanup();
    1137             : 
    1138           0 :         if (!torture_close_connection(cli)) {
    1139           0 :                 correct = False;
    1140             :         }
    1141             : 
    1142           0 :         return correct;
    1143             : }
    1144             : 
    1145             : 
    1146             : /* run a test that simulates an approximate netbench client load */
    1147           0 : static bool run_nbench(int dummy)
    1148             : {
    1149             :         double t;
    1150           0 :         bool correct = True;
    1151             : 
    1152           0 :         nbio_shmem(torture_nprocs);
    1153             : 
    1154           0 :         nbio_id = -1;
    1155             : 
    1156           0 :         signal(SIGALRM, nb_alarm);
    1157           0 :         alarm(1);
    1158           0 :         t = create_procs(run_netbench, &correct);
    1159           0 :         alarm(0);
    1160             : 
    1161           0 :         printf("\nThroughput %g MB/sec\n", 
    1162           0 :                1.0e-6 * nbio_total() / t);
    1163           0 :         return correct;
    1164             : }
    1165             : 
    1166             : 
    1167             : /*
    1168             :   This test checks for two things:
    1169             : 
    1170             :   1) correct support for retaining locks over a close (ie. the server
    1171             :      must not use posix semantics)
    1172             :   2) support for lock timeouts
    1173             :  */
    1174           5 : static bool run_locktest1(int dummy)
    1175             : {
    1176             :         struct cli_state *cli1, *cli2;
    1177           5 :         const char *fname = "\\lockt1.lck";
    1178             :         uint16_t fnum1, fnum2, fnum3;
    1179             :         time_t t1, t2;
    1180             :         unsigned lock_timeout;
    1181             :         NTSTATUS status;
    1182             : 
    1183           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1184           0 :                 return False;
    1185             :         }
    1186           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1187           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1188             : 
    1189           5 :         printf("starting locktest1\n");
    1190             : 
    1191           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1192             : 
    1193           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1194             :                           &fnum1);
    1195           5 :         if (!NT_STATUS_IS_OK(status)) {
    1196           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1197           0 :                 return False;
    1198             :         }
    1199             : 
    1200           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
    1201           5 :         if (!NT_STATUS_IS_OK(status)) {
    1202           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1203           0 :                 return False;
    1204             :         }
    1205             : 
    1206           5 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
    1207           5 :         if (!NT_STATUS_IS_OK(status)) {
    1208           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1209           0 :                 return False;
    1210             :         }
    1211             : 
    1212           5 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    1213           5 :         if (!NT_STATUS_IS_OK(status)) {
    1214           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1215           0 :                 return false;
    1216             :         }
    1217             : 
    1218           5 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1219           5 :         if (NT_STATUS_IS_OK(status)) {
    1220           0 :                 printf("lock2 succeeded! This is a locking bug\n");
    1221           0 :                 return false;
    1222             :         } else {
    1223           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1224           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1225           0 :                         return false;
    1226             :                 }
    1227             :         }
    1228             : 
    1229           5 :         lock_timeout = (1 + (random() % 20));
    1230           5 :         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
    1231           5 :         t1 = time(NULL);
    1232           5 :         status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
    1233           5 :         if (NT_STATUS_IS_OK(status)) {
    1234           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1235           0 :                 return false;
    1236             :         } else {
    1237           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1238           5 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1239           0 :                         return false;
    1240             :                 }
    1241             :         }
    1242           5 :         t2 = time(NULL);
    1243             : 
    1244           5 :         if (ABS(t2 - t1) < lock_timeout-1) {
    1245           0 :                 printf("error: This server appears not to support timed lock requests\n");
    1246             :         }
    1247             : 
    1248           5 :         printf("server slept for %u seconds for a %u second timeout\n",
    1249             :                (unsigned int)(t2-t1), lock_timeout);
    1250             : 
    1251           5 :         status = cli_close(cli1, fnum2);
    1252           5 :         if (!NT_STATUS_IS_OK(status)) {
    1253           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1254           0 :                 return False;
    1255             :         }
    1256             : 
    1257           5 :         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
    1258           5 :         if (NT_STATUS_IS_OK(status)) {
    1259           0 :                 printf("lock4 succeeded! This is a locking bug\n");
    1260           0 :                 return false;
    1261             :         } else {
    1262           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1263           5 :                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
    1264           0 :                         return false;
    1265             :                 }
    1266             :         }
    1267             : 
    1268           5 :         status = cli_close(cli1, fnum1);
    1269           5 :         if (!NT_STATUS_IS_OK(status)) {
    1270           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1271           0 :                 return False;
    1272             :         }
    1273             : 
    1274           5 :         status = cli_close(cli2, fnum3);
    1275           5 :         if (!NT_STATUS_IS_OK(status)) {
    1276           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1277           0 :                 return False;
    1278             :         }
    1279             : 
    1280           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1281           5 :         if (!NT_STATUS_IS_OK(status)) {
    1282           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1283           0 :                 return False;
    1284             :         }
    1285             : 
    1286             : 
    1287           5 :         if (!torture_close_connection(cli1)) {
    1288           0 :                 return False;
    1289             :         }
    1290             : 
    1291           5 :         if (!torture_close_connection(cli2)) {
    1292           0 :                 return False;
    1293             :         }
    1294             : 
    1295           5 :         printf("Passed locktest1\n");
    1296           5 :         return True;
    1297             : }
    1298             : 
    1299             : /*
    1300             :   this checks to see if a secondary tconx can use open files from an
    1301             :   earlier tconx
    1302             :  */
    1303           5 : static bool run_tcon_test(int dummy)
    1304             : {
    1305             :         static struct cli_state *cli;
    1306           5 :         const char *fname = "\\tcontest.tmp";
    1307             :         uint16_t fnum1;
    1308             :         uint32_t cnum1, cnum2, cnum3;
    1309           5 :         struct smbXcli_tcon *orig_tcon = NULL;
    1310             :         uint16_t vuid1, vuid2;
    1311             :         char buf[4];
    1312           5 :         bool ret = True;
    1313             :         NTSTATUS status;
    1314             : 
    1315           5 :         memset(buf, '\0', sizeof(buf));
    1316             : 
    1317           5 :         if (!torture_open_connection(&cli, 0)) {
    1318           0 :                 return False;
    1319             :         }
    1320           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1321             : 
    1322           5 :         printf("starting tcontest\n");
    1323             : 
    1324           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1325             : 
    1326           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1327           5 :         if (!NT_STATUS_IS_OK(status)) {
    1328           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1329           0 :                 return False;
    1330             :         }
    1331             : 
    1332           5 :         cnum1 = cli_state_get_tid(cli);
    1333           5 :         vuid1 = cli_state_get_uid(cli);
    1334             : 
    1335           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1336           5 :         if (!NT_STATUS_IS_OK(status)) {
    1337           0 :                 printf("initial write failed (%s)", nt_errstr(status));
    1338           0 :                 return False;
    1339             :         }
    1340             : 
    1341           5 :         orig_tcon = cli_state_save_tcon(cli);
    1342           5 :         if (orig_tcon == NULL) {
    1343           0 :                 return false;
    1344             :         }
    1345             : 
    1346           5 :         status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
    1347           5 :         if (!NT_STATUS_IS_OK(status)) {
    1348           0 :                 printf("%s refused 2nd tree connect (%s)\n", host,
    1349             :                        nt_errstr(status));
    1350           0 :                 cli_state_restore_tcon(cli, orig_tcon);
    1351           0 :                 cli_shutdown(cli);
    1352           0 :                 return False;
    1353             :         }
    1354             : 
    1355           5 :         cnum2 = cli_state_get_tid(cli);
    1356           5 :         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
    1357           5 :         vuid2 = cli_state_get_uid(cli) + 1;
    1358             : 
    1359             :         /* try a write with the wrong tid */
    1360           5 :         cli_state_set_tid(cli, cnum2);
    1361             : 
    1362           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1363           5 :         if (NT_STATUS_IS_OK(status)) {
    1364           0 :                 printf("* server allows write with wrong TID\n");
    1365           0 :                 ret = False;
    1366             :         } else {
    1367           5 :                 printf("server fails write with wrong TID : %s\n",
    1368             :                        nt_errstr(status));
    1369             :         }
    1370             : 
    1371             : 
    1372             :         /* try a write with an invalid tid */
    1373           5 :         cli_state_set_tid(cli, cnum3);
    1374             : 
    1375           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1376           5 :         if (NT_STATUS_IS_OK(status)) {
    1377           0 :                 printf("* server allows write with invalid TID\n");
    1378           0 :                 ret = False;
    1379             :         } else {
    1380           5 :                 printf("server fails write with invalid TID : %s\n",
    1381             :                        nt_errstr(status));
    1382             :         }
    1383             : 
    1384             :         /* try a write with an invalid vuid */
    1385           5 :         cli_state_set_uid(cli, vuid2);
    1386           5 :         cli_state_set_tid(cli, cnum1);
    1387             : 
    1388           5 :         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    1389           5 :         if (NT_STATUS_IS_OK(status)) {
    1390           0 :                 printf("* server allows write with invalid VUID\n");
    1391           0 :                 ret = False;
    1392             :         } else {
    1393           5 :                 printf("server fails write with invalid VUID : %s\n",
    1394             :                        nt_errstr(status));
    1395             :         }
    1396             : 
    1397           5 :         cli_state_set_tid(cli, cnum1);
    1398           5 :         cli_state_set_uid(cli, vuid1);
    1399             : 
    1400           5 :         status = cli_close(cli, fnum1);
    1401           5 :         if (!NT_STATUS_IS_OK(status)) {
    1402           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    1403           0 :                 cli_state_restore_tcon(cli, orig_tcon);
    1404           0 :                 cli_shutdown(cli);
    1405           0 :                 return False;
    1406             :         }
    1407             : 
    1408           5 :         cli_state_set_tid(cli, cnum2);
    1409             : 
    1410           5 :         status = cli_tdis(cli);
    1411           5 :         if (!NT_STATUS_IS_OK(status)) {
    1412           0 :                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
    1413           0 :                 cli_state_restore_tcon(cli, orig_tcon);
    1414           0 :                 cli_shutdown(cli);
    1415           0 :                 return False;
    1416             :         }
    1417             : 
    1418           5 :         cli_state_restore_tcon(cli, orig_tcon);
    1419             : 
    1420           5 :         cli_state_set_tid(cli, cnum1);
    1421             : 
    1422           5 :         if (!torture_close_connection(cli)) {
    1423           0 :                 return False;
    1424             :         }
    1425             : 
    1426           5 :         return ret;
    1427             : }
    1428             : 
    1429             : 
    1430             : /*
    1431             :  checks for old style tcon support
    1432             :  */
    1433           5 : static bool run_tcon2_test(int dummy)
    1434             : {
    1435             :         static struct cli_state *cli;
    1436             :         uint16_t cnum, max_xmit;
    1437             :         char *service;
    1438             :         NTSTATUS status;
    1439             : 
    1440           5 :         if (!torture_open_connection(&cli, 0)) {
    1441           0 :                 return False;
    1442             :         }
    1443           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1444             : 
    1445           5 :         printf("starting tcon2 test\n");
    1446             : 
    1447           5 :         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
    1448           0 :                 return false;
    1449             :         }
    1450             : 
    1451           5 :         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
    1452             : 
    1453           5 :         SAFE_FREE(service);
    1454             : 
    1455           5 :         if (!NT_STATUS_IS_OK(status)) {
    1456           5 :                 printf("tcon2 failed : %s\n", nt_errstr(status));
    1457             :         } else {
    1458           0 :                 printf("tcon OK : max_xmit=%d cnum=%d\n",
    1459             :                        (int)max_xmit, (int)cnum);
    1460             :         }
    1461             : 
    1462           5 :         if (!torture_close_connection(cli)) {
    1463           0 :                 return False;
    1464             :         }
    1465             : 
    1466           5 :         printf("Passed tcon2 test\n");
    1467           5 :         return True;
    1468             : }
    1469             : 
    1470          50 : static bool tcon_devtest(struct cli_state *cli,
    1471             :                          const char *myshare, const char *devtype,
    1472             :                          const char *return_devtype,
    1473             :                          NTSTATUS expected_error)
    1474             : {
    1475             :         NTSTATUS status;
    1476             :         bool ret;
    1477             : 
    1478          50 :         status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
    1479             : 
    1480          50 :         if (NT_STATUS_IS_OK(expected_error)) {
    1481          20 :                 if (NT_STATUS_IS_OK(status)) {
    1482          40 :                         if (return_devtype != NULL &&
    1483          20 :                             strequal(cli->dev, return_devtype)) {
    1484          20 :                                 ret = True;
    1485             :                         } else { 
    1486           0 :                                 printf("tconX to share %s with type %s "
    1487             :                                        "succeeded but returned the wrong "
    1488             :                                        "device type (got [%s] but should have got [%s])\n",
    1489             :                                        myshare, devtype, cli->dev, return_devtype);
    1490           0 :                                 ret = False;
    1491             :                         }
    1492             :                 } else {
    1493           0 :                         printf("tconX to share %s with type %s "
    1494             :                                "should have succeeded but failed\n",
    1495             :                                myshare, devtype);
    1496           0 :                         ret = False;
    1497             :                 }
    1498          20 :                 cli_tdis(cli);
    1499             :         } else {
    1500          30 :                 if (NT_STATUS_IS_OK(status)) {
    1501           0 :                         printf("tconx to share %s with type %s "
    1502             :                                "should have failed but succeeded\n",
    1503             :                                myshare, devtype);
    1504           0 :                         ret = False;
    1505             :                 } else {
    1506          30 :                         if (NT_STATUS_EQUAL(status, expected_error)) {
    1507          30 :                                 ret = True;
    1508             :                         } else {
    1509           0 :                                 printf("Returned unexpected error\n");
    1510           0 :                                 ret = False;
    1511             :                         }
    1512             :                 }
    1513             :         }
    1514          50 :         return ret;
    1515             : }
    1516             : 
    1517             : /*
    1518             :  checks for correct tconX support
    1519             :  */
    1520           5 : static bool run_tcon_devtype_test(int dummy)
    1521             : {
    1522             :         static struct cli_state *cli1 = NULL;
    1523           5 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
    1524             :         NTSTATUS status;
    1525           5 :         bool ret = True;
    1526             : 
    1527           5 :         status = cli_full_connection_creds(&cli1,
    1528             :                                            myname,
    1529             :                                            host,
    1530             :                                            NULL, /* dest_ss */
    1531             :                                            port_to_use,
    1532             :                                            NULL, /* service */
    1533             :                                            NULL, /* service_type */
    1534             :                                            torture_creds,
    1535             :                                            flags);
    1536             : 
    1537           5 :         if (!NT_STATUS_IS_OK(status)) {
    1538           0 :                 printf("could not open connection\n");
    1539           0 :                 return False;
    1540             :         }
    1541             : 
    1542           5 :         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1543           0 :                 ret = False;
    1544             : 
    1545           5 :         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
    1546           0 :                 ret = False;
    1547             : 
    1548           5 :         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1549           0 :                 ret = False;
    1550             : 
    1551           5 :         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
    1552           0 :                 ret = False;
    1553             : 
    1554           5 :         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1555           0 :                 ret = False;
    1556             : 
    1557           5 :         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
    1558           0 :                 ret = False;
    1559             : 
    1560           5 :         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
    1561           0 :                 ret = False;
    1562             : 
    1563           5 :         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1564           0 :                 ret = False;
    1565             : 
    1566           5 :         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1567           0 :                 ret = False;
    1568             : 
    1569           5 :         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
    1570           0 :                 ret = False;
    1571             : 
    1572           5 :         cli_shutdown(cli1);
    1573             : 
    1574           5 :         if (ret)
    1575           5 :                 printf("Passed tcondevtest\n");
    1576             : 
    1577           5 :         return ret;
    1578             : }
    1579             : 
    1580             : 
    1581             : /*
    1582             :   This test checks that 
    1583             : 
    1584             :   1) the server supports multiple locking contexts on the one SMB
    1585             :   connection, distinguished by PID.  
    1586             : 
    1587             :   2) the server correctly fails overlapping locks made by the same PID (this
    1588             :      goes against POSIX behaviour, which is why it is tricky to implement)
    1589             : 
    1590             :   3) the server denies unlock requests by an incorrect client PID
    1591             : */
    1592           5 : static bool run_locktest2(int dummy)
    1593             : {
    1594             :         static struct cli_state *cli;
    1595           5 :         const char *fname = "\\lockt2.lck";
    1596             :         uint16_t fnum1, fnum2, fnum3;
    1597           5 :         bool correct = True;
    1598             :         NTSTATUS status;
    1599             : 
    1600           5 :         if (!torture_open_connection(&cli, 0)) {
    1601           0 :                 return False;
    1602             :         }
    1603             : 
    1604           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    1605             : 
    1606           5 :         printf("starting locktest2\n");
    1607             : 
    1608           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1609             : 
    1610           5 :         cli_setpid(cli, 1);
    1611             : 
    1612           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1613           5 :         if (!NT_STATUS_IS_OK(status)) {
    1614           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1615           0 :                 return False;
    1616             :         }
    1617             : 
    1618           5 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
    1619           5 :         if (!NT_STATUS_IS_OK(status)) {
    1620           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1621           0 :                 return False;
    1622             :         }
    1623             : 
    1624           5 :         cli_setpid(cli, 2);
    1625             : 
    1626           5 :         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
    1627           5 :         if (!NT_STATUS_IS_OK(status)) {
    1628           0 :                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
    1629           0 :                 return False;
    1630             :         }
    1631             : 
    1632           5 :         cli_setpid(cli, 1);
    1633             : 
    1634           5 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1635           5 :         if (!NT_STATUS_IS_OK(status)) {
    1636           0 :                 printf("lock1 failed (%s)\n", nt_errstr(status));
    1637           0 :                 return false;
    1638             :         }
    1639             : 
    1640           5 :         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
    1641           5 :         if (NT_STATUS_IS_OK(status)) {
    1642           0 :                 printf("WRITE lock1 succeeded! This is a locking bug\n");
    1643           0 :                 correct = false;
    1644             :         } else {
    1645           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1646           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1647           0 :                         return false;
    1648             :                 }
    1649             :         }
    1650             : 
    1651           5 :         status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
    1652           5 :         if (NT_STATUS_IS_OK(status)) {
    1653           0 :                 printf("WRITE lock2 succeeded! This is a locking bug\n");
    1654           0 :                 correct = false;
    1655             :         } else {
    1656           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1657           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1658           0 :                         return false;
    1659             :                 }
    1660             :         }
    1661             : 
    1662           5 :         status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
    1663           5 :         if (NT_STATUS_IS_OK(status)) {
    1664           0 :                 printf("READ lock2 succeeded! This is a locking bug\n");
    1665           0 :                 correct = false;
    1666             :         } else {
    1667           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1668           5 :                                  NT_STATUS_FILE_LOCK_CONFLICT)) {
    1669           0 :                         return false;
    1670             :                 }
    1671             :         }
    1672             : 
    1673           5 :         status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
    1674           5 :         if (!NT_STATUS_IS_OK(status)) {
    1675           0 :                 printf("lock at 100 failed (%s)\n", nt_errstr(status));
    1676             :         }
    1677           5 :         cli_setpid(cli, 2);
    1678           5 :         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
    1679           0 :                 printf("unlock at 100 succeeded! This is a locking bug\n");
    1680           0 :                 correct = False;
    1681             :         }
    1682             : 
    1683           5 :         status = cli_unlock(cli, fnum1, 0, 4);
    1684           5 :         if (NT_STATUS_IS_OK(status)) {
    1685           0 :                 printf("unlock1 succeeded! This is a locking bug\n");
    1686           0 :                 correct = false;
    1687             :         } else {
    1688           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1689           5 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1690           0 :                         return false;
    1691             :                 }
    1692             :         }
    1693             : 
    1694           5 :         status = cli_unlock(cli, fnum1, 0, 8);
    1695           5 :         if (NT_STATUS_IS_OK(status)) {
    1696           0 :                 printf("unlock2 succeeded! This is a locking bug\n");
    1697           0 :                 correct = false;
    1698             :         } else {
    1699           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1700           5 :                                       NT_STATUS_RANGE_NOT_LOCKED)) {
    1701           0 :                         return false;
    1702             :                 }
    1703             :         }
    1704             : 
    1705           5 :         status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
    1706           5 :         if (NT_STATUS_IS_OK(status)) {
    1707           0 :                 printf("lock3 succeeded! This is a locking bug\n");
    1708           0 :                 correct = false;
    1709             :         } else {
    1710           5 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
    1711           5 :                                       NT_STATUS_LOCK_NOT_GRANTED)) {
    1712           0 :                         return false;
    1713             :                 }
    1714             :         }
    1715             : 
    1716           5 :         cli_setpid(cli, 1);
    1717             : 
    1718           5 :         status = cli_close(cli, fnum1);
    1719           5 :         if (!NT_STATUS_IS_OK(status)) {
    1720           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1721           0 :                 return False;
    1722             :         }
    1723             : 
    1724           5 :         status = cli_close(cli, fnum2);
    1725           5 :         if (!NT_STATUS_IS_OK(status)) {
    1726           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1727           0 :                 return False;
    1728             :         }
    1729             : 
    1730           5 :         status = cli_close(cli, fnum3);
    1731           5 :         if (!NT_STATUS_IS_OK(status)) {
    1732           0 :                 printf("close3 failed (%s)\n", nt_errstr(status));
    1733           0 :                 return False;
    1734             :         }
    1735             : 
    1736           5 :         if (!torture_close_connection(cli)) {
    1737           0 :                 correct = False;
    1738             :         }
    1739             : 
    1740           5 :         printf("locktest2 finished\n");
    1741             : 
    1742           5 :         return correct;
    1743             : }
    1744             : 
    1745             : 
    1746             : /*
    1747             :   This test checks that 
    1748             : 
    1749             :   1) the server supports the full offset range in lock requests
    1750             : */
    1751           5 : static bool run_locktest3(int dummy)
    1752             : {
    1753             :         static struct cli_state *cli1, *cli2;
    1754           5 :         const char *fname = "\\lockt3.lck";
    1755             :         uint16_t fnum1, fnum2;
    1756             :         int i;
    1757             :         uint32_t offset;
    1758           5 :         bool correct = True;
    1759             :         NTSTATUS status;
    1760             : 
    1761             : #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
    1762             : 
    1763           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1764           0 :                 return False;
    1765             :         }
    1766           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1767           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1768             : 
    1769           5 :         printf("starting locktest3\n");
    1770             : 
    1771           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1772             : 
    1773           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    1774             :                          &fnum1);
    1775           5 :         if (!NT_STATUS_IS_OK(status)) {
    1776           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    1777           0 :                 return False;
    1778             :         }
    1779             : 
    1780           5 :         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    1781           5 :         if (!NT_STATUS_IS_OK(status)) {
    1782           0 :                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
    1783           0 :                 return False;
    1784             :         }
    1785             : 
    1786         505 :         for (offset=i=0;i<torture_numops;i++) {
    1787         500 :                 NEXT_OFFSET;
    1788             : 
    1789         500 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    1790         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1791           0 :                         printf("lock1 %d failed (%s)\n", 
    1792             :                                i,
    1793             :                                nt_errstr(status));
    1794           0 :                         return False;
    1795             :                 }
    1796             : 
    1797         500 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    1798         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1799           0 :                         printf("lock2 %d failed (%s)\n", 
    1800             :                                i,
    1801             :                                nt_errstr(status));
    1802           0 :                         return False;
    1803             :                 }
    1804             :         }
    1805             : 
    1806         505 :         for (offset=i=0;i<torture_numops;i++) {
    1807         500 :                 NEXT_OFFSET;
    1808             : 
    1809         500 :                 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
    1810         500 :                 if (NT_STATUS_IS_OK(status)) {
    1811           0 :                         printf("error: lock1 %d succeeded!\n", i);
    1812           0 :                         return False;
    1813             :                 }
    1814             : 
    1815         500 :                 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
    1816         500 :                 if (NT_STATUS_IS_OK(status)) {
    1817           0 :                         printf("error: lock2 %d succeeded!\n", i);
    1818           0 :                         return False;
    1819             :                 }
    1820             : 
    1821         500 :                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
    1822         500 :                 if (NT_STATUS_IS_OK(status)) {
    1823           0 :                         printf("error: lock3 %d succeeded!\n", i);
    1824           0 :                         return False;
    1825             :                 }
    1826             : 
    1827         500 :                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
    1828         500 :                 if (NT_STATUS_IS_OK(status)) {
    1829           0 :                         printf("error: lock4 %d succeeded!\n", i);
    1830           0 :                         return False;
    1831             :                 }
    1832             :         }
    1833             : 
    1834         505 :         for (offset=i=0;i<torture_numops;i++) {
    1835         500 :                 NEXT_OFFSET;
    1836             : 
    1837         500 :                 status = cli_unlock(cli1, fnum1, offset-1, 1);
    1838         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1839           0 :                         printf("unlock1 %d failed (%s)\n", 
    1840             :                                i,
    1841             :                                nt_errstr(status));
    1842           0 :                         return False;
    1843             :                 }
    1844             : 
    1845         500 :                 status = cli_unlock(cli2, fnum2, offset-2, 1);
    1846         500 :                 if (!NT_STATUS_IS_OK(status)) {
    1847           0 :                         printf("unlock2 %d failed (%s)\n", 
    1848             :                                i,
    1849             :                                nt_errstr(status));
    1850           0 :                         return False;
    1851             :                 }
    1852             :         }
    1853             : 
    1854           5 :         status = cli_close(cli1, fnum1);
    1855           5 :         if (!NT_STATUS_IS_OK(status)) {
    1856           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    1857           0 :                 return False;
    1858             :         }
    1859             : 
    1860           5 :         status = cli_close(cli2, fnum2);
    1861           5 :         if (!NT_STATUS_IS_OK(status)) {
    1862           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    1863           0 :                 return False;
    1864             :         }
    1865             : 
    1866           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1867           5 :         if (!NT_STATUS_IS_OK(status)) {
    1868           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    1869           0 :                 return False;
    1870             :         }
    1871             : 
    1872           5 :         if (!torture_close_connection(cli1)) {
    1873           0 :                 correct = False;
    1874             :         }
    1875             : 
    1876           5 :         if (!torture_close_connection(cli2)) {
    1877           0 :                 correct = False;
    1878             :         }
    1879             : 
    1880           5 :         printf("finished locktest3\n");
    1881             : 
    1882           5 :         return correct;
    1883             : }
    1884             : 
    1885          40 : static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
    1886             :                            char *buf, off_t offset, size_t size,
    1887             :                            size_t *nread, size_t expect)
    1888             : {
    1889             :         NTSTATUS status;
    1890             :         size_t l_nread;
    1891             : 
    1892          40 :         status = cli_read(cli, fnum, buf, offset, size, &l_nread);
    1893             : 
    1894          40 :         if(!NT_STATUS_IS_OK(status)) {
    1895          20 :                 return false;
    1896          20 :         } else if (l_nread != expect) {
    1897           0 :                 return false;
    1898             :         }
    1899             : 
    1900          20 :         if (nread) {
    1901           0 :                 *nread = l_nread;
    1902             :         }
    1903             : 
    1904          20 :         return true;
    1905             : }
    1906             : 
    1907             : #define EXPECTED(ret, v) if ((ret) != (v)) { \
    1908             :         printf("** "); correct = False; \
    1909             :         }
    1910             : 
    1911             : /*
    1912             :   looks at overlapping locks
    1913             : */
    1914           5 : static bool run_locktest4(int dummy)
    1915             : {
    1916             :         static struct cli_state *cli1, *cli2;
    1917           5 :         const char *fname = "\\lockt4.lck";
    1918             :         uint16_t fnum1, fnum2, f;
    1919             :         bool ret;
    1920             :         char buf[1000];
    1921           5 :         bool correct = True;
    1922             :         NTSTATUS status;
    1923             : 
    1924           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    1925           0 :                 return False;
    1926             :         }
    1927             : 
    1928           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    1929           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    1930             : 
    1931           5 :         printf("starting locktest4\n");
    1932             : 
    1933           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    1934             : 
    1935           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    1936           5 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    1937             : 
    1938           5 :         memset(buf, 0, sizeof(buf));
    1939             : 
    1940           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    1941             :                               NULL);
    1942           5 :         if (!NT_STATUS_IS_OK(status)) {
    1943           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    1944           0 :                 correct = False;
    1945           0 :                 goto fail;
    1946             :         }
    1947             : 
    1948          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    1949           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
    1950           5 :         EXPECTED(ret, False);
    1951           5 :         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
    1952             : 
    1953          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
    1954           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
    1955           5 :         EXPECTED(ret, True);
    1956           5 :         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
    1957             : 
    1958          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
    1959           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
    1960           5 :         EXPECTED(ret, False);
    1961           5 :         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
    1962             : 
    1963          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
    1964           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
    1965           5 :         EXPECTED(ret, True);
    1966           5 :         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
    1967             : 
    1968          10 :         ret = (cli_setpid(cli1, 1),
    1969          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
    1970           5 :               (cli_setpid(cli1, 2),
    1971           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
    1972           5 :         EXPECTED(ret, False);
    1973           5 :         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
    1974             : 
    1975          10 :         ret = (cli_setpid(cli1, 1),
    1976          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
    1977           5 :               (cli_setpid(cli1, 2),
    1978           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
    1979           5 :         EXPECTED(ret, True);
    1980           5 :         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
    1981             : 
    1982          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
    1983           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
    1984           5 :         EXPECTED(ret, True);
    1985           5 :         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
    1986             : 
    1987          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
    1988           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
    1989           5 :         EXPECTED(ret, False);
    1990           5 :         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
    1991             : 
    1992          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
    1993           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
    1994           5 :         EXPECTED(ret, False);
    1995           5 :         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
    1996             : 
    1997          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
    1998           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
    1999           5 :         EXPECTED(ret, True);
    2000           5 :         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2001             : 
    2002          10 :         ret = (cli_setpid(cli1, 1),
    2003          10 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
    2004           5 :              (cli_setpid(cli1, 2),
    2005           5 :              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
    2006           5 :         EXPECTED(ret, False);
    2007           5 :         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
    2008             : 
    2009          15 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
    2010          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
    2011           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
    2012           5 :         EXPECTED(ret, False);
    2013           5 :         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
    2014             : 
    2015             : 
    2016          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
    2017           5 :               test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
    2018           5 :         EXPECTED(ret, False);
    2019           5 :         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
    2020             : 
    2021           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2022           5 :         ret = NT_STATUS_IS_OK(status);
    2023           5 :         if (ret) {
    2024           5 :                 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
    2025             :                                       NULL);
    2026           5 :                 ret = NT_STATUS_IS_OK(status);
    2027             :         }
    2028           5 :         EXPECTED(ret, False);
    2029           5 :         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
    2030             : 
    2031             : 
    2032          15 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2033          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
    2034          15 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
    2035           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
    2036           5 :         EXPECTED(ret, True);
    2037           5 :         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
    2038             : 
    2039             : 
    2040          15 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
    2041          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
    2042          10 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
    2043          10 :               test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
    2044           5 :               !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2045          10 :                                              150, 4, NULL))) &&
    2046           5 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
    2047           5 :         EXPECTED(ret, True);
    2048           5 :         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
    2049             : 
    2050          15 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
    2051          10 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
    2052           5 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2053          10 :                                            160, 4, NULL)) &&
    2054           5 :               test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
    2055           5 :         EXPECTED(ret, True);
    2056           5 :         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
    2057             : 
    2058          15 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
    2059          10 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
    2060           5 :               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2061          10 :                                            170, 4, NULL)) &&
    2062           5 :               test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
    2063           5 :         EXPECTED(ret, True);
    2064           5 :         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
    2065             : 
    2066          15 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
    2067          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
    2068          10 :               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
    2069           5 :               !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
    2070          10 :                                             190, 4, NULL)) &&
    2071           5 :               test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
    2072           5 :         EXPECTED(ret, True);
    2073           5 :         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
    2074             : 
    2075           5 :         cli_close(cli1, fnum1);
    2076           5 :         cli_close(cli2, fnum2);
    2077           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2078           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
    2079          15 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2080          10 :               NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
    2081          10 :               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
    2082          15 :               NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
    2083           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
    2084           5 :         cli_close(cli1, f);
    2085           5 :         cli_close(cli1, fnum1);
    2086           5 :         EXPECTED(ret, True);
    2087           5 :         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
    2088             : 
    2089           5 :  fail:
    2090           5 :         cli_close(cli1, fnum1);
    2091           5 :         cli_close(cli2, fnum2);
    2092           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2093           5 :         torture_close_connection(cli1);
    2094           5 :         torture_close_connection(cli2);
    2095             : 
    2096           5 :         printf("finished locktest4\n");
    2097           5 :         return correct;
    2098             : }
    2099             : 
    2100             : /*
    2101             :   looks at lock upgrade/downgrade.
    2102             : */
    2103           5 : static bool run_locktest5(int dummy)
    2104             : {
    2105             :         static struct cli_state *cli1, *cli2;
    2106           5 :         const char *fname = "\\lockt5.lck";
    2107             :         uint16_t fnum1, fnum2, fnum3;
    2108             :         bool ret;
    2109             :         char buf[1000];
    2110           5 :         bool correct = True;
    2111             :         NTSTATUS status;
    2112             : 
    2113           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    2114           0 :                 return False;
    2115             :         }
    2116             : 
    2117           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2118           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2119             : 
    2120           5 :         printf("starting locktest5\n");
    2121             : 
    2122           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2123             : 
    2124           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2125           5 :         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    2126           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
    2127             : 
    2128           5 :         memset(buf, 0, sizeof(buf));
    2129             : 
    2130           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2131             :                               NULL);
    2132           5 :         if (!NT_STATUS_IS_OK(status)) {
    2133           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2134           0 :                 correct = False;
    2135           0 :                 goto fail;
    2136             :         }
    2137             : 
    2138             :         /* Check for NT bug... */
    2139          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
    2140           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
    2141           5 :         cli_close(cli1, fnum1);
    2142           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2143           5 :         status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
    2144           5 :         ret = NT_STATUS_IS_OK(status);
    2145           5 :         EXPECTED(ret, True);
    2146           5 :         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
    2147           5 :         cli_close(cli1, fnum1);
    2148           5 :         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2149           5 :         cli_unlock(cli1, fnum3, 0, 1);
    2150             : 
    2151          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
    2152           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
    2153           5 :         EXPECTED(ret, True);
    2154           5 :         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
    2155             : 
    2156           5 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
    2157           5 :         ret = NT_STATUS_IS_OK(status);
    2158           5 :         EXPECTED(ret, False);
    2159             : 
    2160           5 :         printf("a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
    2161             : 
    2162             :         /* Unlock the process 2 lock. */
    2163           5 :         cli_unlock(cli2, fnum2, 0, 4);
    2164             : 
    2165           5 :         status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
    2166           5 :         ret = NT_STATUS_IS_OK(status);
    2167           5 :         EXPECTED(ret, False);
    2168             : 
    2169           5 :         printf("the same process on a different fnum %s get a read lock\n", ret?"can":"cannot");
    2170             : 
    2171             :         /* Unlock the process 1 fnum3 lock. */
    2172           5 :         cli_unlock(cli1, fnum3, 0, 4);
    2173             : 
    2174             :         /* Stack 2 more locks here. */
    2175          10 :         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
    2176           5 :               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
    2177             : 
    2178           5 :         EXPECTED(ret, True);
    2179           5 :         printf("the same process %s stack read locks\n", ret?"can":"cannot");
    2180             : 
    2181             :         /* Unlock the first process lock, then check this was the WRITE lock that was
    2182             :                 removed. */
    2183             : 
    2184          10 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2185           5 :               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
    2186             : 
    2187           5 :         EXPECTED(ret, True);
    2188           5 :         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
    2189             : 
    2190             :         /* Unlock the process 2 lock. */
    2191           5 :         cli_unlock(cli2, fnum2, 0, 4);
    2192             : 
    2193             :         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
    2194             : 
    2195          15 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
    2196          10 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
    2197           5 :                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2198             : 
    2199           5 :         EXPECTED(ret, True);
    2200           5 :         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
    2201             : 
    2202             :         /* Ensure the next unlock fails. */
    2203           5 :         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
    2204           5 :         EXPECTED(ret, False);
    2205           5 :         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
    2206             : 
    2207             :         /* Ensure connection 2 can get a write lock. */
    2208           5 :         status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
    2209           5 :         ret = NT_STATUS_IS_OK(status);
    2210           5 :         EXPECTED(ret, True);
    2211             : 
    2212           5 :         printf("a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
    2213             : 
    2214             : 
    2215           5 :  fail:
    2216           5 :         cli_close(cli1, fnum1);
    2217           5 :         cli_close(cli2, fnum2);
    2218           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2219           5 :         if (!torture_close_connection(cli1)) {
    2220           0 :                 correct = False;
    2221             :         }
    2222           5 :         if (!torture_close_connection(cli2)) {
    2223           0 :                 correct = False;
    2224             :         }
    2225             : 
    2226           5 :         printf("finished locktest5\n");
    2227             : 
    2228           5 :         return correct;
    2229             : }
    2230             : 
    2231             : /*
    2232             :   tries the unusual lockingX locktype bits
    2233             : */
    2234           5 : static bool run_locktest6(int dummy)
    2235             : {
    2236             :         static struct cli_state *cli;
    2237           5 :         const char *fname[1] = { "\\lock6.txt" };
    2238             :         int i;
    2239             :         uint16_t fnum;
    2240             :         NTSTATUS status;
    2241             : 
    2242           5 :         if (!torture_open_connection(&cli, 0)) {
    2243           0 :                 return False;
    2244             :         }
    2245             : 
    2246           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    2247             : 
    2248           5 :         printf("starting locktest6\n");
    2249             : 
    2250          10 :         for (i=0;i<1;i++) {
    2251           5 :                 printf("Testing %s\n", fname[i]);
    2252             : 
    2253           5 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2254             : 
    2255           5 :                 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    2256           5 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
    2257           5 :                 cli_close(cli, fnum);
    2258           5 :                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
    2259             : 
    2260           5 :                 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
    2261           5 :                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
    2262           5 :                 cli_close(cli, fnum);
    2263           5 :                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
    2264             : 
    2265           5 :                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2266             :         }
    2267             : 
    2268           5 :         torture_close_connection(cli);
    2269             : 
    2270           5 :         printf("finished locktest6\n");
    2271           5 :         return True;
    2272             : }
    2273             : 
    2274           5 : static bool run_locktest7(int dummy)
    2275             : {
    2276             :         struct cli_state *cli1;
    2277           5 :         const char *fname = "\\lockt7.lck";
    2278             :         uint16_t fnum1;
    2279             :         char buf[200];
    2280           5 :         bool correct = False;
    2281             :         size_t nread;
    2282             :         NTSTATUS status;
    2283             : 
    2284           5 :         if (!torture_open_connection(&cli1, 0)) {
    2285           0 :                 return False;
    2286             :         }
    2287             : 
    2288           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2289             : 
    2290           5 :         printf("starting locktest7\n");
    2291             : 
    2292           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2293             : 
    2294           5 :         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    2295             : 
    2296           5 :         memset(buf, 0, sizeof(buf));
    2297             : 
    2298           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
    2299             :                               NULL);
    2300           5 :         if (!NT_STATUS_IS_OK(status)) {
    2301           0 :                 printf("Failed to create file: %s\n", nt_errstr(status));
    2302           0 :                 goto fail;
    2303             :         }
    2304             : 
    2305           5 :         cli_setpid(cli1, 1);
    2306             : 
    2307           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
    2308           5 :         if (!NT_STATUS_IS_OK(status)) {
    2309           0 :                 printf("Unable to apply read lock on range 130:4, "
    2310             :                        "error was %s\n", nt_errstr(status));
    2311           0 :                 goto fail;
    2312             :         } else {
    2313           5 :                 printf("pid1 successfully locked range 130:4 for READ\n");
    2314             :         }
    2315             : 
    2316           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2317           5 :         if (!NT_STATUS_IS_OK(status)) {
    2318           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2319             :                       nt_errstr(status));
    2320           0 :                 goto fail;
    2321           5 :         } else if (nread != 4) {
    2322           0 :                 printf("pid1 unable to read the range 130:4, "
    2323             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2324           0 :                 goto fail;
    2325             :         } else {
    2326           5 :                 printf("pid1 successfully read the range 130:4\n");
    2327             :         }
    2328             : 
    2329           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2330           5 :         if (!NT_STATUS_IS_OK(status)) {
    2331           5 :                 printf("pid1 unable to write to the range 130:4, error was "
    2332             :                        "%s\n", nt_errstr(status));
    2333           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2334           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2335           0 :                         goto fail;
    2336             :                 }
    2337             :         } else {
    2338           0 :                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
    2339           0 :                 goto fail;
    2340             :         }
    2341             : 
    2342           5 :         cli_setpid(cli1, 2);
    2343             : 
    2344           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2345           5 :         if (!NT_STATUS_IS_OK(status)) {
    2346           0 :                 printf("pid2 unable to read the range 130:4, error was %s\n",
    2347             :                       nt_errstr(status));
    2348           0 :                 goto fail;
    2349           5 :         } else if (nread != 4) {
    2350           0 :                 printf("pid2 unable to read the range 130:4, "
    2351             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2352           0 :                 goto fail;
    2353             :         } else {
    2354           5 :                 printf("pid2 successfully read the range 130:4\n");
    2355             :         }
    2356             : 
    2357           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2358           5 :         if (!NT_STATUS_IS_OK(status)) {
    2359           5 :                 printf("pid2 unable to write to the range 130:4, error was "
    2360             :                        "%s\n", nt_errstr(status));
    2361           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2362           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2363           0 :                         goto fail;
    2364             :                 }
    2365             :         } else {
    2366           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2367           0 :                 goto fail;
    2368             :         }
    2369             : 
    2370           5 :         cli_setpid(cli1, 1);
    2371           5 :         cli_unlock(cli1, fnum1, 130, 4);
    2372             : 
    2373           5 :         status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
    2374           5 :         if (!NT_STATUS_IS_OK(status)) {
    2375           0 :                 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
    2376           0 :                 goto fail;
    2377             :         } else {
    2378           5 :                 printf("pid1 successfully locked range 130:4 for WRITE\n");
    2379             :         }
    2380             : 
    2381           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2382           5 :         if (!NT_STATUS_IS_OK(status)) {
    2383           0 :                 printf("pid1 unable to read the range 130:4, error was %s\n",
    2384             :                       nt_errstr(status));
    2385           0 :                 goto fail;
    2386           5 :         } else if (nread != 4) {
    2387           0 :                 printf("pid1 unable to read the range 130:4, "
    2388             :                        "recv %ld req %d\n", (unsigned long)nread, 4);
    2389           0 :                 goto fail;
    2390             :         } else {
    2391           5 :                 printf("pid1 successfully read the range 130:4\n");
    2392             :         }
    2393             : 
    2394           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2395           5 :         if (!NT_STATUS_IS_OK(status)) {
    2396           0 :                 printf("pid1 unable to write to the range 130:4, error was "
    2397             :                        "%s\n", nt_errstr(status));
    2398           0 :                 goto fail;
    2399             :         } else {
    2400           5 :                 printf("pid1 successfully wrote to the range 130:4\n");
    2401             :         }
    2402             : 
    2403           5 :         cli_setpid(cli1, 2);
    2404             : 
    2405           5 :         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
    2406           5 :         if (!NT_STATUS_IS_OK(status)) {
    2407           5 :                 printf("pid2 unable to read the range 130:4, error was "
    2408             :                        "%s\n", nt_errstr(status));
    2409           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2410           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2411           0 :                         goto fail;
    2412             :                 }
    2413             :         } else {
    2414           0 :                 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
    2415             :                        (unsigned long)nread);
    2416           0 :                 goto fail;
    2417             :         }
    2418             : 
    2419           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
    2420           5 :         if (!NT_STATUS_IS_OK(status)) {
    2421           5 :                 printf("pid2 unable to write to the range 130:4, error was "
    2422             :                        "%s\n", nt_errstr(status));
    2423           5 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2424           0 :                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
    2425           0 :                         goto fail;
    2426             :                 }
    2427             :         } else {
    2428           0 :                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
    2429           0 :                 goto fail;
    2430             :         }
    2431             : 
    2432           5 :         cli_unlock(cli1, fnum1, 130, 0);
    2433           5 :         correct = True;
    2434             : 
    2435           5 : fail:
    2436           5 :         cli_close(cli1, fnum1);
    2437           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2438           5 :         torture_close_connection(cli1);
    2439             : 
    2440           5 :         printf("finished locktest7\n");
    2441           5 :         return correct;
    2442             : }
    2443             : 
    2444             : /*
    2445             :  * This demonstrates a problem with our use of GPFS share modes: A file
    2446             :  * descriptor sitting in the pending close queue holding a GPFS share mode
    2447             :  * blocks opening a file another time. Happens with Word 2007 temp files.
    2448             :  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
    2449             :  * open is denied with NT_STATUS_SHARING_VIOLATION.
    2450             :  */
    2451             : 
    2452           0 : static bool run_locktest8(int dummy)
    2453             : {
    2454             :         struct cli_state *cli1;
    2455           0 :         const char *fname = "\\lockt8.lck";
    2456             :         uint16_t fnum1, fnum2;
    2457             :         char buf[200];
    2458           0 :         bool correct = False;
    2459             :         NTSTATUS status;
    2460             : 
    2461           0 :         if (!torture_open_connection(&cli1, 0)) {
    2462           0 :                 return False;
    2463             :         }
    2464             : 
    2465           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2466             : 
    2467           0 :         printf("starting locktest8\n");
    2468             : 
    2469           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2470             : 
    2471           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
    2472             :                           &fnum1);
    2473           0 :         if (!NT_STATUS_IS_OK(status)) {
    2474           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2475           0 :                 return false;
    2476             :         }
    2477             : 
    2478           0 :         memset(buf, 0, sizeof(buf));
    2479             : 
    2480           0 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
    2481           0 :         if (!NT_STATUS_IS_OK(status)) {
    2482           0 :                 d_fprintf(stderr, "cli_openx second time returned %s\n",
    2483             :                           nt_errstr(status));
    2484           0 :                 goto fail;
    2485             :         }
    2486             : 
    2487           0 :         status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
    2488           0 :         if (!NT_STATUS_IS_OK(status)) {
    2489           0 :                 printf("Unable to apply read lock on range 1:1, error was "
    2490             :                        "%s\n", nt_errstr(status));
    2491           0 :                 goto fail;
    2492             :         }
    2493             : 
    2494           0 :         status = cli_close(cli1, fnum1);
    2495           0 :         if (!NT_STATUS_IS_OK(status)) {
    2496           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2497           0 :                 goto fail;
    2498             :         }
    2499             : 
    2500           0 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    2501           0 :         if (!NT_STATUS_IS_OK(status)) {
    2502           0 :                 d_fprintf(stderr, "cli_openx third time returned %s\n",
    2503             :                           nt_errstr(status));
    2504           0 :                 goto fail;
    2505             :         }
    2506             : 
    2507           0 :         correct = true;
    2508             : 
    2509           0 : fail:
    2510           0 :         cli_close(cli1, fnum1);
    2511           0 :         cli_close(cli1, fnum2);
    2512           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2513           0 :         torture_close_connection(cli1);
    2514             : 
    2515           0 :         printf("finished locktest8\n");
    2516           0 :         return correct;
    2517             : }
    2518             : 
    2519             : /*
    2520             :  * This test is designed to be run in conjunction with
    2521             :  * external NFS or POSIX locks taken in the filesystem.
    2522             :  * It checks that the smbd server will block until the
    2523             :  * lock is released and then acquire it. JRA.
    2524             :  */
    2525             : 
    2526             : static bool got_alarm;
    2527             : static struct cli_state *alarm_cli;
    2528             : 
    2529           0 : static void alarm_handler(int dummy)
    2530             : {
    2531           0 :         got_alarm = True;
    2532           0 : }
    2533             : 
    2534           0 : static void alarm_handler_parent(int dummy)
    2535             : {
    2536           0 :         smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_LOCAL_DISCONNECT);
    2537           0 : }
    2538             : 
    2539           8 : static void do_local_lock(const char *fname, int read_fd, int write_fd)
    2540             : {
    2541             :         int fd;
    2542           8 :         char c = '\0';
    2543             :         struct flock lock;
    2544           8 :         const char *local_pathname = NULL;
    2545             :         int ret;
    2546             : 
    2547           8 :         local_pathname = talloc_asprintf(talloc_tos(),
    2548             :                         "%s/%s", local_path, fname);
    2549           8 :         if (!local_pathname) {
    2550           0 :                 printf("child: alloc fail\n");
    2551           0 :                 exit(1);
    2552             :         }
    2553             : 
    2554           8 :         unlink(local_pathname);
    2555           8 :         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
    2556           8 :         if (fd == -1) {
    2557           0 :                 printf("child: open of %s failed %s.\n",
    2558           0 :                         local_pathname, strerror(errno));
    2559           0 :                 exit(1);
    2560             :         }
    2561             : 
    2562             :         /* Now take a fcntl lock. */
    2563           8 :         lock.l_type = F_WRLCK;
    2564           8 :         lock.l_whence = SEEK_SET;
    2565           8 :         lock.l_start = 0;
    2566           8 :         lock.l_len = 4;
    2567           8 :         lock.l_pid = getpid();
    2568             : 
    2569           8 :         ret = fcntl(fd,F_SETLK,&lock);
    2570           8 :         if (ret == -1) {
    2571           0 :                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
    2572           0 :                         local_pathname, strerror(errno));
    2573           0 :                 exit(1);
    2574             :         } else {
    2575           8 :                 printf("child: got lock 0:4 on file %s.\n",
    2576             :                         local_pathname );
    2577           8 :                 fflush(stdout);
    2578             :         }
    2579             : 
    2580           8 :         CatchSignal(SIGALRM, alarm_handler);
    2581           8 :         alarm(5);
    2582             :         /* Signal the parent. */
    2583           8 :         if (write(write_fd, &c, 1) != 1) {
    2584           0 :                 printf("child: start signal fail %s.\n",
    2585           0 :                         strerror(errno));
    2586           0 :                 exit(1);
    2587             :         }
    2588           8 :         alarm(0);
    2589             : 
    2590           8 :         alarm(10);
    2591             :         /* Wait for the parent to be ready. */
    2592           8 :         if (read(read_fd, &c, 1) != 1) {
    2593           0 :                 printf("child: reply signal fail %s.\n",
    2594           0 :                         strerror(errno));
    2595           0 :                 exit(1);
    2596             :         }
    2597           8 :         alarm(0);
    2598             : 
    2599           8 :         sleep(5);
    2600           8 :         close(fd);
    2601           8 :         printf("child: released lock 0:4 on file %s.\n",
    2602             :                 local_pathname );
    2603           8 :         fflush(stdout);
    2604           8 :         exit(0);
    2605             : }
    2606             : 
    2607           8 : static bool _run_locktest9X(const char *fname, int timeout)
    2608             : {
    2609             :         struct cli_state *cli1;
    2610           8 :         char *fpath = talloc_asprintf(talloc_tos(), "\\%s", fname);
    2611             :         uint16_t fnum;
    2612           8 :         bool correct = False;
    2613             :         int pipe_in[2], pipe_out[2];
    2614             :         pid_t child_pid;
    2615           8 :         char c = '\0';
    2616             :         int ret;
    2617             :         struct timeval start;
    2618             :         double seconds;
    2619             :         NTSTATUS status;
    2620             : 
    2621           8 :         printf("starting locktest9X: %s\n", fname);
    2622             : 
    2623           8 :         if (local_path == NULL) {
    2624           0 :                 d_fprintf(stderr, "locktest9X must be given a local path via -l <localpath>\n");
    2625           0 :                 return false;
    2626             :         }
    2627             : 
    2628           8 :         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
    2629           0 :                 return false;
    2630             :         }
    2631             : 
    2632           8 :         child_pid = fork();
    2633          16 :         if (child_pid == -1) {
    2634           0 :                 return false;
    2635             :         }
    2636             : 
    2637          16 :         if (child_pid == 0) {
    2638             :                 /* Child. */
    2639           8 :                 do_local_lock(fname, pipe_out[0], pipe_in[1]);
    2640           0 :                 exit(0);
    2641             :         }
    2642             : 
    2643           8 :         close(pipe_out[0]);
    2644           8 :         close(pipe_in[1]);
    2645           8 :         pipe_out[0] = -1;
    2646           8 :         pipe_in[1] = -1;
    2647             : 
    2648             :         /* Parent. */
    2649           8 :         ret = read(pipe_in[0], &c, 1);
    2650           8 :         if (ret != 1) {
    2651           0 :                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
    2652           0 :                         strerror(errno));
    2653           0 :                 return false;
    2654             :         }
    2655             : 
    2656           8 :         if (!torture_open_connection(&cli1, 0)) {
    2657           0 :                 return false;
    2658             :         }
    2659             : 
    2660           8 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2661             : 
    2662           8 :         status = cli_openx(cli1, fpath, O_RDWR, DENY_NONE,
    2663             :                           &fnum);
    2664           8 :         if (!NT_STATUS_IS_OK(status)) {
    2665           0 :                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
    2666           0 :                 return false;
    2667             :         }
    2668             : 
    2669             :         /* Ensure the child has the lock. */
    2670           8 :         status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
    2671           8 :         if (NT_STATUS_IS_OK(status)) {
    2672           0 :                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
    2673           0 :                 goto fail;
    2674             :         } else {
    2675           8 :                 d_printf("Child has the lock.\n");
    2676             :         }
    2677             : 
    2678             :         /* Tell the child to wait 5 seconds then exit. */
    2679           8 :         ret = write(pipe_out[1], &c, 1);
    2680           8 :         if (ret != 1) {
    2681           0 :                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
    2682           0 :                         strerror(errno));
    2683           0 :                 goto fail;
    2684             :         }
    2685             : 
    2686             :         /* Wait 20 seconds for the lock. */
    2687           8 :         alarm_cli = cli1;
    2688           8 :         CatchSignal(SIGALRM, alarm_handler_parent);
    2689           8 :         alarm(20);
    2690             : 
    2691           8 :         start = timeval_current();
    2692             : 
    2693           8 :         status = cli_lock32(cli1, fnum, 0, 4, timeout, WRITE_LOCK);
    2694           8 :         if (!NT_STATUS_IS_OK(status)) {
    2695           0 :                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
    2696             :                        "%s\n", nt_errstr(status));
    2697           0 :                 goto fail_nofd;
    2698             :         }
    2699           8 :         alarm(0);
    2700             : 
    2701           8 :         seconds = timeval_elapsed(&start);
    2702             : 
    2703           8 :         printf("Parent got the lock after %.2f seconds.\n",
    2704             :                 seconds);
    2705             : 
    2706           8 :         status = cli_close(cli1, fnum);
    2707           8 :         if (!NT_STATUS_IS_OK(status)) {
    2708           0 :                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
    2709           0 :                 goto fail;
    2710             :         }
    2711             : 
    2712           8 :         correct = true;
    2713             : 
    2714           8 : fail:
    2715           8 :         cli_close(cli1, fnum);
    2716           8 :         torture_close_connection(cli1);
    2717             : 
    2718           8 : fail_nofd:
    2719             : 
    2720           8 :         printf("finished locktest9X: %s\n", fname);
    2721           8 :         return correct;
    2722             : }
    2723             : 
    2724           4 : static bool run_locktest9a(int dummy)
    2725             : {
    2726           4 :         return _run_locktest9X("lock9a.dat", -1);
    2727             : }
    2728             : 
    2729           4 : static bool run_locktest9b(int dummy)
    2730             : {
    2731           4 :         return _run_locktest9X("lock9b.dat", 10000);
    2732             : }
    2733             : 
    2734             : struct locktest10_state {
    2735             :         bool ok;
    2736             :         bool done;
    2737             : };
    2738             : 
    2739             : static void locktest10_lockingx_done(struct tevent_req *subreq);
    2740             : static void locktest10_read_andx_done(struct tevent_req *subreq);
    2741             : 
    2742           5 : static bool run_locktest10(int dummy)
    2743             : {
    2744           5 :         struct tevent_context *ev = NULL;
    2745           5 :         struct cli_state *cli1 = NULL;
    2746           5 :         struct cli_state *cli2 = NULL;
    2747           5 :         struct smb1_lock_element lck = { 0 };
    2748           5 :         struct tevent_req *reqs[2] = { NULL };
    2749           5 :         struct tevent_req *smbreqs[2] = { NULL };
    2750           5 :         const char fname[] = "\\lockt10.lck";
    2751             :         uint16_t fnum1, fnum2;
    2752           5 :         bool ret = false;
    2753             :         bool ok;
    2754           5 :         uint8_t data = 1;
    2755           5 :         struct locktest10_state state = { .ok = true };
    2756             :         NTSTATUS status;
    2757             : 
    2758           5 :         printf("starting locktest10\n");
    2759             : 
    2760           5 :         ev = samba_tevent_context_init(NULL);
    2761           5 :         if (ev == NULL) {
    2762           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    2763           0 :                 goto done;
    2764             :         }
    2765             : 
    2766           5 :         ok = torture_open_connection(&cli1, 0);
    2767           5 :         if (!ok) {
    2768           0 :                 goto done;
    2769             :         }
    2770           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2771             : 
    2772           5 :         ok = torture_open_connection(&cli2, 1);
    2773           5 :         if (!ok) {
    2774           0 :                 goto done;
    2775             :         }
    2776           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    2777             : 
    2778           5 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    2779           5 :         if (!NT_STATUS_IS_OK(status)) {
    2780           0 :                 d_fprintf(stderr,
    2781             :                           "cli_openx failed: %s\n",
    2782             :                           nt_errstr(status));
    2783           0 :                 goto done;
    2784             :         }
    2785             : 
    2786           5 :         status = cli_writeall(cli1, fnum1, 0, &data, 0, sizeof(data), NULL);
    2787           5 :         if (!NT_STATUS_IS_OK(status)) {
    2788           0 :                 d_fprintf(stderr,
    2789             :                           "cli_writeall failed: %s\n",
    2790             :                           nt_errstr(status));
    2791           0 :                 goto done;
    2792             :         }
    2793             : 
    2794           5 :         status = cli_openx(cli2, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    2795           5 :         if (!NT_STATUS_IS_OK(status)) {
    2796           0 :                 d_fprintf(stderr,
    2797             :                           "cli_openx failed: %s\n",
    2798             :                           nt_errstr(status));
    2799           0 :                 goto done;
    2800             :         }
    2801             : 
    2802           5 :         status = cli_locktype(
    2803             :                 cli2, fnum2, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    2804           5 :         if (!NT_STATUS_IS_OK(status)) {
    2805           0 :                 d_fprintf(stderr,
    2806             :                           "cli_locktype failed: %s\n",
    2807             :                           nt_errstr(status));
    2808           0 :                 goto done;
    2809             :         }
    2810             : 
    2811           5 :         lck = (struct smb1_lock_element) {
    2812           5 :                 .pid = cli_getpid(cli1), .offset = 0, .length = 1,
    2813             :         };
    2814             : 
    2815           5 :         reqs[0] = cli_lockingx_create(
    2816             :                 ev,                             /* mem_ctx */
    2817             :                 ev,                             /* tevent_context */
    2818             :                 cli1,                           /* cli */
    2819             :                 fnum1,                          /* fnum */
    2820             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    2821             :                 0,                              /* newoplocklevel */
    2822             :                 1,                              /* timeout */
    2823             :                 0,                              /* num_unlocks */
    2824             :                 NULL,                           /* unlocks */
    2825             :                 1,                              /* num_locks */
    2826             :                 &lck,                               /* locks */
    2827             :                 &smbreqs[0]);                       /* psmbreq */
    2828           5 :         if (reqs[0] == NULL) {
    2829           0 :                 d_fprintf(stderr, "cli_lockingx_create failed\n");
    2830           0 :                 goto done;
    2831             :         }
    2832           5 :         tevent_req_set_callback(reqs[0], locktest10_lockingx_done, &state);
    2833             : 
    2834           5 :         reqs[1] = cli_read_andx_create(
    2835             :                 ev,             /* mem_ctx */
    2836             :                 ev,             /* ev */
    2837             :                 cli1,           /* cli */
    2838             :                 fnum1,          /* fnum */
    2839             :                 0,              /* offset */
    2840             :                 1,              /* size */
    2841             :                 &smbreqs[1]);       /* psmbreq */
    2842           5 :         if (reqs[1] == NULL) {
    2843           0 :                 d_fprintf(stderr, "cli_read_andx_create failed\n");
    2844           0 :                 goto done;
    2845             :         }
    2846           5 :         tevent_req_set_callback(reqs[1], locktest10_read_andx_done, &state);
    2847             : 
    2848           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
    2849           5 :         if (!NT_STATUS_IS_OK(status)) {
    2850           0 :                 d_fprintf(stderr,
    2851             :                           "smb1cli_req_chain_submit failed: %s\n",
    2852             :                           nt_errstr(status));
    2853           0 :                 goto done;
    2854             :         }
    2855             : 
    2856          35 :         while (!state.done) {
    2857          25 :                 tevent_loop_once(ev);
    2858             :         }
    2859             : 
    2860           5 :         torture_close_connection(cli1);
    2861             : 
    2862           5 :         if (state.ok) {
    2863           5 :                 ret = true;
    2864             :         }
    2865           5 : done:
    2866           5 :         return ret;
    2867             : }
    2868             : 
    2869           5 : static void locktest10_lockingx_done(struct tevent_req *subreq)
    2870             : {
    2871           5 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    2872             :         NTSTATUS status;
    2873             : 
    2874           5 :         status = cli_lockingx_recv(subreq);
    2875           5 :         TALLOC_FREE(subreq);
    2876             : 
    2877           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    2878           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    2879           0 :                 state->ok = false;
    2880             :         }
    2881           5 : }
    2882             : 
    2883           5 : static void locktest10_read_andx_done(struct tevent_req *subreq)
    2884             : {
    2885           5 :         struct locktest10_state *state = tevent_req_callback_data_void(subreq);
    2886           5 :         ssize_t received = -1;
    2887           5 :         uint8_t *rcvbuf = NULL;
    2888             :         NTSTATUS status;
    2889             : 
    2890           5 :         status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    2891             : 
    2892           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_REQUEST_ABORTED)) {
    2893           0 :                 d_printf("cli_read_andx returned %s\n", nt_errstr(status));
    2894           0 :                 state->ok = false;
    2895             :         }
    2896             : 
    2897           5 :         state->done = true;
    2898           5 :         TALLOC_FREE(subreq);
    2899           5 : }
    2900             : 
    2901           5 : static bool run_locktest11(int dummy)
    2902             : {
    2903             :         struct cli_state *cli1;
    2904           5 :         const char *fname = "\\lockt11.lck";
    2905             :         NTSTATUS status;
    2906             :         uint16_t fnum;
    2907           5 :         bool ret = false;
    2908             : 
    2909           5 :         if (!torture_open_connection(&cli1, 0)) {
    2910           0 :                 return false;
    2911             :         }
    2912             : 
    2913           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    2914             : 
    2915           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2916             : 
    2917           5 :         status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum);
    2918           5 :         if (!NT_STATUS_IS_OK(status)) {
    2919           0 :                 d_fprintf(stderr,
    2920             :                           "cli_openx returned %s\n",
    2921             :                           nt_errstr(status));
    2922           0 :                 return false;
    2923             :         }
    2924             : 
    2925             :         /*
    2926             :          * Test that LOCKING_ANDX_CANCEL_LOCK without any locks
    2927             :          * returns NT_STATUS_OK
    2928             :          */
    2929             : 
    2930           5 :         status = cli_lockingx(
    2931             :                 cli1,                           /* cli */
    2932             :                 fnum,                           /* fnum */
    2933             :                 LOCKING_ANDX_CANCEL_LOCK,       /* typeoflock */
    2934             :                 0,                              /* newoplocklevel */
    2935             :                 0,                              /* timeout */
    2936             :                 0,                              /* num_unlocks */
    2937             :                 NULL,                           /* unlocks */
    2938             :                 0,                              /* num_locks */
    2939             :                 NULL);                          /* locks */
    2940             : 
    2941           5 :         if (!NT_STATUS_IS_OK(status)) {
    2942           1 :                 d_printf("cli_lockingX returned %s\n", nt_errstr(status));
    2943           1 :                 goto fail;
    2944             :         }
    2945             : 
    2946           4 :         ret = true;
    2947           5 : fail:
    2948           5 :         cli_close(cli1, fnum);
    2949           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    2950             : 
    2951           5 :         return ret;
    2952             : }
    2953             : 
    2954             : struct deferred_close_state {
    2955             :         struct tevent_context *ev;
    2956             :         struct cli_state *cli;
    2957             :         uint16_t fnum;
    2958             : };
    2959             : 
    2960             : static void deferred_close_waited(struct tevent_req *subreq);
    2961             : static void deferred_close_done(struct tevent_req *subreq);
    2962             : 
    2963           5 : static struct tevent_req *deferred_close_send(
    2964             :         TALLOC_CTX *mem_ctx,
    2965             :         struct tevent_context *ev,
    2966             :         int wait_secs,
    2967             :         struct cli_state *cli,
    2968             :         uint16_t fnum)
    2969             : {
    2970           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    2971           5 :         struct deferred_close_state *state = NULL;
    2972           5 :         struct timeval wakeup_time = timeval_current_ofs(wait_secs, 0);
    2973             : 
    2974           5 :         req = tevent_req_create(
    2975             :                 mem_ctx, &state, struct deferred_close_state);
    2976           5 :         if (req == NULL) {
    2977           0 :                 return NULL;
    2978             :         }
    2979           5 :         state->ev = ev;
    2980           5 :         state->cli = cli;
    2981           5 :         state->fnum = fnum;
    2982             : 
    2983           5 :         subreq = tevent_wakeup_send(state, state->ev, wakeup_time);
    2984           5 :         if (tevent_req_nomem(subreq, req)) {
    2985           0 :                 return tevent_req_post(req, ev);
    2986             :         }
    2987           5 :         tevent_req_set_callback(subreq, deferred_close_waited, req);
    2988           5 :         return req;
    2989             : }
    2990             : 
    2991           5 : static void deferred_close_waited(struct tevent_req *subreq)
    2992             : {
    2993           5 :         struct tevent_req *req = tevent_req_callback_data(
    2994             :                 subreq, struct tevent_req);
    2995           5 :         struct deferred_close_state *state = tevent_req_data(
    2996             :                 req, struct deferred_close_state);
    2997             :         bool ok;
    2998             : 
    2999           5 :         ok = tevent_wakeup_recv(subreq);
    3000           5 :         TALLOC_FREE(subreq);
    3001           5 :         if (!ok) {
    3002           0 :                 tevent_req_oom(req);
    3003           0 :                 return;
    3004             :         }
    3005             : 
    3006           5 :         subreq = cli_close_send(state, state->ev, state->cli, state->fnum);
    3007           5 :         if (tevent_req_nomem(subreq, req)) {
    3008           0 :                 return;
    3009             :         }
    3010           5 :         tevent_req_set_callback(subreq, deferred_close_done, req);
    3011             : }
    3012             : 
    3013           5 : static void deferred_close_done(struct tevent_req *subreq)
    3014             : {
    3015           5 :         NTSTATUS status = cli_close_recv(subreq);
    3016           5 :         tevent_req_simple_finish_ntstatus(subreq, status);
    3017           5 : }
    3018             : 
    3019           5 : static NTSTATUS deferred_close_recv(struct tevent_req *req)
    3020             : {
    3021           5 :         return tevent_req_simple_recv_ntstatus(req);
    3022             : }
    3023             : 
    3024             : struct lockread_state {
    3025             :         struct smb1_lock_element lck;
    3026             :         struct tevent_req *reqs[2];
    3027             :         struct tevent_req *smbreqs[2];
    3028             :         NTSTATUS lock_status;
    3029             :         NTSTATUS read_status;
    3030             :         uint8_t *readbuf;
    3031             : };
    3032             : 
    3033             : static void lockread_lockingx_done(struct tevent_req *subreq);
    3034             : static void lockread_read_andx_done(struct tevent_req *subreq);
    3035             : 
    3036           5 : static struct tevent_req *lockread_send(
    3037             :         TALLOC_CTX *mem_ctx,
    3038             :         struct tevent_context *ev,
    3039             :         struct cli_state *cli,
    3040             :         uint16_t fnum)
    3041             : {
    3042           5 :         struct tevent_req *req = NULL;
    3043           5 :         struct lockread_state *state = NULL;
    3044             :         NTSTATUS status;
    3045             : 
    3046           5 :         req = tevent_req_create(mem_ctx, &state, struct lockread_state);
    3047           5 :         if (req == NULL) {
    3048           0 :                 return NULL;
    3049             :         }
    3050             : 
    3051          10 :         state->lck = (struct smb1_lock_element) {
    3052           5 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3053             :         };
    3054             : 
    3055          10 :         state->reqs[0] = cli_lockingx_create(
    3056             :                 ev,                             /* mem_ctx */
    3057             :                 ev,                             /* tevent_context */
    3058             :                 cli,                            /* cli */
    3059             :                 fnum,                           /* fnum */
    3060             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3061             :                 0,                              /* newoplocklevel */
    3062             :                 10000,                          /* timeout */
    3063             :                 0,                              /* num_unlocks */
    3064             :                 NULL,                           /* unlocks */
    3065             :                 1,                              /* num_locks */
    3066           5 :                 &state->lck,                     /* locks */
    3067           5 :                 &state->smbreqs[0]);             /* psmbreq */
    3068           5 :         if (tevent_req_nomem(state->reqs[0], req)) {
    3069           0 :                 return tevent_req_post(req, ev);
    3070             :         }
    3071           5 :         tevent_req_set_callback(
    3072           5 :                 state->reqs[0], lockread_lockingx_done, req);
    3073             : 
    3074           5 :         state->reqs[1] = cli_read_andx_create(
    3075             :                 ev,             /* mem_ctx */
    3076             :                 ev,             /* ev */
    3077             :                 cli,            /* cli */
    3078             :                 fnum,           /* fnum */
    3079             :                 0,              /* offset */
    3080             :                 1,              /* size */
    3081           5 :                 &state->smbreqs[1]);     /* psmbreq */
    3082           5 :         if (tevent_req_nomem(state->reqs[1], req)) {
    3083           0 :                 return tevent_req_post(req, ev);
    3084             :         }
    3085           5 :         tevent_req_set_callback(
    3086           5 :                 state->reqs[1], lockread_read_andx_done, req);
    3087             : 
    3088           5 :         status = smb1cli_req_chain_submit(state->smbreqs, 2);
    3089           5 :         if (tevent_req_nterror(req, status)) {
    3090           0 :                 return tevent_req_post(req, ev);
    3091             :         }
    3092           5 :         return req;
    3093             : }
    3094             : 
    3095           5 : static void lockread_lockingx_done(struct tevent_req *subreq)
    3096             : {
    3097           5 :         struct tevent_req *req = tevent_req_callback_data(
    3098             :                 subreq, struct tevent_req);
    3099           5 :         struct lockread_state *state = tevent_req_data(
    3100             :                 req, struct lockread_state);
    3101           5 :         state->lock_status = cli_lockingx_recv(subreq);
    3102           5 :         TALLOC_FREE(subreq);
    3103           5 :         d_fprintf(stderr,
    3104             :                   "lockingx returned %s\n",
    3105             :                   nt_errstr(state->lock_status));
    3106           5 : }
    3107             : 
    3108           5 : static void lockread_read_andx_done(struct tevent_req *subreq)
    3109             : {
    3110           5 :         struct tevent_req *req = tevent_req_callback_data(
    3111             :                 subreq, struct tevent_req);
    3112           5 :         struct lockread_state *state = tevent_req_data(
    3113             :                 req, struct lockread_state);
    3114           5 :         ssize_t received = -1;
    3115           5 :         uint8_t *rcvbuf = NULL;
    3116             : 
    3117           5 :         state->read_status = cli_read_andx_recv(subreq, &received, &rcvbuf);
    3118             : 
    3119           5 :         d_fprintf(stderr,
    3120             :                   "read returned %s\n",
    3121             :                   nt_errstr(state->read_status));
    3122             : 
    3123           5 :         if (!NT_STATUS_IS_OK(state->read_status)) {
    3124           4 :                 TALLOC_FREE(subreq);
    3125           4 :                 tevent_req_done(req);
    3126           4 :                 return;
    3127             :         }
    3128             : 
    3129           1 :         if (received > 0) {
    3130           1 :                 state->readbuf = talloc_memdup(state, rcvbuf, received);
    3131           1 :                 TALLOC_FREE(subreq);
    3132           1 :                 if (tevent_req_nomem(state->readbuf, req)) {
    3133           0 :                         return;
    3134             :                 }
    3135             :         }
    3136           1 :         TALLOC_FREE(subreq);
    3137           1 :         tevent_req_done(req);
    3138             : }
    3139             : 
    3140           5 : static NTSTATUS lockread_recv(
    3141             :         struct tevent_req *req,
    3142             :         NTSTATUS *lock_status,
    3143             :         NTSTATUS *read_status,
    3144             :         TALLOC_CTX *mem_ctx,
    3145             :         uint8_t **read_buf)
    3146             : {
    3147           5 :         struct lockread_state *state = tevent_req_data(
    3148             :                 req, struct lockread_state);
    3149             :         NTSTATUS status;
    3150             : 
    3151           5 :         if (tevent_req_is_nterror(req, &status)) {
    3152           0 :                 return status;
    3153             :         }
    3154             : 
    3155           5 :         *lock_status = state->lock_status;
    3156           5 :         *read_status = state->read_status;
    3157           5 :         if (state->readbuf != NULL) {
    3158           1 :                 *read_buf = talloc_move(mem_ctx, &state->readbuf);
    3159             :         } else {
    3160           4 :                 *read_buf = NULL;
    3161             :         }
    3162             : 
    3163           5 :         return NT_STATUS_OK;
    3164             : }
    3165             : 
    3166             : struct lock12_state {
    3167             :         uint8_t dummy;
    3168             : };
    3169             : 
    3170             : static void lock12_closed(struct tevent_req *subreq);
    3171             : static void lock12_read(struct tevent_req *subreq);
    3172             : 
    3173           5 : static struct tevent_req *lock12_send(
    3174             :         TALLOC_CTX *mem_ctx,
    3175             :         struct tevent_context *ev,
    3176             :         struct cli_state *cli,
    3177             :         uint16_t fnum1,
    3178             :         uint16_t fnum2)
    3179             : {
    3180           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3181           5 :         struct lock12_state *state = NULL;
    3182             : 
    3183           5 :         req = tevent_req_create(mem_ctx, &state, struct lock12_state);
    3184           5 :         if (req == NULL) {
    3185           0 :                 return NULL;
    3186             :         }
    3187             : 
    3188           5 :         subreq = deferred_close_send(state, ev, 1, cli, fnum1);
    3189           5 :         if (tevent_req_nomem(subreq, req)) {
    3190           0 :                 return tevent_req_post(req, ev);
    3191             :         }
    3192           5 :         tevent_req_set_callback(subreq, lock12_closed, req);
    3193             : 
    3194           5 :         subreq = lockread_send(state, ev, cli, fnum2);
    3195           5 :         if (tevent_req_nomem(subreq, req)) {
    3196           0 :                 return tevent_req_post(req, ev);
    3197             :         }
    3198           5 :         tevent_req_set_callback(subreq, lock12_read, req);
    3199             : 
    3200           5 :         return req;
    3201             : }
    3202             : 
    3203           5 : static void lock12_closed(struct tevent_req *subreq)
    3204             : {
    3205           5 :         struct tevent_req *req = tevent_req_callback_data(
    3206             :                 subreq, struct tevent_req);
    3207             :         NTSTATUS status;
    3208             : 
    3209           5 :         status = deferred_close_recv(subreq);
    3210           5 :         TALLOC_FREE(subreq);
    3211           5 :         DBG_DEBUG("close returned %s\n", nt_errstr(status));
    3212           5 :         if (tevent_req_nterror(req, status)) {
    3213           0 :                 return;
    3214             :         }
    3215             : }
    3216             : 
    3217           5 : static void lock12_read(struct tevent_req *subreq)
    3218             : {
    3219           5 :         struct tevent_req *req = tevent_req_callback_data(
    3220             :                 subreq, struct tevent_req);
    3221           5 :         struct lock12_state *state = tevent_req_data(
    3222             :                 req, struct lock12_state);
    3223             :         NTSTATUS status, lock_status, read_status;
    3224           5 :         uint8_t *buf = NULL;
    3225             : 
    3226           5 :         status = lockread_recv(
    3227             :                 subreq, &lock_status, &read_status, state, &buf);
    3228           5 :         TALLOC_FREE(subreq);
    3229          10 :         if (tevent_req_nterror(req, status) ||
    3230          10 :             tevent_req_nterror(req, lock_status) ||
    3231           5 :             tevent_req_nterror(req, read_status)) {
    3232           4 :                 return;
    3233             :         }
    3234           1 :         tevent_req_done(req);
    3235             : }
    3236             : 
    3237           5 : static NTSTATUS lock12_recv(struct tevent_req *req)
    3238             : 
    3239             : {
    3240             :         NTSTATUS status;
    3241             : 
    3242           5 :         if (tevent_req_is_nterror(req, &status)) {
    3243           4 :                 return status;
    3244             :         }
    3245           1 :         return NT_STATUS_OK;
    3246             : }
    3247             : 
    3248           5 : static bool run_locktest12(int dummy)
    3249             : {
    3250           5 :         struct tevent_context *ev = NULL;
    3251           5 :         struct tevent_req *req = NULL;
    3252           5 :         struct cli_state *cli = NULL;
    3253           5 :         const char fname[] = "\\lockt12.lck";
    3254             :         uint16_t fnum1, fnum2;
    3255           5 :         bool ret = false;
    3256             :         bool ok;
    3257           5 :         uint8_t data = 1;
    3258             :         NTSTATUS status;
    3259             : 
    3260           5 :         printf("starting locktest12\n");
    3261             : 
    3262           5 :         ev = samba_tevent_context_init(NULL);
    3263           5 :         if (ev == NULL) {
    3264           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3265           0 :                 goto done;
    3266             :         }
    3267             : 
    3268           5 :         ok = torture_open_connection(&cli, 0);
    3269           5 :         if (!ok) {
    3270           0 :                 goto done;
    3271             :         }
    3272           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3273             : 
    3274           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3275           5 :         if (!NT_STATUS_IS_OK(status)) {
    3276           0 :                 d_fprintf(stderr,
    3277             :                           "cli_openx failed: %s\n",
    3278             :                           nt_errstr(status));
    3279           0 :                 goto done;
    3280             :         }
    3281             : 
    3282           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3283           5 :         if (!NT_STATUS_IS_OK(status)) {
    3284           0 :                 d_fprintf(stderr,
    3285             :                           "cli_openx failed: %s\n",
    3286             :                           nt_errstr(status));
    3287           0 :                 goto done;
    3288             :         }
    3289             : 
    3290           5 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3291           5 :         if (!NT_STATUS_IS_OK(status)) {
    3292           0 :                 d_fprintf(stderr,
    3293             :                           "cli_writeall failed: %s\n",
    3294             :                           nt_errstr(status));
    3295           0 :                 goto done;
    3296             :         }
    3297             : 
    3298           5 :         status = cli_locktype(
    3299             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3300           5 :         if (!NT_STATUS_IS_OK(status)) {
    3301           0 :                 d_fprintf(stderr,
    3302             :                           "cli_locktype failed: %s\n",
    3303             :                           nt_errstr(status));
    3304           0 :                 goto done;
    3305             :         }
    3306             : 
    3307           5 :         req = lock12_send(ev, ev, cli, fnum1, fnum2);
    3308           5 :         if (req == NULL) {
    3309           0 :                 d_fprintf(stderr, "lock12_send failed\n");
    3310           0 :                 goto done;
    3311             :         }
    3312             : 
    3313           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3314           5 :         if (!ok) {
    3315           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3316           0 :                 goto done;
    3317             :         }
    3318             : 
    3319           5 :         if (!NT_STATUS_IS_OK(status)) {
    3320           0 :                 d_fprintf(stderr,
    3321             :                           "tevent_req_poll_ntstatus returned %s\n",
    3322             :                           nt_errstr(status));
    3323           0 :                 goto done;
    3324             :         }
    3325             : 
    3326           5 :         status = lock12_recv(req);
    3327           5 :         if (!NT_STATUS_IS_OK(status)) {
    3328           4 :                 d_fprintf(stderr, "lock12 returned %s\n", nt_errstr(status));
    3329           4 :                 goto done;
    3330             :         }
    3331             : 
    3332           1 :         ret = true;
    3333           5 : done:
    3334           5 :         if (cli != NULL) {
    3335           5 :                 torture_close_connection(cli);
    3336             :         }
    3337           5 :         return ret;
    3338             : }
    3339             : 
    3340             : struct lock_ntcancel_state {
    3341             :         struct timeval start;
    3342             :         struct smb1_lock_element lck;
    3343             :         struct tevent_req *subreq;
    3344             : };
    3345             : 
    3346             : static void lock_ntcancel_waited(struct tevent_req *subreq);
    3347             : static void lock_ntcancel_done(struct tevent_req *subreq);
    3348             : 
    3349           5 : static struct tevent_req *lock_ntcancel_send(
    3350             :         TALLOC_CTX *mem_ctx,
    3351             :         struct tevent_context *ev,
    3352             :         struct cli_state *cli,
    3353             :         uint16_t fnum)
    3354             : {
    3355           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    3356           5 :         struct lock_ntcancel_state *state = NULL;
    3357             : 
    3358           5 :         req = tevent_req_create(mem_ctx, &state, struct lock_ntcancel_state);
    3359           5 :         if (req == NULL) {
    3360           0 :                 return NULL;
    3361             :         }
    3362          10 :         state->lck = (struct smb1_lock_element) {
    3363           5 :                 .pid = cli_getpid(cli), .offset = 0, .length = 1,
    3364             :         };
    3365           5 :         state->start = timeval_current();
    3366             : 
    3367           5 :         state->subreq = cli_lockingx_send(
    3368             :                 state,                          /* mem_ctx */
    3369             :                 ev,                             /* tevent_context */
    3370             :                 cli,                            /* cli */
    3371             :                 fnum,                           /* fnum */
    3372             :                 LOCKING_ANDX_EXCLUSIVE_LOCK,    /* typeoflock */
    3373             :                 0,                              /* newoplocklevel */
    3374             :                 10000,                          /* timeout */
    3375             :                 0,                              /* num_unlocks */
    3376             :                 NULL,                           /* unlocks */
    3377             :                 1,                              /* num_locks */
    3378           5 :                 &state->lck);                    /* locks */
    3379           5 :         if (tevent_req_nomem(state->subreq, req)) {
    3380           0 :                 return tevent_req_post(req, ev);
    3381             :         }
    3382           5 :         tevent_req_set_callback(state->subreq, lock_ntcancel_done, req);
    3383             : 
    3384           5 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(1, 0));
    3385           5 :         if (tevent_req_nomem(subreq, req)) {
    3386           0 :                 return tevent_req_post(req, ev);
    3387             :         }
    3388           5 :         tevent_req_set_callback(subreq, lock_ntcancel_waited, req);
    3389           5 :         return req;
    3390             : }
    3391             : 
    3392           5 : static void lock_ntcancel_waited(struct tevent_req *subreq)
    3393             : {
    3394           5 :         struct tevent_req *req = tevent_req_callback_data(
    3395             :                 subreq, struct tevent_req);
    3396           5 :         struct lock_ntcancel_state *state = tevent_req_data(
    3397             :                 req, struct lock_ntcancel_state);
    3398             :         bool ok;
    3399             : 
    3400           5 :         ok = tevent_wakeup_recv(subreq);
    3401           5 :         TALLOC_FREE(subreq);
    3402           5 :         if (!ok) {
    3403           0 :                 tevent_req_oom(req);
    3404           0 :                 return;
    3405             :         }
    3406             : 
    3407           5 :         ok = tevent_req_cancel(state->subreq);
    3408           5 :         if (!ok) {
    3409           0 :                 d_fprintf(stderr, "Could not cancel subreq\n");
    3410           0 :                 tevent_req_oom(req);
    3411           0 :                 return;
    3412             :         }
    3413             : }
    3414             : 
    3415           5 : static void lock_ntcancel_done(struct tevent_req *subreq)
    3416             : {
    3417           5 :         struct tevent_req *req = tevent_req_callback_data(
    3418             :                 subreq, struct tevent_req);
    3419           5 :         struct lock_ntcancel_state *state = tevent_req_data(
    3420             :                 req, struct lock_ntcancel_state);
    3421             :         NTSTATUS status;
    3422             :         double elapsed;
    3423             : 
    3424           5 :         status = cli_lockingx_recv(subreq);
    3425           5 :         TALLOC_FREE(subreq);
    3426             : 
    3427           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    3428           0 :                 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
    3429           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3430           0 :                 return;
    3431             :         }
    3432             : 
    3433           5 :         elapsed = timeval_elapsed(&state->start);
    3434             : 
    3435           5 :         if (elapsed > 3) {
    3436           0 :                 d_printf("cli_lockingx was too slow, cancel did not work\n");
    3437           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    3438           0 :                 return;
    3439             :         }
    3440             : 
    3441           5 :         tevent_req_done(req);
    3442             : }
    3443             : 
    3444           5 : static NTSTATUS lock_ntcancel_recv(struct tevent_req *req)
    3445             : {
    3446           5 :         return tevent_req_simple_recv_ntstatus(req);
    3447             : }
    3448             : 
    3449           5 : static bool run_locktest13(int dummy)
    3450             : {
    3451           5 :         struct tevent_context *ev = NULL;
    3452           5 :         struct tevent_req *req = NULL;
    3453           5 :         struct cli_state *cli = NULL;
    3454           5 :         const char fname[] = "\\lockt13.lck";
    3455             :         uint16_t fnum1, fnum2;
    3456           5 :         bool ret = false;
    3457             :         bool ok;
    3458           5 :         uint8_t data = 1;
    3459             :         NTSTATUS status;
    3460             : 
    3461           5 :         printf("starting locktest13\n");
    3462             : 
    3463           5 :         ev = samba_tevent_context_init(NULL);
    3464           5 :         if (ev == NULL) {
    3465           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    3466           0 :                 goto done;
    3467             :         }
    3468             : 
    3469           5 :         ok = torture_open_connection(&cli, 0);
    3470           5 :         if (!ok) {
    3471           0 :                 goto done;
    3472             :         }
    3473           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3474             : 
    3475           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
    3476           5 :         if (!NT_STATUS_IS_OK(status)) {
    3477           0 :                 d_fprintf(stderr,
    3478             :                           "cli_openx failed: %s\n",
    3479             :                           nt_errstr(status));
    3480           0 :                 goto done;
    3481             :         }
    3482             : 
    3483           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
    3484           5 :         if (!NT_STATUS_IS_OK(status)) {
    3485           0 :                 d_fprintf(stderr,
    3486             :                           "cli_openx failed: %s\n",
    3487             :                           nt_errstr(status));
    3488           0 :                 goto done;
    3489             :         }
    3490             : 
    3491           5 :         status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
    3492           5 :         if (!NT_STATUS_IS_OK(status)) {
    3493           0 :                 d_fprintf(stderr,
    3494             :                           "cli_writeall failed: %s\n",
    3495             :                           nt_errstr(status));
    3496           0 :                 goto done;
    3497             :         }
    3498             : 
    3499           5 :         status = cli_locktype(
    3500             :                 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
    3501           5 :         if (!NT_STATUS_IS_OK(status)) {
    3502           0 :                 d_fprintf(stderr,
    3503             :                           "cli_locktype failed: %s\n",
    3504             :                           nt_errstr(status));
    3505           0 :                 goto done;
    3506             :         }
    3507             : 
    3508           5 :         req = lock_ntcancel_send(ev, ev, cli, fnum2);
    3509           5 :         if (req == NULL) {
    3510           0 :                 d_fprintf(stderr, "lock_ntcancel_send failed\n");
    3511           0 :                 goto done;
    3512             :         }
    3513             : 
    3514           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    3515           5 :         if (!ok) {
    3516           0 :                 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
    3517           0 :                 goto done;
    3518             :         }
    3519             : 
    3520           5 :         if (!NT_STATUS_IS_OK(status)) {
    3521           0 :                 d_fprintf(stderr,
    3522             :                           "tevent_req_poll_ntstatus returned %s\n",
    3523             :                           nt_errstr(status));
    3524           0 :                 goto done;
    3525             :         }
    3526             : 
    3527           5 :         status = lock_ntcancel_recv(req);
    3528           5 :         if (!NT_STATUS_IS_OK(status)) {
    3529           0 :                 d_fprintf(stderr,
    3530             :                           "lock_ntcancel returned %s\n",
    3531             :                           nt_errstr(status));
    3532           0 :                 goto done;
    3533             :         }
    3534             : 
    3535           5 :         ret = true;
    3536           5 : done:
    3537           5 :         if (cli != NULL) {
    3538           5 :                 torture_close_connection(cli);
    3539             :         }
    3540           5 :         return ret;
    3541             : }
    3542             : 
    3543             : /*
    3544             : test whether fnums and tids open on one VC are available on another (a major
    3545             : security hole)
    3546             : */
    3547           5 : static bool run_fdpasstest(int dummy)
    3548             : {
    3549             :         struct cli_state *cli1, *cli2;
    3550           5 :         const char *fname = "\\fdpass.tst";
    3551             :         uint16_t fnum1;
    3552             :         char buf[1024];
    3553             :         NTSTATUS status;
    3554             : 
    3555           5 :         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
    3556           0 :                 return False;
    3557             :         }
    3558           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    3559           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    3560             : 
    3561           5 :         printf("starting fdpasstest\n");
    3562             : 
    3563           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3564             : 
    3565           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    3566             :                           &fnum1);
    3567           5 :         if (!NT_STATUS_IS_OK(status)) {
    3568           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3569           0 :                 return False;
    3570             :         }
    3571             : 
    3572           5 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
    3573             :                               13, NULL);
    3574           5 :         if (!NT_STATUS_IS_OK(status)) {
    3575           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3576           0 :                 return False;
    3577             :         }
    3578             : 
    3579           5 :         cli_state_set_uid(cli2, cli_state_get_uid(cli1));
    3580           5 :         cli_state_set_tid(cli2, cli_state_get_tid(cli1));
    3581           5 :         cli_setpid(cli2, cli_getpid(cli1));
    3582             : 
    3583           5 :         if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
    3584           0 :                 printf("read succeeded! nasty security hole [%s]\n", buf);
    3585           0 :                 return false;
    3586             :         }
    3587             : 
    3588           5 :         cli_close(cli1, fnum1);
    3589           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3590             : 
    3591           5 :         torture_close_connection(cli1);
    3592           5 :         torture_close_connection(cli2);
    3593             : 
    3594           5 :         printf("finished fdpasstest\n");
    3595           5 :         return True;
    3596             : }
    3597             : 
    3598           5 : static bool run_fdsesstest(int dummy)
    3599             : {
    3600             :         struct cli_state *cli;
    3601             :         uint16_t new_vuid;
    3602             :         uint16_t saved_vuid;
    3603             :         uint32_t new_cnum;
    3604             :         uint32_t saved_cnum;
    3605           5 :         const char *fname = "\\fdsess.tst";
    3606           5 :         const char *fname1 = "\\fdsess1.tst";
    3607             :         uint16_t fnum1;
    3608             :         uint16_t fnum2;
    3609             :         char buf[1024];
    3610           5 :         bool ret = True;
    3611             :         NTSTATUS status;
    3612             : 
    3613           5 :         if (!torture_open_connection(&cli, 0))
    3614           0 :                 return False;
    3615           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3616             : 
    3617           5 :         if (!torture_cli_session_setup2(cli, &new_vuid))
    3618           0 :                 return False;
    3619             : 
    3620           5 :         saved_cnum = cli_state_get_tid(cli);
    3621           5 :         if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
    3622           0 :                 return False;
    3623           5 :         new_cnum = cli_state_get_tid(cli);
    3624           5 :         cli_state_set_tid(cli, saved_cnum);
    3625             : 
    3626           5 :         printf("starting fdsesstest\n");
    3627             : 
    3628           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3629           5 :         cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3630             : 
    3631           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    3632           5 :         if (!NT_STATUS_IS_OK(status)) {
    3633           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3634           0 :                 return False;
    3635             :         }
    3636             : 
    3637           5 :         status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
    3638             :                               NULL);
    3639           5 :         if (!NT_STATUS_IS_OK(status)) {
    3640           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    3641           0 :                 return False;
    3642             :         }
    3643             : 
    3644           5 :         saved_vuid = cli_state_get_uid(cli);
    3645           5 :         cli_state_set_uid(cli, new_vuid);
    3646             : 
    3647           5 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3648           0 :                 printf("read succeeded with different vuid! "
    3649             :                        "nasty security hole [%s]\n", buf);
    3650           0 :                 ret = false;
    3651             :         }
    3652             :         /* Try to open a file with different vuid, samba cnum. */
    3653           5 :         if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
    3654           5 :                 printf("create with different vuid, same cnum succeeded.\n");
    3655           5 :                 cli_close(cli, fnum2);
    3656           5 :                 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3657             :         } else {
    3658           0 :                 printf("create with different vuid, same cnum failed.\n");
    3659           0 :                 printf("This will cause problems with service clients.\n");
    3660           0 :                 ret = False;
    3661             :         }
    3662             : 
    3663           5 :         cli_state_set_uid(cli, saved_vuid);
    3664             : 
    3665             :         /* Try with same vuid, different cnum. */
    3666           5 :         cli_state_set_tid(cli, new_cnum);
    3667             : 
    3668           5 :         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
    3669           0 :                 printf("read succeeded with different cnum![%s]\n", buf);
    3670           0 :                 ret = false;
    3671             :         }
    3672             : 
    3673           5 :         cli_state_set_tid(cli, saved_cnum);
    3674           5 :         cli_close(cli, fnum1);
    3675           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3676             : 
    3677           5 :         torture_close_connection(cli);
    3678             : 
    3679           5 :         printf("finished fdsesstest\n");
    3680           5 :         return ret;
    3681             : }
    3682             : 
    3683             : /*
    3684             :   This test checks that 
    3685             : 
    3686             :   1) the server does not allow an unlink on a file that is open
    3687             : */
    3688           5 : static bool run_unlinktest(int dummy)
    3689             : {
    3690             :         struct cli_state *cli;
    3691           5 :         const char *fname = "\\unlink.tst";
    3692             :         uint16_t fnum;
    3693           5 :         bool correct = True;
    3694             :         NTSTATUS status;
    3695             : 
    3696           5 :         if (!torture_open_connection(&cli, 0)) {
    3697           0 :                 return False;
    3698             :         }
    3699             : 
    3700           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3701             : 
    3702           5 :         printf("starting unlink test\n");
    3703             : 
    3704           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3705             : 
    3706           5 :         cli_setpid(cli, 1);
    3707             : 
    3708           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    3709           5 :         if (!NT_STATUS_IS_OK(status)) {
    3710           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    3711           0 :                 return False;
    3712             :         }
    3713             : 
    3714           5 :         status = cli_unlink(cli, fname,
    3715             :                             FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3716           5 :         if (NT_STATUS_IS_OK(status)) {
    3717           0 :                 printf("error: server allowed unlink on an open file\n");
    3718           0 :                 correct = False;
    3719             :         } else {
    3720           5 :                 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
    3721           5 :                                       NT_STATUS_SHARING_VIOLATION);
    3722             :         }
    3723             : 
    3724           5 :         cli_close(cli, fnum);
    3725           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3726             : 
    3727           5 :         if (!torture_close_connection(cli)) {
    3728           0 :                 correct = False;
    3729             :         }
    3730             : 
    3731           5 :         printf("unlink test finished\n");
    3732             : 
    3733           5 :         return correct;
    3734             : }
    3735             : 
    3736             : 
    3737             : /*
    3738             : test how many open files this server supports on the one socket
    3739             : */
    3740           0 : static bool run_maxfidtest(int dummy)
    3741             : {
    3742             :         struct cli_state *cli;
    3743             :         fstring fname;
    3744             :         uint16_t fnums[0x11000];
    3745             :         int i;
    3746           0 :         int retries=4;
    3747           0 :         bool correct = True;
    3748             :         NTSTATUS status;
    3749             : 
    3750           0 :         cli = current_cli;
    3751             : 
    3752           0 :         if (retries <= 0) {
    3753           0 :                 printf("failed to connect\n");
    3754           0 :                 return False;
    3755             :         }
    3756             : 
    3757           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    3758             : 
    3759           0 :         for (i=0; i<0x11000; i++) {
    3760           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3761           0 :                 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
    3762             :                                   &fnums[i]);
    3763           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3764           0 :                         printf("open of %s failed (%s)\n", 
    3765             :                                fname, nt_errstr(status));
    3766           0 :                         printf("maximum fnum is %d\n", i);
    3767           0 :                         break;
    3768             :                 }
    3769           0 :                 printf("%6d\r", i);
    3770             :         }
    3771           0 :         printf("%6d\n", i);
    3772           0 :         i--;
    3773             : 
    3774           0 :         printf("cleaning up\n");
    3775           0 :         for (;i>=0;i--) {
    3776           0 :                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
    3777           0 :                 cli_close(cli, fnums[i]);
    3778             : 
    3779           0 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    3780           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3781           0 :                         printf("unlink of %s failed (%s)\n", 
    3782             :                                fname, nt_errstr(status));
    3783           0 :                         correct = False;
    3784             :                 }
    3785           0 :                 printf("%6d\r", i);
    3786             :         }
    3787           0 :         printf("%6d\n", 0);
    3788             : 
    3789           0 :         printf("maxfid test finished\n");
    3790           0 :         if (!torture_close_connection(cli)) {
    3791           0 :                 correct = False;
    3792             :         }
    3793           0 :         return correct;
    3794             : }
    3795             : 
    3796             : /* generate a random buffer */
    3797           0 : static void rand_buf(char *buf, int len)
    3798             : {
    3799           0 :         while (len--) {
    3800           0 :                 *buf = (char)sys_random();
    3801           0 :                 buf++;
    3802             :         }
    3803           0 : }
    3804             : 
    3805             : /* send smb negprot commands, not reading the response */
    3806           0 : static bool run_negprot_nowait(int dummy)
    3807             : {
    3808             :         struct tevent_context *ev;
    3809             :         int i;
    3810             :         struct cli_state *cli;
    3811           0 :         bool correct = True;
    3812             : 
    3813           0 :         printf("starting negprot nowait test\n");
    3814             : 
    3815           0 :         ev = samba_tevent_context_init(talloc_tos());
    3816           0 :         if (ev == NULL) {
    3817           0 :                 return false;
    3818             :         }
    3819             : 
    3820           0 :         if (!(cli = open_nbt_connection())) {
    3821           0 :                 TALLOC_FREE(ev);
    3822           0 :                 return False;
    3823             :         }
    3824             : 
    3825           0 :         for (i=0;i<50000;i++) {
    3826             :                 struct tevent_req *req;
    3827             : 
    3828           0 :                 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
    3829             :                                            PROTOCOL_CORE, PROTOCOL_NT1, 0);
    3830           0 :                 if (req == NULL) {
    3831           0 :                         TALLOC_FREE(ev);
    3832           0 :                         return false;
    3833             :                 }
    3834           0 :                 if (!tevent_req_poll(req, ev)) {
    3835           0 :                         d_fprintf(stderr, "tevent_req_poll failed: %s\n",
    3836           0 :                                   strerror(errno));
    3837           0 :                         TALLOC_FREE(ev);
    3838           0 :                         return false;
    3839             :                 }
    3840           0 :                 TALLOC_FREE(req);
    3841             :         }
    3842             : 
    3843           0 :         if (torture_close_connection(cli)) {
    3844           0 :                 correct = False;
    3845             :         }
    3846             : 
    3847           0 :         printf("finished negprot nowait test\n");
    3848             : 
    3849           0 :         return correct;
    3850             : }
    3851             : 
    3852             : /* send smb negprot commands, not reading the response */
    3853           4 : static bool run_bad_nbt_session(int dummy)
    3854             : {
    3855             :         struct nmb_name called, calling;
    3856             :         struct sockaddr_storage ss;
    3857             :         NTSTATUS status;
    3858             :         int fd;
    3859             :         bool ret;
    3860             : 
    3861           4 :         printf("starting bad nbt session test\n");
    3862             : 
    3863           4 :         make_nmb_name(&calling, myname, 0x0);
    3864           4 :         make_nmb_name(&called , host, 0x20);
    3865             : 
    3866           4 :         if (!resolve_name(host, &ss, 0x20, true)) {
    3867           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
    3868           0 :                 return false;
    3869             :         }
    3870             : 
    3871           4 :         status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
    3872           4 :         if (!NT_STATUS_IS_OK(status)) {
    3873           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    3874             :                           nt_errstr(status));
    3875           0 :                 return false;
    3876             :         }
    3877             : 
    3878           4 :         ret = cli_bad_session_request(fd, &calling, &called);
    3879           4 :         close(fd);
    3880           4 :         if (!ret) {
    3881           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
    3882             :                           nt_errstr(status));
    3883           0 :                 return false;
    3884             :         }
    3885             : 
    3886           4 :         printf("finished bad nbt session test\n");
    3887           4 :         return true;
    3888             : }
    3889             : 
    3890             : /* send random IPC commands */
    3891           0 : static bool run_randomipc(int dummy)
    3892             : {
    3893           0 :         char *rparam = NULL;
    3894           0 :         char *rdata = NULL;
    3895             :         unsigned int rdrcnt,rprcnt;
    3896             :         char param[1024];
    3897             :         int api, param_len, i;
    3898             :         struct cli_state *cli;
    3899           0 :         bool correct = True;
    3900           0 :         int count = 50000;
    3901             : 
    3902           0 :         printf("starting random ipc test\n");
    3903             : 
    3904           0 :         if (!torture_open_connection(&cli, 0)) {
    3905           0 :                 return False;
    3906             :         }
    3907             : 
    3908           0 :         for (i=0;i<count;i++) {
    3909           0 :                 api = sys_random() % 500;
    3910           0 :                 param_len = (sys_random() % 64);
    3911             : 
    3912           0 :                 rand_buf(param, param_len);
    3913             : 
    3914           0 :                 SSVAL(param,0,api); 
    3915             : 
    3916           0 :                 cli_api(cli, 
    3917             :                         param, param_len, 8,  
    3918             :                         NULL, 0, CLI_BUFFER_SIZE,
    3919             :                         &rparam, &rprcnt,     
    3920             :                         &rdata, &rdrcnt);
    3921           0 :                 if (i % 100 == 0) {
    3922           0 :                         printf("%d/%d\r", i,count);
    3923             :                 }
    3924             :         }
    3925           0 :         printf("%d/%d\n", i, count);
    3926             : 
    3927           0 :         if (!torture_close_connection(cli)) {
    3928           0 :                 correct = False;
    3929             :         }
    3930             : 
    3931           0 :         SAFE_FREE(rparam);
    3932           0 :         SAFE_FREE(rdata);
    3933             : 
    3934           0 :         printf("finished random ipc test\n");
    3935             : 
    3936           0 :         return correct;
    3937             : }
    3938             : 
    3939             : 
    3940             : 
    3941           8 : static void browse_callback(const char *sname, uint32_t stype,
    3942             :                             const char *comment, void *state)
    3943             : {
    3944           8 :         printf("\t%20.20s %08x %s\n", sname, stype, comment);
    3945           8 : }
    3946             : 
    3947             : 
    3948             : 
    3949             : /*
    3950             :   This test checks the browse list code
    3951             : 
    3952             : */
    3953           5 : static bool run_browsetest(int dummy)
    3954             : {
    3955             :         static struct cli_state *cli;
    3956           5 :         bool correct = True;
    3957             : 
    3958           5 :         printf("starting browse test\n");
    3959             : 
    3960           5 :         if (!torture_open_connection(&cli, 0)) {
    3961           0 :                 return False;
    3962             :         }
    3963             : 
    3964           5 :         printf("domain list:\n");
    3965           5 :         cli_NetServerEnum(cli, cli->server_domain, 
    3966             :                           SV_TYPE_DOMAIN_ENUM,
    3967             :                           browse_callback, NULL);
    3968             : 
    3969           5 :         printf("machine list:\n");
    3970           5 :         cli_NetServerEnum(cli, cli->server_domain, 
    3971             :                           SV_TYPE_ALL,
    3972             :                           browse_callback, NULL);
    3973             : 
    3974           5 :         if (!torture_close_connection(cli)) {
    3975           0 :                 correct = False;
    3976             :         }
    3977             : 
    3978           5 :         printf("browse test finished\n");
    3979             : 
    3980           5 :         return correct;
    3981             : 
    3982             : }
    3983             : 
    3984          20 : static bool check_attributes(struct cli_state *cli,
    3985             :                                 const char *fname,
    3986             :                                 uint32_t expected_attrs)
    3987             : {
    3988          20 :         uint32_t attrs = 0;
    3989          20 :         NTSTATUS status = cli_getatr(cli,
    3990             :                                 fname,
    3991             :                                 &attrs,
    3992             :                                 NULL,
    3993             :                                 NULL);
    3994          20 :         if (!NT_STATUS_IS_OK(status)) {
    3995           0 :                 printf("cli_getatr failed with %s\n",
    3996             :                         nt_errstr(status));
    3997           0 :                 return false;
    3998             :         }
    3999          20 :         if (attrs != expected_attrs) {
    4000           0 :                 printf("Attributes incorrect 0x%x, should be 0x%x\n",
    4001             :                         (unsigned int)attrs,
    4002             :                         (unsigned int)expected_attrs);
    4003           0 :                 return false;
    4004             :         }
    4005          20 :         return true;
    4006             : }
    4007             : 
    4008             : /*
    4009             :   This checks how the getatr calls works
    4010             : */
    4011           5 : static bool run_attrtest(int dummy)
    4012             : {
    4013             :         struct cli_state *cli;
    4014             :         uint16_t fnum;
    4015             :         time_t t, t2;
    4016           5 :         const char *fname = "\\attrib123456789.tst";
    4017           5 :         bool correct = True;
    4018             :         NTSTATUS status;
    4019             : 
    4020           5 :         printf("starting attrib test\n");
    4021             : 
    4022           5 :         if (!torture_open_connection(&cli, 0)) {
    4023           0 :                 return False;
    4024             :         }
    4025             : 
    4026             :         /* Ensure we can't unlink with out-of-range (unknown) attribute. */
    4027           5 :         status = cli_unlink(cli, fname, 0x20000);
    4028           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4029           0 :                 correct = false;
    4030           0 :                 goto out;
    4031             :         }
    4032             : 
    4033           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4034           5 :         cli_openx(cli, fname, 
    4035             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4036           5 :         cli_close(cli, fnum);
    4037             : 
    4038           5 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4039           5 :         if (!NT_STATUS_IS_OK(status)) {
    4040           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4041           0 :                 correct = False;
    4042             :         }
    4043             : 
    4044           5 :         if (labs(t - time(NULL)) > 60*60*24*10) {
    4045           0 :                 printf("ERROR: SMBgetatr bug. time is %s",
    4046             :                        ctime(&t));
    4047           0 :                 t = time(NULL);
    4048           0 :                 correct = True;
    4049             :         }
    4050             : 
    4051           5 :         t2 = t-60*60*24; /* 1 day ago */
    4052             : 
    4053             :         /* Ensure we can't set with out-of-range (unknown) attribute. */
    4054           5 :         status = cli_setatr(cli, fname, 0x20000, t2);
    4055           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    4056           0 :                 correct = false;
    4057           0 :                 goto out;
    4058             :         }
    4059             : 
    4060           5 :         status = cli_setatr(cli, fname, 0, t2);
    4061           5 :         if (!NT_STATUS_IS_OK(status)) {
    4062           0 :                 printf("setatr failed (%s)\n", nt_errstr(status));
    4063           0 :                 correct = True;
    4064             :         }
    4065             : 
    4066           5 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    4067           5 :         if (!NT_STATUS_IS_OK(status)) {
    4068           0 :                 printf("getatr failed (%s)\n", nt_errstr(status));
    4069           0 :                 correct = True;
    4070             :         }
    4071             : 
    4072           5 :         if (t != t2) {
    4073           0 :                 printf("ERROR: getatr/setatr bug. times are\n%s",
    4074             :                        ctime(&t));
    4075           0 :                 printf("%s", ctime(&t2));
    4076           0 :                 correct = True;
    4077             :         }
    4078             : 
    4079           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4080             : 
    4081             :         /* Check cli_setpathinfo_ext() */
    4082             :         /* Re-create the file. */
    4083           5 :         status = cli_openx(cli, fname,
    4084             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4085           5 :         if (!NT_STATUS_IS_OK(status)) {
    4086           0 :                 printf("Failed to recreate %s (%s)\n",
    4087             :                         fname, nt_errstr(status));
    4088           0 :                 correct = false;
    4089             :         }
    4090           5 :         cli_close(cli, fnum);
    4091             : 
    4092           5 :         status = cli_setpathinfo_ext(
    4093             :                 cli,
    4094             :                 fname,
    4095           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4096           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4097           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4098           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4099             :                 FILE_ATTRIBUTE_SYSTEM |
    4100             :                 FILE_ATTRIBUTE_HIDDEN |
    4101             :                 FILE_ATTRIBUTE_READONLY);
    4102           5 :         if (!NT_STATUS_IS_OK(status)) {
    4103           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4104             :                         nt_errstr(status));
    4105           0 :                 correct = false;
    4106             :         }
    4107             : 
    4108             :         /* Check attributes are correct. */
    4109           5 :         correct = check_attributes(cli,
    4110             :                         fname,
    4111             :                         FILE_ATTRIBUTE_SYSTEM |
    4112             :                         FILE_ATTRIBUTE_HIDDEN |
    4113             :                         FILE_ATTRIBUTE_READONLY);
    4114           5 :         if (correct == false) {
    4115           0 :                 goto out;
    4116             :         }
    4117             : 
    4118             :         /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
    4119           5 :         status = cli_setpathinfo_ext(
    4120             :                 cli,
    4121             :                 fname,
    4122           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4123           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4124           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4125           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4126             :                 FILE_ATTRIBUTE_NORMAL);
    4127           5 :         if (!NT_STATUS_IS_OK(status)) {
    4128           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4129             :                         nt_errstr(status));
    4130           0 :                 correct = false;
    4131             :         }
    4132             : 
    4133             :         /* Check attributes are correct. */
    4134           5 :         correct = check_attributes(cli,
    4135             :                         fname,
    4136             :                         FILE_ATTRIBUTE_SYSTEM |
    4137             :                         FILE_ATTRIBUTE_HIDDEN |
    4138             :                         FILE_ATTRIBUTE_READONLY);
    4139           5 :         if (correct == false) {
    4140           0 :                 goto out;
    4141             :         }
    4142             : 
    4143             :         /* Setting to (uint16_t)-1 should also be ignored. */
    4144           5 :         status = cli_setpathinfo_ext(
    4145             :                 cli,
    4146             :                 fname,
    4147           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4148           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4149           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4150           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4151             :                 (uint32_t)-1);
    4152           5 :         if (!NT_STATUS_IS_OK(status)) {
    4153           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4154             :                         nt_errstr(status));
    4155           0 :                 correct = false;
    4156             :         }
    4157             : 
    4158             :         /* Check attributes are correct. */
    4159           5 :         correct = check_attributes(cli,
    4160             :                         fname,
    4161             :                         FILE_ATTRIBUTE_SYSTEM |
    4162             :                         FILE_ATTRIBUTE_HIDDEN |
    4163             :                         FILE_ATTRIBUTE_READONLY);
    4164           5 :         if (correct == false) {
    4165           0 :                 goto out;
    4166             :         }
    4167             : 
    4168             :         /* Setting to 0 should clear them all. */
    4169           5 :         status = cli_setpathinfo_ext(
    4170             :                 cli,
    4171             :                 fname,
    4172           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* create */
    4173           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
    4174           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
    4175           5 :                 (struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
    4176             :                 0);
    4177           5 :         if (!NT_STATUS_IS_OK(status)) {
    4178           0 :                 printf("cli_setpathinfo_ext failed with %s\n",
    4179             :                         nt_errstr(status));
    4180           0 :                 correct = false;
    4181             :         }
    4182             : 
    4183             :         /* Check attributes are correct. */
    4184           5 :         correct = check_attributes(cli,
    4185             :                         fname,
    4186             :                         FILE_ATTRIBUTE_NORMAL);
    4187           5 :         if (correct == false) {
    4188           0 :                 goto out;
    4189             :         }
    4190             : 
    4191          10 :   out:
    4192             : 
    4193           5 :         cli_unlink(cli,
    4194             :                 fname,
    4195             :                 FILE_ATTRIBUTE_SYSTEM |
    4196             :                 FILE_ATTRIBUTE_HIDDEN|
    4197             :                 FILE_ATTRIBUTE_READONLY);
    4198             : 
    4199           5 :         if (!torture_close_connection(cli)) {
    4200           0 :                 correct = False;
    4201             :         }
    4202             : 
    4203           5 :         printf("attrib test finished\n");
    4204             : 
    4205           5 :         return correct;
    4206             : }
    4207             : 
    4208             : 
    4209             : /*
    4210             :   This checks a couple of trans2 calls
    4211             : */
    4212           5 : static bool run_trans2test(int dummy)
    4213             : {
    4214             :         struct cli_state *cli;
    4215             :         uint16_t fnum;
    4216             :         off_t size;
    4217             :         time_t c_time, a_time, m_time;
    4218             :         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
    4219           5 :         const char *fname = "\\trans2.tst";
    4220           5 :         const char *dname = "\\trans2";
    4221           5 :         const char *fname2 = "\\trans2\\trans2.tst";
    4222             :         char *pname;
    4223           5 :         bool correct = True;
    4224             :         NTSTATUS status;
    4225             :         uint32_t fs_attr;
    4226             :         uint64_t ino;
    4227             : 
    4228           5 :         printf("starting trans2 test\n");
    4229             : 
    4230           5 :         if (!torture_open_connection(&cli, 0)) {
    4231           0 :                 return False;
    4232             :         }
    4233             : 
    4234           5 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4235             :                 /* Ensure ino is zero, SMB2 gets a real one. */
    4236           0 :                 ino = 0;
    4237             :         } else {
    4238             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
    4239           5 :                 ino = (uint64_t)-1;
    4240             :         }
    4241             : 
    4242           5 :         status = cli_get_fs_attr_info(cli, &fs_attr);
    4243           5 :         if (!NT_STATUS_IS_OK(status)) {
    4244           0 :                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
    4245             :                        nt_errstr(status));
    4246           0 :                 correct = false;
    4247             :         }
    4248             : 
    4249           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4250           5 :         cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4251           5 :         status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
    4252             :                                      &a_time_ts, &w_time_ts, &m_time_ts, NULL);
    4253           5 :         if (!NT_STATUS_IS_OK(status)) {
    4254           0 :                 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
    4255           0 :                 correct = False;
    4256             :         }
    4257             : 
    4258           5 :         status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
    4259           5 :         if (!NT_STATUS_IS_OK(status)) {
    4260           0 :                 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
    4261           0 :                 correct = False;
    4262             :         }
    4263           5 :         else if (strcmp(pname, fname)) {
    4264           0 :                 printf("qfilename gave different name? [%s] [%s]\n",
    4265             :                        fname, pname);
    4266           0 :                 correct = False;
    4267             :         }
    4268             : 
    4269           5 :         cli_close(cli, fnum);
    4270             : 
    4271           5 :         sleep(2);
    4272             : 
    4273           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4274           5 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
    4275             :                           &fnum);
    4276           5 :         if (!NT_STATUS_IS_OK(status)) {
    4277           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4278           0 :                 return False;
    4279             :         }
    4280           5 :         cli_close(cli, fnum);
    4281             : 
    4282           5 :         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
    4283             :                                 NULL);
    4284           5 :         if (!NT_STATUS_IS_OK(status)) {
    4285           0 :                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
    4286           0 :                 correct = False;
    4287             :         } else {
    4288           5 :                 time_t t = time(NULL);
    4289             : 
    4290           5 :                 if (c_time != m_time) {
    4291           0 :                         printf("create time=%s", ctime(&c_time));
    4292           0 :                         printf("modify time=%s", ctime(&m_time));
    4293           0 :                         printf("This system appears to have sticky create times\n");
    4294             :                 }
    4295           5 :                 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
    4296           0 :                         printf("access time=%s", ctime(&a_time));
    4297           0 :                         printf("This system appears to set a midnight access time\n");
    4298           0 :                         correct = False;
    4299             :                 }
    4300             : 
    4301           5 :                 if (labs(m_time - t) > 60*60*24*7) {
    4302           0 :                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
    4303           0 :                         correct = False;
    4304             :                 }
    4305             :         }
    4306             : 
    4307             : 
    4308           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4309           5 :         cli_openx(cli, fname, 
    4310             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4311           5 :         cli_close(cli, fnum);
    4312           5 :         status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
    4313             :                                 &m_time_ts, &size, NULL, &ino);
    4314           5 :         if (!NT_STATUS_IS_OK(status)) {
    4315           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4316           0 :                 correct = False;
    4317             :         } else {
    4318           5 :                 if (w_time_ts.tv_sec < 60*60*24*2) {
    4319           0 :                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
    4320           0 :                         printf("This system appears to set a initial 0 write time\n");
    4321           0 :                         correct = False;
    4322             :                 }
    4323           5 :                 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
    4324             :                         /* SMB2 should always return an inode. */
    4325           0 :                         if (ino == 0) {
    4326           0 :                                 printf("SMB2 bad inode (0)\n");
    4327           0 :                                 correct = false;
    4328             :                         }
    4329             :                 } else {
    4330             :                         /* SMB1 must always return zero here. */
    4331           5 :                         if (ino != 0) {
    4332           0 :                                 printf("SMB1 bad inode (!0)\n");
    4333           0 :                                 correct = false;
    4334             :                         }
    4335             :                 }
    4336             :         }
    4337             : 
    4338           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4339             : 
    4340             : 
    4341             :         /* check if the server updates the directory modification time
    4342             :            when creating a new file */
    4343           5 :         status = cli_mkdir(cli, dname);
    4344           5 :         if (!NT_STATUS_IS_OK(status)) {
    4345           0 :                 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
    4346           0 :                 correct = False;
    4347             :         }
    4348           5 :         sleep(3);
    4349           5 :         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
    4350             :                                 &w_time_ts, &m_time_ts, &size, NULL, NULL);
    4351           5 :         if (!NT_STATUS_IS_OK(status)) {
    4352           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4353           0 :                 correct = False;
    4354             :         }
    4355             : 
    4356           5 :         cli_openx(cli, fname2, 
    4357             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
    4358           5 :         cli_writeall(cli, fnum,  0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
    4359           5 :         cli_close(cli, fnum);
    4360           5 :         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
    4361             :                                 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
    4362           5 :         if (!NT_STATUS_IS_OK(status)) {
    4363           0 :                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
    4364           0 :                 correct = False;
    4365             :         } else {
    4366           5 :                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
    4367             :                     == 0) {
    4368           0 :                         printf("This system does not update directory modification times\n");
    4369           0 :                         correct = False;
    4370             :                 }
    4371             :         }
    4372           5 :         cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4373           5 :         cli_rmdir(cli, dname);
    4374             : 
    4375           5 :         if (!torture_close_connection(cli)) {
    4376           0 :                 correct = False;
    4377             :         }
    4378             : 
    4379           5 :         printf("trans2 test finished\n");
    4380             : 
    4381           5 :         return correct;
    4382             : }
    4383             : 
    4384             : /*
    4385             :   This checks new W2K calls.
    4386             : */
    4387             : 
    4388         180 : static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
    4389             : {
    4390         180 :         uint8_t *buf = NULL;
    4391             :         uint32_t len;
    4392             :         NTSTATUS status;
    4393             : 
    4394         180 :         status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
    4395             :                                CLI_BUFFER_SIZE, NULL, &buf, &len);
    4396         180 :         if (!NT_STATUS_IS_OK(status)) {
    4397         180 :                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
    4398             :                        nt_errstr(status));
    4399             :         } else {
    4400           0 :                 printf("qfileinfo: level %d, len = %u\n", level, len);
    4401           0 :                 dump_data(0, (uint8_t *)buf, len);
    4402           0 :                 printf("\n");
    4403             :         }
    4404         180 :         TALLOC_FREE(buf);
    4405         180 :         return status;
    4406             : }
    4407             : 
    4408           5 : static bool run_w2ktest(int dummy)
    4409             : {
    4410             :         struct cli_state *cli;
    4411             :         uint16_t fnum;
    4412           5 :         const char *fname = "\\w2ktest\\w2k.tst";
    4413             :         int level;
    4414           5 :         bool correct = True;
    4415             : 
    4416           5 :         printf("starting w2k test\n");
    4417             : 
    4418           5 :         if (!torture_open_connection(&cli, 0)) {
    4419           0 :                 return False;
    4420             :         }
    4421             : 
    4422           5 :         cli_openx(cli, fname, 
    4423             :                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
    4424             : 
    4425         185 :         for (level = 1004; level < 1040; level++) {
    4426         180 :                 new_trans(cli, fnum, level);
    4427             :         }
    4428             : 
    4429           5 :         cli_close(cli, fnum);
    4430             : 
    4431           5 :         if (!torture_close_connection(cli)) {
    4432           0 :                 correct = False;
    4433             :         }
    4434             : 
    4435           5 :         printf("w2k test finished\n");
    4436             : 
    4437           5 :         return correct;
    4438             : }
    4439             : 
    4440             : 
    4441             : /*
    4442             :   this is a harness for some oplock tests
    4443             :  */
    4444           5 : static bool run_oplock1(int dummy)
    4445             : {
    4446             :         struct cli_state *cli1;
    4447           5 :         const char *fname = "\\lockt1.lck";
    4448             :         uint16_t fnum1;
    4449           5 :         bool correct = True;
    4450             :         NTSTATUS status;
    4451             : 
    4452           5 :         printf("starting oplock test 1\n");
    4453             : 
    4454           5 :         if (!torture_open_connection(&cli1, 0)) {
    4455           0 :                 return False;
    4456             :         }
    4457             : 
    4458           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4459             : 
    4460           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4461             : 
    4462           5 :         cli1->use_oplocks = True;
    4463             : 
    4464           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4465             :                           &fnum1);
    4466           5 :         if (!NT_STATUS_IS_OK(status)) {
    4467           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4468           0 :                 return False;
    4469             :         }
    4470             : 
    4471           5 :         cli1->use_oplocks = False;
    4472             : 
    4473           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4474           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4475             : 
    4476           5 :         status = cli_close(cli1, fnum1);
    4477           5 :         if (!NT_STATUS_IS_OK(status)) {
    4478           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    4479           0 :                 return False;
    4480             :         }
    4481             : 
    4482           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4483           5 :         if (!NT_STATUS_IS_OK(status)) {
    4484           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4485           0 :                 return False;
    4486             :         }
    4487             : 
    4488           5 :         if (!torture_close_connection(cli1)) {
    4489           0 :                 correct = False;
    4490             :         }
    4491             : 
    4492           5 :         printf("finished oplock test 1\n");
    4493             : 
    4494           5 :         return correct;
    4495             : }
    4496             : 
    4497           4 : static bool run_oplock2(int dummy)
    4498             : {
    4499             :         struct cli_state *cli1, *cli2;
    4500           4 :         const char *fname = "\\lockt2.lck";
    4501             :         uint16_t fnum1, fnum2;
    4502           4 :         int saved_use_oplocks = use_oplocks;
    4503             :         char buf[4];
    4504           4 :         bool correct = True;
    4505             :         volatile bool *shared_correct;
    4506             :         size_t nread;
    4507             :         NTSTATUS status;
    4508             : 
    4509           4 :         shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
    4510           4 :         *shared_correct = True;
    4511             : 
    4512           4 :         use_level_II_oplocks = True;
    4513           4 :         use_oplocks = True;
    4514             : 
    4515           4 :         printf("starting oplock test 2\n");
    4516             : 
    4517           4 :         if (!torture_open_connection(&cli1, 0)) {
    4518           0 :                 use_level_II_oplocks = False;
    4519           0 :                 use_oplocks = saved_use_oplocks;
    4520           0 :                 return False;
    4521             :         }
    4522             : 
    4523           4 :         if (!torture_open_connection(&cli2, 1)) {
    4524           0 :                 use_level_II_oplocks = False;
    4525           0 :                 use_oplocks = saved_use_oplocks;
    4526           0 :                 return False;
    4527             :         }
    4528             : 
    4529           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4530             : 
    4531           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4532           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4533             : 
    4534           4 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4535             :                           &fnum1);
    4536           4 :         if (!NT_STATUS_IS_OK(status)) {
    4537           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4538           0 :                 return False;
    4539             :         }
    4540             : 
    4541             :         /* Don't need the globals any more. */
    4542           4 :         use_level_II_oplocks = False;
    4543           4 :         use_oplocks = saved_use_oplocks;
    4544             : 
    4545           4 :         if (fork() == 0) {
    4546             :                 /* Child code */
    4547           4 :                 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
    4548           4 :                 if (!NT_STATUS_IS_OK(status)) {
    4549           0 :                         printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
    4550           0 :                         *shared_correct = False;
    4551           0 :                         exit(0);
    4552             :                 }
    4553             : 
    4554           4 :                 sleep(2);
    4555             : 
    4556           4 :                 status = cli_close(cli2, fnum2);
    4557           4 :                 if (!NT_STATUS_IS_OK(status)) {
    4558           0 :                         printf("close2 failed (%s)\n", nt_errstr(status));
    4559           0 :                         *shared_correct = False;
    4560             :                 }
    4561             : 
    4562           4 :                 exit(0);
    4563             :         }
    4564             : 
    4565           4 :         sleep(2);
    4566             : 
    4567             :         /* Ensure cli1 processes the break. Empty file should always return 0
    4568             :          * bytes.  */
    4569           4 :         status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
    4570           4 :         if (!NT_STATUS_IS_OK(status)) {
    4571           0 :                 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
    4572           0 :                 correct = false;
    4573           4 :         } else if (nread != 0) {
    4574           0 :                 printf("read on empty fnum1 failed. recv %ld expected %d\n",
    4575             :                       (unsigned long)nread, 0);
    4576           0 :                 correct = false;
    4577             :         }
    4578             : 
    4579             :         /* Should now be at level II. */
    4580             :         /* Test if sending a write locks causes a break to none. */
    4581           4 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
    4582           4 :         if (!NT_STATUS_IS_OK(status)) {
    4583           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4584           0 :                 correct = False;
    4585             :         }
    4586             : 
    4587           4 :         cli_unlock(cli1, fnum1, 0, 4);
    4588             : 
    4589           4 :         sleep(2);
    4590             : 
    4591           4 :         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
    4592           4 :         if (!NT_STATUS_IS_OK(status)) {
    4593           0 :                 printf("lock failed (%s)\n", nt_errstr(status));
    4594           0 :                 correct = False;
    4595             :         }
    4596             : 
    4597           4 :         cli_unlock(cli1, fnum1, 0, 4);
    4598             : 
    4599           4 :         sleep(2);
    4600             : 
    4601           4 :         cli_read(cli1, fnum1, buf, 0, 4, NULL);
    4602             : 
    4603           4 :         status = cli_close(cli1, fnum1);
    4604           4 :         if (!NT_STATUS_IS_OK(status)) {
    4605           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4606           0 :                 correct = False;
    4607             :         }
    4608             : 
    4609           4 :         sleep(4);
    4610             : 
    4611           4 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4612           4 :         if (!NT_STATUS_IS_OK(status)) {
    4613           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4614           0 :                 correct = False;
    4615             :         }
    4616             : 
    4617           4 :         if (!torture_close_connection(cli1)) {
    4618           0 :                 correct = False;
    4619             :         }
    4620             : 
    4621           4 :         if (!*shared_correct) {
    4622           0 :                 correct = False;
    4623             :         }
    4624             : 
    4625           4 :         printf("finished oplock test 2\n");
    4626             : 
    4627           4 :         return correct;
    4628             : }
    4629             : 
    4630             : struct oplock4_state {
    4631             :         struct tevent_context *ev;
    4632             :         struct cli_state *cli;
    4633             :         bool *got_break;
    4634             :         uint16_t *fnum2;
    4635             : };
    4636             : 
    4637             : static void oplock4_got_break(struct tevent_req *req);
    4638             : static void oplock4_got_open(struct tevent_req *req);
    4639             : 
    4640           5 : static bool run_oplock4(int dummy)
    4641             : {
    4642             :         struct tevent_context *ev;
    4643             :         struct cli_state *cli1, *cli2;
    4644             :         struct tevent_req *oplock_req, *open_req;
    4645           5 :         const char *fname = "\\lockt4.lck";
    4646           5 :         const char *fname_ln = "\\lockt4_ln.lck";
    4647             :         uint16_t fnum1, fnum2;
    4648           5 :         int saved_use_oplocks = use_oplocks;
    4649             :         NTSTATUS status;
    4650           5 :         bool correct = true;
    4651             : 
    4652             :         bool got_break;
    4653             : 
    4654             :         struct oplock4_state *state;
    4655             : 
    4656           5 :         printf("starting oplock test 4\n");
    4657             : 
    4658           5 :         if (!torture_open_connection(&cli1, 0)) {
    4659           0 :                 use_level_II_oplocks = false;
    4660           0 :                 use_oplocks = saved_use_oplocks;
    4661           0 :                 return false;
    4662             :         }
    4663             : 
    4664           5 :         if (!torture_open_connection(&cli2, 1)) {
    4665           0 :                 use_level_II_oplocks = false;
    4666           0 :                 use_oplocks = saved_use_oplocks;
    4667           0 :                 return false;
    4668             :         }
    4669             : 
    4670           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4671           5 :         cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4672             : 
    4673           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    4674           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    4675             : 
    4676             :         /* Create the file. */
    4677           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    4678             :                           &fnum1);
    4679           5 :         if (!NT_STATUS_IS_OK(status)) {
    4680           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4681           0 :                 return false;
    4682             :         }
    4683             : 
    4684           5 :         status = cli_close(cli1, fnum1);
    4685           5 :         if (!NT_STATUS_IS_OK(status)) {
    4686           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4687           0 :                 return false;
    4688             :         }
    4689             : 
    4690             :         /* Now create a hardlink. */
    4691           5 :         status = cli_hardlink(cli1, fname, fname_ln);
    4692           5 :         if (!NT_STATUS_IS_OK(status)) {
    4693           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    4694           0 :                 return false;
    4695             :         }
    4696             : 
    4697             :         /* Prove that opening hardlinks cause deny modes to conflict. */
    4698           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
    4699           5 :         if (!NT_STATUS_IS_OK(status)) {
    4700           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4701           0 :                 return false;
    4702             :         }
    4703             : 
    4704           5 :         status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
    4705           5 :         if (NT_STATUS_IS_OK(status)) {
    4706           0 :                 printf("open of %s succeeded - should fail with sharing violation.\n",
    4707             :                         fname_ln);
    4708           0 :                 return false;
    4709             :         }
    4710             : 
    4711           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    4712           0 :                 printf("open of %s should fail with sharing violation. Got %s\n",
    4713             :                         fname_ln, nt_errstr(status));
    4714           0 :                 return false;
    4715             :         }
    4716             : 
    4717           5 :         status = cli_close(cli1, fnum1);
    4718           5 :         if (!NT_STATUS_IS_OK(status)) {
    4719           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4720           0 :                 return false;
    4721             :         }
    4722             : 
    4723           5 :         cli1->use_oplocks = true;
    4724           5 :         cli2->use_oplocks = true;
    4725             : 
    4726           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    4727           5 :         if (!NT_STATUS_IS_OK(status)) {
    4728           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    4729           0 :                 return false;
    4730             :         }
    4731             : 
    4732           5 :         ev = samba_tevent_context_init(talloc_tos());
    4733           5 :         if (ev == NULL) {
    4734           0 :                 printf("tevent_context_init failed\n");
    4735           0 :                 return false;
    4736             :         }
    4737             : 
    4738           5 :         state = talloc(ev, struct oplock4_state);
    4739           5 :         if (state == NULL) {
    4740           0 :                 printf("talloc failed\n");
    4741           0 :                 return false;
    4742             :         }
    4743           5 :         state->ev = ev;
    4744           5 :         state->cli = cli1;
    4745           5 :         state->got_break = &got_break;
    4746           5 :         state->fnum2 = &fnum2;
    4747             : 
    4748           5 :         oplock_req = cli_smb_oplock_break_waiter_send(
    4749             :                 talloc_tos(), ev, cli1);
    4750           5 :         if (oplock_req == NULL) {
    4751           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    4752           0 :                 return false;
    4753             :         }
    4754           5 :         tevent_req_set_callback(oplock_req, oplock4_got_break, state);
    4755             : 
    4756           5 :         open_req = cli_openx_send(
    4757             :                 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
    4758           5 :         if (open_req == NULL) {
    4759           0 :                 printf("cli_openx_send failed\n");
    4760           0 :                 return false;
    4761             :         }
    4762           5 :         tevent_req_set_callback(open_req, oplock4_got_open, state);
    4763             : 
    4764           5 :         got_break = false;
    4765           5 :         fnum2 = 0xffff;
    4766             : 
    4767          45 :         while (!got_break || fnum2 == 0xffff) {
    4768             :                 int ret;
    4769          35 :                 ret = tevent_loop_once(ev);
    4770          35 :                 if (ret == -1) {
    4771           0 :                         printf("tevent_loop_once failed: %s\n",
    4772           0 :                                strerror(errno));
    4773           0 :                         return false;
    4774             :                 }
    4775             :         }
    4776             : 
    4777           5 :         status = cli_close(cli2, fnum2);
    4778           5 :         if (!NT_STATUS_IS_OK(status)) {
    4779           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    4780           0 :                 correct = false;
    4781             :         }
    4782             : 
    4783           5 :         status = cli_close(cli1, fnum1);
    4784           5 :         if (!NT_STATUS_IS_OK(status)) {
    4785           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    4786           0 :                 correct = false;
    4787             :         }
    4788             : 
    4789           5 :         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4790           5 :         if (!NT_STATUS_IS_OK(status)) {
    4791           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4792           0 :                 correct = false;
    4793             :         }
    4794             : 
    4795           5 :         status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    4796           5 :         if (!NT_STATUS_IS_OK(status)) {
    4797           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    4798           0 :                 correct = false;
    4799             :         }
    4800             : 
    4801           5 :         if (!torture_close_connection(cli1)) {
    4802           0 :                 correct = false;
    4803             :         }
    4804             : 
    4805           5 :         if (!got_break) {
    4806           0 :                 correct = false;
    4807             :         }
    4808             : 
    4809           5 :         printf("finished oplock test 4\n");
    4810             : 
    4811           5 :         return correct;
    4812             : }
    4813             : 
    4814           5 : static void oplock4_got_break(struct tevent_req *req)
    4815             : {
    4816           5 :         struct oplock4_state *state = tevent_req_callback_data(
    4817             :                 req, struct oplock4_state);
    4818             :         uint16_t fnum;
    4819             :         uint8_t level;
    4820             :         NTSTATUS status;
    4821             : 
    4822           5 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    4823           5 :         TALLOC_FREE(req);
    4824           5 :         if (!NT_STATUS_IS_OK(status)) {
    4825           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    4826             :                        nt_errstr(status));
    4827           0 :                 return;
    4828             :         }
    4829           5 :         *state->got_break = true;
    4830             : 
    4831           5 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    4832             :                                   NO_OPLOCK);
    4833           5 :         if (req == NULL) {
    4834           0 :                 printf("cli_oplock_ack_send failed\n");
    4835           0 :                 return;
    4836             :         }
    4837             : }
    4838             : 
    4839           5 : static void oplock4_got_open(struct tevent_req *req)
    4840             : {
    4841           5 :         struct oplock4_state *state = tevent_req_callback_data(
    4842             :                 req, struct oplock4_state);
    4843             :         NTSTATUS status;
    4844             : 
    4845           5 :         status = cli_openx_recv(req, state->fnum2);
    4846           5 :         if (!NT_STATUS_IS_OK(status)) {
    4847           0 :                 printf("cli_openx_recv returned %s\n", nt_errstr(status));
    4848           0 :                 *state->fnum2 = 0xffff;
    4849             :         }
    4850           5 : }
    4851             : 
    4852             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
    4853             : 
    4854             : struct oplock5_state {
    4855             :         int pipe_down_fd;
    4856             : };
    4857             : 
    4858             : /*
    4859             :  * Async open the file that has a kernel oplock, do an echo to get
    4860             :  * that 100% across, close the file to signal to the child fd that the
    4861             :  * oplock can be dropped, wait for the open reply.
    4862             :  */
    4863             : 
    4864             : static void oplock5_opened(struct tevent_req *subreq);
    4865             : static void oplock5_pong(struct tevent_req *subreq);
    4866             : static void oplock5_timedout(struct tevent_req *subreq);
    4867             : 
    4868           1 : static struct tevent_req *oplock5_send(
    4869             :         TALLOC_CTX *mem_ctx,
    4870             :         struct tevent_context *ev,
    4871             :         struct cli_state *cli,
    4872             :         const char *fname,
    4873             :         int pipe_down_fd)
    4874             : {
    4875           1 :         struct tevent_req *req = NULL, *subreq = NULL;
    4876           1 :         struct oplock5_state *state = NULL;
    4877             :         static uint8_t data = 0;
    4878             : 
    4879           1 :         req = tevent_req_create(mem_ctx, &state, struct oplock5_state);
    4880           1 :         if (req == NULL) {
    4881           0 :                 return NULL;
    4882             :         }
    4883           1 :         state->pipe_down_fd = pipe_down_fd;
    4884             : 
    4885           1 :         subreq = cli_ntcreate_send(
    4886             :                 state,
    4887             :                 ev,
    4888             :                 cli,
    4889             :                 fname,
    4890             :                 0,                      /* CreatFlags */
    4891             :                 SEC_FILE_READ_DATA,    /* DesiredAccess */
    4892             :                 FILE_ATTRIBUTE_NORMAL,  /* FileAttributes */
    4893             :                 FILE_SHARE_WRITE|FILE_SHARE_READ, /* ShareAccess */
    4894             :                 FILE_OPEN,               /* CreateDisposition */
    4895             :                 FILE_NON_DIRECTORY_FILE, /* CreateOptions */
    4896             :                 0,                       /* Impersonation */
    4897             :                 0);                      /* SecurityFlags */
    4898           1 :         if (tevent_req_nomem(subreq, req)) {
    4899           0 :                 return tevent_req_post(req, ev);
    4900             :         }
    4901           1 :         tevent_req_set_callback(subreq, oplock5_opened, req);
    4902             : 
    4903           1 :         subreq = cli_echo_send(
    4904             :                 state,
    4905             :                 ev,
    4906             :                 cli,
    4907             :                 1,
    4908           1 :                 (DATA_BLOB) { .data = &data, .length = sizeof(data) });
    4909           1 :         if (tevent_req_nomem(subreq, req)) {
    4910           0 :                 return tevent_req_post(req, ev);
    4911             :         }
    4912           1 :         tevent_req_set_callback(subreq, oplock5_pong, req);
    4913             : 
    4914           1 :         subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(20, 0));
    4915           1 :         if (tevent_req_nomem(subreq, req)) {
    4916           0 :                 return tevent_req_post(req, ev);
    4917             :         }
    4918           1 :         tevent_req_set_callback(subreq, oplock5_timedout, req);
    4919             : 
    4920           1 :         return req;
    4921             : }
    4922             : 
    4923           1 : static void oplock5_opened(struct tevent_req *subreq)
    4924             : {
    4925           1 :         struct tevent_req *req = tevent_req_callback_data(
    4926             :                 subreq, struct tevent_req);
    4927             :         NTSTATUS status;
    4928             :         uint16_t fnum;
    4929             : 
    4930           1 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
    4931           1 :         TALLOC_FREE(subreq);
    4932           1 :         if (tevent_req_nterror(req, status)) {
    4933           0 :                 return;
    4934             :         }
    4935           1 :         tevent_req_done(req);
    4936             : }
    4937             : 
    4938           1 : static void oplock5_pong(struct tevent_req *subreq)
    4939             : {
    4940           1 :         struct tevent_req *req = tevent_req_callback_data(
    4941             :                 subreq, struct tevent_req);
    4942           1 :         struct oplock5_state *state = tevent_req_data(
    4943             :                 req, struct oplock5_state);
    4944             :         NTSTATUS status;
    4945             : 
    4946           1 :         status = cli_echo_recv(subreq);
    4947           1 :         TALLOC_FREE(subreq);
    4948           1 :         if (tevent_req_nterror(req, status)) {
    4949           0 :                 return;
    4950             :         }
    4951             : 
    4952           1 :         close(state->pipe_down_fd);
    4953             : }
    4954             : 
    4955           0 : static void oplock5_timedout(struct tevent_req *subreq)
    4956             : {
    4957           0 :         struct tevent_req *req = tevent_req_callback_data(
    4958             :                 subreq, struct tevent_req);
    4959             :         bool ok;
    4960             : 
    4961           0 :         ok = tevent_wakeup_recv(subreq);
    4962           0 :         TALLOC_FREE(subreq);
    4963           0 :         if (!ok) {
    4964           0 :                 tevent_req_oom(req);
    4965           0 :                 return;
    4966             :         }
    4967           0 :         tevent_req_nterror(req, NT_STATUS_TIMEOUT);
    4968             : }
    4969             : 
    4970           1 : static NTSTATUS oplock5_recv(struct tevent_req *req)
    4971             : {
    4972           1 :         return tevent_req_simple_recv_ntstatus(req);
    4973             : }
    4974             : 
    4975           1 : static bool run_oplock5(int dummy)
    4976             : {
    4977           1 :         struct tevent_context *ev = NULL;
    4978           1 :         struct tevent_req *req = NULL;
    4979           1 :         struct cli_state *cli = NULL;
    4980           1 :         const char *fname = "oplock5.txt";
    4981             :         int pipe_down[2], pipe_up[2];
    4982             :         pid_t child_pid;
    4983           1 :         uint8_t c = '\0';
    4984             :         NTSTATUS status;
    4985             :         int ret;
    4986             :         bool ok;
    4987             : 
    4988           1 :         printf("starting oplock5\n");
    4989             : 
    4990           1 :         if (local_path == NULL) {
    4991           0 :                 d_fprintf(stderr, "oplock5 must be given a local path via "
    4992             :                           "-l <localpath>\n");
    4993           0 :                 return false;
    4994             :         }
    4995             : 
    4996           1 :         ret = pipe(pipe_down);
    4997           1 :         if (ret == -1) {
    4998           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    4999           0 :                 return false;
    5000             :         }
    5001           1 :         ret = pipe(pipe_up);
    5002           1 :         if (ret == -1) {
    5003           0 :                 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
    5004           0 :                 return false;
    5005             :         }
    5006             : 
    5007           1 :         child_pid = fork();
    5008           2 :         if (child_pid == -1) {
    5009           0 :                 d_fprintf(stderr, "fork() failed: %s\n", strerror(errno));
    5010           0 :                 return false;
    5011             :         }
    5012             : 
    5013           2 :         if (child_pid == 0) {
    5014           1 :                 char *local_file = NULL;
    5015             :                 int fd;
    5016             : 
    5017           1 :                 close(pipe_down[1]);
    5018           1 :                 close(pipe_up[0]);
    5019             : 
    5020           2 :                 local_file = talloc_asprintf(
    5021           1 :                         talloc_tos(), "%s/%s", local_path, fname);
    5022           1 :                 if (local_file == 0) {
    5023           0 :                         c = 1;
    5024           0 :                         goto do_write;
    5025             :                 }
    5026           1 :                 fd = open(local_file, O_RDWR|O_CREAT, 0644);
    5027           1 :                 if (fd == -1) {
    5028           0 :                         d_fprintf(stderr,
    5029             :                                   "open(%s) in child failed: %s\n",
    5030             :                                   local_file,
    5031           0 :                                   strerror(errno));
    5032           0 :                         c = 2;
    5033           0 :                         goto do_write;
    5034             :                 }
    5035             : 
    5036           1 :                 signal(SIGIO, SIG_IGN);
    5037             : 
    5038           1 :                 ret = fcntl(fd, F_SETLEASE, F_WRLCK);
    5039           1 :                 if (ret == -1) {
    5040           0 :                         d_fprintf(stderr,
    5041             :                                   "SETLEASE in child failed: %s\n",
    5042           0 :                                   strerror(errno));
    5043           0 :                         c = 3;
    5044           0 :                         goto do_write;
    5045             :                 }
    5046             : 
    5047           2 :         do_write:
    5048           1 :                 ret = sys_write(pipe_up[1], &c, sizeof(c));
    5049           1 :                 if (ret == -1) {
    5050           0 :                         d_fprintf(stderr,
    5051             :                                   "sys_write failed: %s\n",
    5052           0 :                                   strerror(errno));
    5053           0 :                         exit(4);
    5054             :                 }
    5055           1 :                 ret = sys_read(pipe_down[0], &c, sizeof(c));
    5056           1 :                 if (ret == -1) {
    5057           0 :                         d_fprintf(stderr,
    5058             :                                   "sys_read failed: %s\n",
    5059           0 :                                   strerror(errno));
    5060           0 :                         exit(5);
    5061             :                 }
    5062           1 :                 exit(0);
    5063             :         }
    5064             : 
    5065           1 :         close(pipe_up[1]);
    5066           1 :         close(pipe_down[0]);
    5067             : 
    5068           1 :         ret = sys_read(pipe_up[0], &c, sizeof(c));
    5069           1 :         if (ret != 1) {
    5070           0 :                 d_fprintf(stderr,
    5071             :                           "sys_read failed: %s\n",
    5072           0 :                           strerror(errno));
    5073           0 :                 return false;
    5074             :         }
    5075           1 :         if (c != 0) {
    5076           0 :                 d_fprintf(stderr, "got error code %"PRIu8"\n", c);
    5077           0 :                 return false;
    5078             :         }
    5079             : 
    5080           1 :         ok = torture_open_connection(&cli, 0);
    5081           1 :         if (!ok) {
    5082           0 :                 d_fprintf(stderr, "torture_open_connection failed\n");
    5083           0 :                 return false;
    5084             :         }
    5085             : 
    5086           1 :         ev = samba_tevent_context_init(talloc_tos());
    5087           1 :         if (ev == NULL) {
    5088           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    5089           0 :                 return false;
    5090             :         }
    5091             : 
    5092           1 :         req = oplock5_send(ev, ev, cli, fname, pipe_down[1]);
    5093           1 :         if (req == NULL) {
    5094           0 :                 d_fprintf(stderr, "oplock5_send failed\n");
    5095           0 :                 return false;
    5096             :         }
    5097             : 
    5098           1 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    5099           1 :         if (!ok) {
    5100           0 :                 d_fprintf(stderr,
    5101             :                           "tevent_req_poll_ntstatus failed: %s\n",
    5102             :                           nt_errstr(status));
    5103           0 :                 return false;
    5104             :         }
    5105             : 
    5106           1 :         status = oplock5_recv(req);
    5107           1 :         TALLOC_FREE(req);
    5108           1 :         if (!NT_STATUS_IS_OK(status)) {
    5109           0 :                 d_fprintf(stderr,
    5110             :                           "oplock5 failed: %s\n",
    5111             :                           nt_errstr(status));
    5112           0 :                 return false;
    5113             :         }
    5114             : 
    5115           1 :         return true;
    5116             : }
    5117             : 
    5118             : #endif /* HAVE_KERNEL_OPLOCKS_LINUX */
    5119             : 
    5120             : /*
    5121             :   Test delete on close semantics.
    5122             :  */
    5123           5 : static bool run_deletetest(int dummy)
    5124             : {
    5125           5 :         struct cli_state *cli1 = NULL;
    5126           5 :         struct cli_state *cli2 = NULL;
    5127           5 :         const char *fname = "\\delete.file";
    5128           5 :         uint16_t fnum1 = (uint16_t)-1;
    5129           5 :         uint16_t fnum2 = (uint16_t)-1;
    5130           5 :         bool correct = false;
    5131             :         NTSTATUS status;
    5132             : 
    5133           5 :         printf("starting delete test\n");
    5134             : 
    5135           5 :         if (!torture_open_connection(&cli1, 0)) {
    5136           0 :                 return False;
    5137             :         }
    5138             : 
    5139           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5140             : 
    5141             :         /* Test 1 - this should delete the file on close. */
    5142             : 
    5143           5 :         cli_setatr(cli1, fname, 0, 0);
    5144           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5145             : 
    5146           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    5147             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5148             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5149           5 :         if (!NT_STATUS_IS_OK(status)) {
    5150           0 :                 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
    5151           0 :                 goto fail;
    5152             :         }
    5153             : 
    5154           5 :         status = cli_close(cli1, fnum1);
    5155           5 :         if (!NT_STATUS_IS_OK(status)) {
    5156           0 :                 printf("[1] close failed (%s)\n", nt_errstr(status));
    5157           0 :                 goto fail;
    5158             :         }
    5159             : 
    5160           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
    5161           5 :         if (NT_STATUS_IS_OK(status)) {
    5162           0 :                 printf("[1] open of %s succeeded (should fail)\n", fname);
    5163           0 :                 goto fail;
    5164             :         }
    5165             : 
    5166           5 :         printf("first delete on close test succeeded.\n");
    5167             : 
    5168             :         /* Test 2 - this should delete the file on close. */
    5169             : 
    5170           5 :         cli_setatr(cli1, fname, 0, 0);
    5171           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5172             : 
    5173           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5174             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5175             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5176           5 :         if (!NT_STATUS_IS_OK(status)) {
    5177           0 :                 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
    5178           0 :                 goto fail;
    5179             :         }
    5180             : 
    5181           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5182           5 :         if (!NT_STATUS_IS_OK(status)) {
    5183           0 :                 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5184           0 :                 goto fail;
    5185             :         }
    5186             : 
    5187           5 :         status = cli_close(cli1, fnum1);
    5188           5 :         if (!NT_STATUS_IS_OK(status)) {
    5189           0 :                 printf("[2] close failed (%s)\n", nt_errstr(status));
    5190           0 :                 goto fail;
    5191             :         }
    5192             : 
    5193           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5194           5 :         if (NT_STATUS_IS_OK(status)) {
    5195           0 :                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
    5196           0 :                 status = cli_close(cli1, fnum1);
    5197           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5198           0 :                         printf("[2] close failed (%s)\n", nt_errstr(status));
    5199             :                 }
    5200           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5201           0 :                 goto fail;
    5202             :         }
    5203             : 
    5204           5 :         printf("second delete on close test succeeded.\n");
    5205             : 
    5206             :         /* Test 3 - ... */
    5207           5 :         cli_setatr(cli1, fname, 0, 0);
    5208           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5209             : 
    5210           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
    5211             :                               FILE_ATTRIBUTE_NORMAL,
    5212             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5213             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5214           5 :         if (!NT_STATUS_IS_OK(status)) {
    5215           0 :                 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5216           0 :                 goto fail;
    5217             :         }
    5218             : 
    5219             :         /* This should fail with a sharing violation - open for delete is only compatible
    5220             :            with SHARE_DELETE. */
    5221             : 
    5222           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5223             :                               FILE_ATTRIBUTE_NORMAL,
    5224             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5225             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5226           5 :         if (NT_STATUS_IS_OK(status)) {
    5227           0 :                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
    5228           0 :                 goto fail;
    5229             :         }
    5230             : 
    5231             :         /* This should succeed. */
    5232           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5233             :                              FILE_ATTRIBUTE_NORMAL,
    5234             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5235             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5236           5 :         if (!NT_STATUS_IS_OK(status)) {
    5237           0 :                 printf("[3] open  - 3 of %s failed (%s)\n", fname, nt_errstr(status));
    5238           0 :                 goto fail;
    5239             :         }
    5240             : 
    5241           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5242           5 :         if (!NT_STATUS_IS_OK(status)) {
    5243           0 :                 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5244           0 :                 goto fail;
    5245             :         }
    5246             : 
    5247           5 :         status = cli_close(cli1, fnum1);
    5248           5 :         if (!NT_STATUS_IS_OK(status)) {
    5249           0 :                 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
    5250           0 :                 goto fail;
    5251             :         }
    5252             : 
    5253           5 :         status = cli_close(cli1, fnum2);
    5254           5 :         if (!NT_STATUS_IS_OK(status)) {
    5255           0 :                 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
    5256           0 :                 goto fail;
    5257             :         }
    5258             : 
    5259             :         /* This should fail - file should no longer be there. */
    5260             : 
    5261           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5262           5 :         if (NT_STATUS_IS_OK(status)) {
    5263           0 :                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
    5264           0 :                 status = cli_close(cli1, fnum1);
    5265           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5266           0 :                         printf("[3] close failed (%s)\n", nt_errstr(status));
    5267             :                 }
    5268           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5269           0 :                 goto fail;
    5270             :         }
    5271             : 
    5272           5 :         printf("third delete on close test succeeded.\n");
    5273             : 
    5274             :         /* Test 4 ... */
    5275           5 :         cli_setatr(cli1, fname, 0, 0);
    5276           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5277             : 
    5278           5 :         status = cli_ntcreate(cli1, fname, 0,
    5279             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5280             :                               FILE_ATTRIBUTE_NORMAL,
    5281             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5282             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5283           5 :         if (!NT_STATUS_IS_OK(status)) {
    5284           0 :                 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
    5285           0 :                 goto fail;
    5286             :         }
    5287             : 
    5288             :         /* This should succeed. */
    5289           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5290             :                              FILE_ATTRIBUTE_NORMAL,
    5291             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5292             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5293           5 :         if (!NT_STATUS_IS_OK(status)) {
    5294           0 :                 printf("[4] open  - 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5295           0 :                 goto fail;
    5296             :         }
    5297             : 
    5298           5 :         status = cli_close(cli1, fnum2);
    5299           5 :         if (!NT_STATUS_IS_OK(status)) {
    5300           0 :                 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
    5301           0 :                 goto fail;
    5302             :         }
    5303             : 
    5304           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5305           5 :         if (!NT_STATUS_IS_OK(status)) {
    5306           0 :                 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5307           0 :                 goto fail;
    5308             :         }
    5309             : 
    5310             :         /* This should fail - no more opens once delete on close set. */
    5311           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5312             :                               FILE_ATTRIBUTE_NORMAL,
    5313             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5314             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5315           5 :         if (NT_STATUS_IS_OK(status)) {
    5316           0 :                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
    5317           0 :                 goto fail;
    5318             :         }
    5319             : 
    5320           5 :         status = cli_close(cli1, fnum1);
    5321           5 :         if (!NT_STATUS_IS_OK(status)) {
    5322           0 :                 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
    5323           0 :                 goto fail;
    5324             :         }
    5325             : 
    5326           5 :         printf("fourth delete on close test succeeded.\n");
    5327             : 
    5328             :         /* Test 5 ... */
    5329           5 :         cli_setatr(cli1, fname, 0, 0);
    5330           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5331             : 
    5332           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
    5333           5 :         if (!NT_STATUS_IS_OK(status)) {
    5334           0 :                 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
    5335           0 :                 goto fail;
    5336             :         }
    5337             : 
    5338             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5339             : 
    5340           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5341           5 :         if (NT_STATUS_IS_OK(status)) {
    5342           0 :                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
    5343           0 :                 goto fail;
    5344             :         }
    5345             : 
    5346           5 :         status = cli_close(cli1, fnum1);
    5347           5 :         if (!NT_STATUS_IS_OK(status)) {
    5348           0 :                 printf("[5] close failed (%s)\n", nt_errstr(status));
    5349           0 :                 goto fail;
    5350             :         }
    5351             : 
    5352           5 :         printf("fifth delete on close test succeeded.\n");
    5353             : 
    5354             :         /* Test 6 ... */
    5355           5 :         cli_setatr(cli1, fname, 0, 0);
    5356           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5357             : 
    5358           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5359             :                              FILE_ATTRIBUTE_NORMAL,
    5360             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5361             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5362           5 :         if (!NT_STATUS_IS_OK(status)) {
    5363           0 :                 printf("[6] open of %s failed (%s)\n", fname,
    5364             :                        nt_errstr(status));
    5365           0 :                 goto fail;
    5366             :         }
    5367             : 
    5368             :         /* This should fail - only allowed on NT opens with DELETE access. */
    5369             : 
    5370           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5371           5 :         if (NT_STATUS_IS_OK(status)) {
    5372           0 :                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
    5373           0 :                 goto fail;
    5374             :         }
    5375             : 
    5376           5 :         status = cli_close(cli1, fnum1);
    5377           5 :         if (!NT_STATUS_IS_OK(status)) {
    5378           0 :                 printf("[6] close failed (%s)\n", nt_errstr(status));
    5379           0 :                 goto fail;
    5380             :         }
    5381             : 
    5382           5 :         printf("sixth delete on close test succeeded.\n");
    5383             : 
    5384             :         /* Test 7 ... */
    5385           5 :         cli_setatr(cli1, fname, 0, 0);
    5386           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5387             : 
    5388           5 :         status = cli_ntcreate(cli1, fname, 0,
    5389             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5390             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5391             :                               0, 0, &fnum1, NULL);
    5392           5 :         if (!NT_STATUS_IS_OK(status)) {
    5393           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5394           0 :                 goto fail;
    5395             :         }
    5396             : 
    5397           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5398           5 :         if (!NT_STATUS_IS_OK(status)) {
    5399           0 :                 printf("[7] setting delete_on_close on file failed !\n");
    5400           0 :                 goto fail;
    5401             :         }
    5402             : 
    5403           5 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5404           5 :         if (!NT_STATUS_IS_OK(status)) {
    5405           0 :                 printf("[7] unsetting delete_on_close on file failed !\n");
    5406           0 :                 goto fail;
    5407             :         }
    5408             : 
    5409           5 :         status = cli_close(cli1, fnum1);
    5410           5 :         if (!NT_STATUS_IS_OK(status)) {
    5411           0 :                 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
    5412           0 :                 goto fail;
    5413             :         }
    5414             : 
    5415             :         /* This next open should succeed - we reset the flag. */
    5416           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5417           5 :         if (!NT_STATUS_IS_OK(status)) {
    5418           0 :                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
    5419           0 :                 goto fail;
    5420             :         }
    5421             : 
    5422           5 :         status = cli_close(cli1, fnum1);
    5423           5 :         if (!NT_STATUS_IS_OK(status)) {
    5424           0 :                 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
    5425           0 :                 goto fail;
    5426             :         }
    5427             : 
    5428           5 :         printf("seventh delete on close test succeeded.\n");
    5429             : 
    5430             :         /* Test 8 ... */
    5431           5 :         cli_setatr(cli1, fname, 0, 0);
    5432           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5433             : 
    5434           5 :         if (!torture_open_connection(&cli2, 1)) {
    5435           0 :                 printf("[8] failed to open second connection.\n");
    5436           0 :                 goto fail;
    5437             :         }
    5438             : 
    5439           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5440             : 
    5441           5 :         status = cli_ntcreate(cli1, fname, 0,
    5442             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5443             :                              FILE_ATTRIBUTE_NORMAL,
    5444             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5445             :                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5446           5 :         if (!NT_STATUS_IS_OK(status)) {
    5447           0 :                 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5448           0 :                 goto fail;
    5449             :         }
    5450             : 
    5451           5 :         status = cli_ntcreate(cli2, fname, 0,
    5452             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5453             :                              FILE_ATTRIBUTE_NORMAL,
    5454             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5455             :                              FILE_OPEN, 0, 0, &fnum2, NULL);
    5456           5 :         if (!NT_STATUS_IS_OK(status)) {
    5457           0 :                 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    5458           0 :                 goto fail;
    5459             :         }
    5460             : 
    5461           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5462           5 :         if (!NT_STATUS_IS_OK(status)) {
    5463           0 :                 printf("[8] setting delete_on_close on file failed !\n");
    5464           0 :                 goto fail;
    5465             :         }
    5466             : 
    5467           5 :         status = cli_close(cli1, fnum1);
    5468           5 :         if (!NT_STATUS_IS_OK(status)) {
    5469           0 :                 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
    5470           0 :                 goto fail;
    5471             :         }
    5472             : 
    5473           5 :         status = cli_close(cli2, fnum2);
    5474           5 :         if (!NT_STATUS_IS_OK(status)) {
    5475           0 :                 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
    5476           0 :                 goto fail;
    5477             :         }
    5478             : 
    5479             :         /* This should fail.. */
    5480           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5481           5 :         if (NT_STATUS_IS_OK(status)) {
    5482           0 :                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
    5483           0 :                 goto fail;
    5484             :         }
    5485             : 
    5486           5 :         printf("eighth delete on close test succeeded.\n");
    5487             : 
    5488             :         /* Test 9 ... */
    5489             : 
    5490             :         /* This should fail - we need to set DELETE_ACCESS. */
    5491           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5492             :                               FILE_ATTRIBUTE_NORMAL,
    5493             :                               FILE_SHARE_NONE,
    5494             :                               FILE_OVERWRITE_IF,
    5495             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5496           5 :         if (NT_STATUS_IS_OK(status)) {
    5497           0 :                 printf("[9] open of %s succeeded should have failed!\n", fname);
    5498           0 :                 goto fail;
    5499             :         }
    5500             : 
    5501           5 :         printf("ninth delete on close test succeeded.\n");
    5502             : 
    5503             :         /* Test 10 ... */
    5504             : 
    5505           5 :         status = cli_ntcreate(cli1, fname, 0,
    5506             :                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5507             :                              FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    5508             :                              FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
    5509             :                              0, &fnum1, NULL);
    5510           5 :         if (!NT_STATUS_IS_OK(status)) {
    5511           0 :                 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
    5512           0 :                 goto fail;
    5513             :         }
    5514             : 
    5515             :         /* This should delete the file. */
    5516           5 :         status = cli_close(cli1, fnum1);
    5517           5 :         if (!NT_STATUS_IS_OK(status)) {
    5518           0 :                 printf("[10] close failed (%s)\n", nt_errstr(status));
    5519           0 :                 goto fail;
    5520             :         }
    5521             : 
    5522             :         /* This should fail.. */
    5523           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
    5524           5 :         if (NT_STATUS_IS_OK(status)) {
    5525           0 :                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
    5526           0 :                 goto fail;
    5527             :         }
    5528             : 
    5529           5 :         printf("tenth delete on close test succeeded.\n");
    5530             : 
    5531             :         /* Test 11 ... */
    5532             : 
    5533           5 :         cli_setatr(cli1, fname, 0, 0);
    5534           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5535             : 
    5536             :         /* Can we open a read-only file with delete access? */
    5537             : 
    5538             :         /* Create a readonly file. */
    5539           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
    5540             :                               FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
    5541             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    5542           5 :         if (!NT_STATUS_IS_OK(status)) {
    5543           0 :                 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
    5544           0 :                 goto fail;
    5545             :         }
    5546             : 
    5547           5 :         status = cli_close(cli1, fnum1);
    5548           5 :         if (!NT_STATUS_IS_OK(status)) {
    5549           0 :                 printf("[11] close failed (%s)\n", nt_errstr(status));
    5550           0 :                 goto fail;
    5551             :         }
    5552             : 
    5553             :         /* Now try open for delete access. */
    5554           5 :         status = cli_ntcreate(cli1, fname, 0,
    5555             :                              FILE_READ_ATTRIBUTES|DELETE_ACCESS,
    5556             :                              0,
    5557             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5558             :                              FILE_OPEN, 0, 0, &fnum1, NULL);
    5559           5 :         if (!NT_STATUS_IS_OK(status)) {
    5560           0 :                 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
    5561           0 :                 goto fail;
    5562             :         }
    5563             : 
    5564           5 :         cli_close(cli1, fnum1);
    5565             : 
    5566           5 :         printf("eleventh delete on close test succeeded.\n");
    5567             : 
    5568             :         /*
    5569             :          * Test 12
    5570             :          * like test 4 but with initial delete on close
    5571             :          */
    5572             : 
    5573           5 :         cli_setatr(cli1, fname, 0, 0);
    5574           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5575             : 
    5576           5 :         status = cli_ntcreate(cli1, fname, 0,
    5577             :                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
    5578             :                               FILE_ATTRIBUTE_NORMAL,
    5579             :                               FILE_SHARE_READ|FILE_SHARE_WRITE,
    5580             :                               FILE_OVERWRITE_IF,
    5581             :                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
    5582           5 :         if (!NT_STATUS_IS_OK(status)) {
    5583           0 :                 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    5584           0 :                 goto fail;
    5585             :         }
    5586             : 
    5587           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5588             :                               FILE_ATTRIBUTE_NORMAL,
    5589             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5590             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5591           5 :         if (!NT_STATUS_IS_OK(status)) {
    5592           0 :                 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
    5593           0 :                 goto fail;
    5594             :         }
    5595             : 
    5596           5 :         status = cli_close(cli1, fnum2);
    5597           5 :         if (!NT_STATUS_IS_OK(status)) {
    5598           0 :                 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
    5599           0 :                 goto fail;
    5600             :         }
    5601             : 
    5602           5 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5603           5 :         if (!NT_STATUS_IS_OK(status)) {
    5604           0 :                 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
    5605           0 :                 goto fail;
    5606             :         }
    5607             : 
    5608             :         /* This should fail - no more opens once delete on close set. */
    5609           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5610             :                               FILE_ATTRIBUTE_NORMAL,
    5611             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5612             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5613           5 :         if (NT_STATUS_IS_OK(status)) {
    5614           0 :                 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
    5615           0 :                 goto fail;
    5616             :         }
    5617             : 
    5618           5 :         status = cli_nt_delete_on_close(cli1, fnum1, false);
    5619           5 :         if (!NT_STATUS_IS_OK(status)) {
    5620           0 :                 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
    5621           0 :                 goto fail;
    5622             :         }
    5623             : 
    5624           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5625             :                               FILE_ATTRIBUTE_NORMAL,
    5626             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5627             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5628           5 :         if (!NT_STATUS_IS_OK(status)) {
    5629           0 :                 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
    5630           0 :                 goto fail;
    5631             :         }
    5632             : 
    5633           5 :         status = cli_close(cli1, fnum2);
    5634           5 :         if (!NT_STATUS_IS_OK(status)) {
    5635           0 :                 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
    5636           0 :                 goto fail;
    5637             :         }
    5638             : 
    5639           5 :         status = cli_close(cli1, fnum1);
    5640           5 :         if (!NT_STATUS_IS_OK(status)) {
    5641           0 :                 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
    5642           0 :                 goto fail;
    5643             :         }
    5644             : 
    5645             :         /*
    5646             :          * setting delete on close on the handle does
    5647             :          * not unset the initial delete on close...
    5648             :          */
    5649           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    5650             :                               FILE_ATTRIBUTE_NORMAL,
    5651             :                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5652             :                               FILE_OPEN, 0, 0, &fnum2, NULL);
    5653           5 :         if (NT_STATUS_IS_OK(status)) {
    5654           0 :                 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
    5655           0 :                 goto fail;
    5656           5 :         } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    5657           0 :                 printf("ntcreate returned %s, expected "
    5658             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
    5659             :                        nt_errstr(status));
    5660           0 :                 goto fail;
    5661             :         }
    5662             : 
    5663           5 :         printf("twelfth delete on close test succeeded.\n");
    5664             : 
    5665             : 
    5666           5 :         printf("finished delete test\n");
    5667             : 
    5668           5 :         correct = true;
    5669             : 
    5670           5 :   fail:
    5671             :         /* FIXME: This will crash if we aborted before cli2 got
    5672             :          * intialized, because these functions don't handle
    5673             :          * uninitialized connections. */
    5674             : 
    5675           5 :         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
    5676           5 :         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
    5677           5 :         cli_setatr(cli1, fname, 0, 0);
    5678           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5679             : 
    5680           5 :         if (cli1 && !torture_close_connection(cli1)) {
    5681           0 :                 correct = False;
    5682             :         }
    5683           5 :         if (cli2 && !torture_close_connection(cli2)) {
    5684           0 :                 correct = False;
    5685             :         }
    5686           5 :         return correct;
    5687             : }
    5688             : 
    5689             : struct delete_stream_state {
    5690             :         bool closed;
    5691             : };
    5692             : 
    5693             : static void delete_stream_unlinked(struct tevent_req *subreq);
    5694             : static void delete_stream_closed(struct tevent_req *subreq);
    5695             : 
    5696           5 : static struct tevent_req *delete_stream_send(
    5697             :         TALLOC_CTX *mem_ctx,
    5698             :         struct tevent_context *ev,
    5699             :         struct cli_state *cli,
    5700             :         const char *base_fname,
    5701             :         uint16_t stream_fnum)
    5702             : {
    5703           5 :         struct tevent_req *req = NULL, *subreq = NULL;
    5704           5 :         struct delete_stream_state *state = NULL;
    5705             : 
    5706           5 :         req = tevent_req_create(
    5707             :                 mem_ctx, &state, struct delete_stream_state);
    5708           5 :         if (req == NULL) {
    5709           0 :                 return NULL;
    5710             :         }
    5711             : 
    5712           5 :         subreq = cli_unlink_send(
    5713             :                 state,
    5714             :                 ev,
    5715             :                 cli,
    5716             :                 base_fname,
    5717             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5718           5 :         if (tevent_req_nomem(subreq, req)) {
    5719           0 :                 return tevent_req_post(req, ev);
    5720             :         }
    5721           5 :         tevent_req_set_callback(subreq, delete_stream_unlinked, req);
    5722             : 
    5723           5 :         subreq = cli_close_send(state, ev, cli, stream_fnum);
    5724           5 :         if (tevent_req_nomem(subreq, req)) {
    5725           0 :                 return tevent_req_post(req, ev);
    5726             :         }
    5727           5 :         tevent_req_set_callback(subreq, delete_stream_closed, req);
    5728             : 
    5729           5 :         return req;
    5730             : }
    5731             : 
    5732           5 : static void delete_stream_unlinked(struct tevent_req *subreq)
    5733             : {
    5734           5 :         struct tevent_req *req = tevent_req_callback_data(
    5735             :                 subreq, struct tevent_req);
    5736           5 :         struct delete_stream_state *state = tevent_req_data(
    5737             :                 req, struct delete_stream_state);
    5738             :         NTSTATUS status;
    5739             : 
    5740           5 :         status = cli_unlink_recv(subreq);
    5741           5 :         TALLOC_FREE(subreq);
    5742           5 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    5743           0 :                 printf("cli_unlink returned %s\n",
    5744             :                        nt_errstr(status));
    5745           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    5746           0 :                 return;
    5747             :         }
    5748           5 :         if (!state->closed) {
    5749             :                 /* close reply should have come in first */
    5750           0 :                 printf("Not closed\n");
    5751           0 :                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    5752           0 :                 return;
    5753             :         }
    5754           5 :         tevent_req_done(req);
    5755             : }
    5756             : 
    5757           5 : static void delete_stream_closed(struct tevent_req *subreq)
    5758             : {
    5759           5 :         struct tevent_req *req = tevent_req_callback_data(
    5760             :                 subreq, struct tevent_req);
    5761           5 :         struct delete_stream_state *state = tevent_req_data(
    5762             :                 req, struct delete_stream_state);
    5763             :         NTSTATUS status;
    5764             : 
    5765           5 :         status = cli_close_recv(subreq);
    5766           5 :         TALLOC_FREE(subreq);
    5767           5 :         if (tevent_req_nterror(req, status)) {
    5768           0 :                 return;
    5769             :         }
    5770             :         /* also waiting for the unlink to come back */
    5771           5 :         state->closed = true;
    5772             : }
    5773             : 
    5774           5 : static NTSTATUS delete_stream_recv(struct tevent_req *req)
    5775             : {
    5776           5 :         return tevent_req_simple_recv_ntstatus(req);
    5777             : }
    5778             : 
    5779           5 : static bool run_delete_stream(int dummy)
    5780             : {
    5781           5 :         struct tevent_context *ev = NULL;
    5782           5 :         struct tevent_req *req = NULL;
    5783           5 :         struct cli_state *cli = NULL;
    5784           5 :         const char fname[] = "delete_stream";
    5785           5 :         const char fname_stream[] = "delete_stream:Zone.Identifier:$DATA";
    5786             :         uint16_t fnum1, fnum2;
    5787             :         NTSTATUS status;
    5788             :         bool ok;
    5789             : 
    5790           5 :         printf("Starting stream delete test\n");
    5791             : 
    5792           5 :         ok = torture_open_connection(&cli, 0);
    5793           5 :         if (!ok) {
    5794           0 :                 return false;
    5795             :         }
    5796             : 
    5797           5 :         cli_setatr(cli, fname, 0, 0);
    5798           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5799             : 
    5800             :         /* Create the file. */
    5801           5 :         status = cli_ntcreate(
    5802             :                 cli,
    5803             :                 fname,
    5804             :                 0,
    5805             :                 READ_CONTROL_ACCESS,
    5806             :                 0,
    5807             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    5808             :                 FILE_CREATE,
    5809             :                 0x0,
    5810             :                 0x0,
    5811             :                 &fnum1,
    5812             :                 NULL);
    5813           5 :         if (!NT_STATUS_IS_OK(status)) {
    5814           0 :                 d_fprintf(stderr,
    5815             :                           "cli_ntcreate of %s failed (%s)\n",
    5816             :                           fname,
    5817             :                           nt_errstr(status));
    5818           0 :                 return false;
    5819             :         }
    5820           5 :         status = cli_close(cli, fnum1);
    5821           5 :         if (!NT_STATUS_IS_OK(status)) {
    5822           0 :                 d_fprintf(stderr,
    5823             :                           "cli_close of %s failed (%s)\n",
    5824             :                           fname,
    5825             :                           nt_errstr(status));
    5826           0 :                 return false;
    5827             :         }
    5828             : 
    5829             :         /* Now create the stream. */
    5830           5 :         status = cli_ntcreate(
    5831             :                 cli,
    5832             :                 fname_stream,
    5833             :                 0,
    5834             :                 FILE_WRITE_DATA,
    5835             :                 0,
    5836             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    5837             :                 FILE_CREATE,
    5838             :                 0x0,
    5839             :                 0x0,
    5840             :                 &fnum1,
    5841             :                 NULL);
    5842             : 
    5843           5 :         if (!NT_STATUS_IS_OK(status)) {
    5844           0 :                 d_fprintf(stderr,
    5845             :                           "cli_ntcreate of %s failed (%s)\n",
    5846             :                           fname_stream,
    5847             :                           nt_errstr(status));
    5848           0 :                 return false;
    5849             :         }
    5850             : 
    5851             :         /* open it a second time */
    5852             : 
    5853           5 :         status = cli_ntcreate(
    5854             :                 cli,
    5855             :                 fname_stream,
    5856             :                 0,
    5857             :                 FILE_WRITE_DATA,
    5858             :                 0,
    5859             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    5860             :                 FILE_OPEN,
    5861             :                 0x0,
    5862             :                 0x0,
    5863             :                 &fnum2,
    5864             :                 NULL);
    5865             : 
    5866           5 :         if (!NT_STATUS_IS_OK(status)) {
    5867           0 :                 d_fprintf(stderr,
    5868             :                           "2nd cli_ntcreate of %s failed (%s)\n",
    5869             :                           fname_stream,
    5870             :                           nt_errstr(status));
    5871           0 :                 return false;
    5872             :         }
    5873             : 
    5874           5 :         ev = samba_tevent_context_init(talloc_tos());
    5875           5 :         if (ev == NULL) {
    5876           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
    5877           0 :                 return false;
    5878             :         }
    5879             : 
    5880           5 :         req = delete_stream_send(ev, ev, cli, fname, fnum1);
    5881           5 :         if (req == NULL) {
    5882           0 :                 d_fprintf(stderr, "delete_stream_send failed\n");
    5883           0 :                 return false;
    5884             :         }
    5885             : 
    5886           5 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    5887           5 :         if (!ok) {
    5888           0 :                 d_fprintf(stderr,
    5889             :                           "tevent_req_poll_ntstatus failed: %s\n",
    5890             :                           nt_errstr(status));
    5891           0 :                 return false;
    5892             :         }
    5893             : 
    5894           5 :         status = delete_stream_recv(req);
    5895           5 :         TALLOC_FREE(req);
    5896           5 :         if (!NT_STATUS_IS_OK(status)) {
    5897           0 :                 d_fprintf(stderr,
    5898             :                           "delete_stream failed: %s\n",
    5899             :                           nt_errstr(status));
    5900           0 :                 return false;
    5901             :         }
    5902             : 
    5903           5 :         status = cli_close(cli, fnum2);
    5904           5 :         if (!NT_STATUS_IS_OK(status)) {
    5905           0 :                 d_fprintf(stderr,
    5906             :                           "close failed: %s\n",
    5907             :                           nt_errstr(status));
    5908           0 :                 return false;
    5909             :         }
    5910             : 
    5911           5 :         status = cli_unlink(
    5912             :                 cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    5913           5 :         if (!NT_STATUS_IS_OK(status)) {
    5914           0 :                 d_fprintf(stderr,
    5915             :                           "unlink failed: %s\n",
    5916             :                           nt_errstr(status));
    5917           0 :                 return false;
    5918             :         }
    5919             : 
    5920           5 :         return true;
    5921             : }
    5922             : 
    5923             : /*
    5924             :   Exercise delete on close semantics - use on the PRINT1 share in torture
    5925             :   testing.
    5926             :  */
    5927           2 : static bool run_delete_print_test(int dummy)
    5928             : {
    5929           2 :         struct cli_state *cli1 = NULL;
    5930           2 :         const char *fname = "print_delete.file";
    5931           2 :         uint16_t fnum1 = (uint16_t)-1;
    5932           2 :         bool correct = false;
    5933           2 :         const char *buf = "print file data\n";
    5934             :         NTSTATUS status;
    5935             : 
    5936           2 :         printf("starting print delete test\n");
    5937             : 
    5938           2 :         if (!torture_open_connection(&cli1, 0)) {
    5939           0 :                 return false;
    5940             :         }
    5941             : 
    5942           2 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    5943             : 
    5944           2 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
    5945             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
    5946             :                               0, 0, &fnum1, NULL);
    5947           2 :         if (!NT_STATUS_IS_OK(status)) {
    5948           0 :                 printf("open of %s failed (%s)\n",
    5949             :                         fname,
    5950             :                         nt_errstr(status));
    5951           0 :                 goto fail;
    5952             :         }
    5953             : 
    5954           2 :         status = cli_writeall(cli1,
    5955             :                         fnum1,
    5956             :                         0,
    5957             :                         (const uint8_t *)buf,
    5958             :                         0, /* offset */
    5959             :                         strlen(buf), /* size */
    5960             :                         NULL);
    5961           2 :         if (!NT_STATUS_IS_OK(status)) {
    5962           0 :                 printf("writing print file data failed (%s)\n",
    5963             :                         nt_errstr(status));
    5964           0 :                 goto fail;
    5965             :         }
    5966             : 
    5967           2 :         status = cli_nt_delete_on_close(cli1, fnum1, true);
    5968           2 :         if (!NT_STATUS_IS_OK(status)) {
    5969           0 :                 printf("setting delete_on_close failed (%s)\n",
    5970             :                         nt_errstr(status));
    5971           0 :                 goto fail;
    5972             :         }
    5973             : 
    5974           2 :         status = cli_close(cli1, fnum1);
    5975           2 :         if (!NT_STATUS_IS_OK(status)) {
    5976           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    5977           0 :                 goto fail;
    5978             :         }
    5979             : 
    5980           2 :         printf("finished print delete test\n");
    5981             : 
    5982           2 :         correct = true;
    5983             : 
    5984           2 :   fail:
    5985             : 
    5986           2 :         if (fnum1 != (uint16_t)-1) {
    5987           2 :                 cli_close(cli1, fnum1);
    5988             :         }
    5989             : 
    5990           2 :         if (cli1 && !torture_close_connection(cli1)) {
    5991           0 :                 correct = false;
    5992             :         }
    5993           2 :         return correct;
    5994             : }
    5995             : 
    5996             : /*
    5997             :   Test wildcard delete.
    5998             :  */
    5999           5 : static bool run_wild_deletetest(int dummy)
    6000             : {
    6001           5 :         struct cli_state *cli = NULL;
    6002           5 :         const char *dname = "\\WTEST";
    6003           5 :         const char *fname = "\\WTEST\\A";
    6004           5 :         const char *wunlink_name = "\\WTEST\\*";
    6005           5 :         uint16_t fnum1 = (uint16_t)-1;
    6006           5 :         bool correct = false;
    6007             :         NTSTATUS status;
    6008             : 
    6009           5 :         printf("starting wildcard delete test\n");
    6010             : 
    6011           5 :         if (!torture_open_connection(&cli, 0)) {
    6012           0 :                 return false;
    6013             :         }
    6014             : 
    6015           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6016             : 
    6017           5 :         cli_unlink(cli, fname, 0);
    6018           5 :         cli_rmdir(cli, dname);
    6019           5 :         status = cli_mkdir(cli, dname);
    6020           5 :         if (!NT_STATUS_IS_OK(status)) {
    6021           0 :                 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
    6022           0 :                 goto fail;
    6023             :         }
    6024           5 :         status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
    6025           5 :         if (!NT_STATUS_IS_OK(status)) {
    6026           0 :                 printf("open of %s failed %s!\n", fname, nt_errstr(status));
    6027           0 :                 goto fail;
    6028             :         }
    6029           5 :         status = cli_close(cli, fnum1);
    6030           5 :         fnum1 = -1;
    6031             : 
    6032             :         /*
    6033             :          * Note the unlink attribute-type of zero. This should
    6034             :          * map into FILE_ATTRIBUTE_NORMAL at the server even
    6035             :          * on a wildcard delete.
    6036             :          */
    6037             : 
    6038           5 :         status = cli_unlink(cli, wunlink_name, 0);
    6039           5 :         if (!NT_STATUS_IS_OK(status)) {
    6040           0 :                 printf("unlink of %s failed %s!\n",
    6041             :                         wunlink_name, nt_errstr(status));
    6042           0 :                 goto fail;
    6043             :         }
    6044             : 
    6045           5 :         printf("finished wildcard delete test\n");
    6046             : 
    6047           5 :         correct = true;
    6048             : 
    6049           5 :   fail:
    6050             : 
    6051           5 :         if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
    6052           5 :         cli_unlink(cli, fname, 0);
    6053           5 :         cli_rmdir(cli, dname);
    6054             : 
    6055           5 :         if (cli && !torture_close_connection(cli)) {
    6056           0 :                 correct = false;
    6057             :         }
    6058           5 :         return correct;
    6059             : }
    6060             : 
    6061           4 : static bool run_deletetest_ln(int dummy)
    6062             : {
    6063             :         struct cli_state *cli;
    6064           4 :         const char *fname = "\\delete1";
    6065           4 :         const char *fname_ln = "\\delete1_ln";
    6066             :         uint16_t fnum;
    6067             :         uint16_t fnum1;
    6068             :         NTSTATUS status;
    6069           4 :         bool correct = true;
    6070             :         time_t t;
    6071             : 
    6072           4 :         printf("starting deletetest-ln\n");
    6073             : 
    6074           4 :         if (!torture_open_connection(&cli, 0)) {
    6075           0 :                 return false;
    6076             :         }
    6077             : 
    6078           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6079           4 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6080             : 
    6081           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6082             : 
    6083             :         /* Create the file. */
    6084           4 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6085           4 :         if (!NT_STATUS_IS_OK(status)) {
    6086           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    6087           0 :                 return false;
    6088             :         }
    6089             : 
    6090           4 :         status = cli_close(cli, fnum);
    6091           4 :         if (!NT_STATUS_IS_OK(status)) {
    6092           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    6093           0 :                 return false;
    6094             :         }
    6095             : 
    6096             :         /* Now create a hardlink. */
    6097           4 :         status = cli_hardlink(cli, fname, fname_ln);
    6098           4 :         if (!NT_STATUS_IS_OK(status)) {
    6099           0 :                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
    6100           0 :                 return false;
    6101             :         }
    6102             : 
    6103             :         /* Open the original file. */
    6104           4 :         status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
    6105             :                         FILE_ATTRIBUTE_NORMAL,
    6106             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6107             :                         FILE_OPEN_IF, 0, 0, &fnum, NULL);
    6108           4 :         if (!NT_STATUS_IS_OK(status)) {
    6109           0 :                 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
    6110           0 :                 return false;
    6111             :         }
    6112             : 
    6113             :         /* Unlink the hard link path. */
    6114           4 :         status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
    6115             :                         FILE_ATTRIBUTE_NORMAL,
    6116             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6117             :                         FILE_OPEN_IF, 0, 0, &fnum1, NULL);
    6118           4 :         if (!NT_STATUS_IS_OK(status)) {
    6119           0 :                 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
    6120           0 :                 return false;
    6121             :         }
    6122           4 :         status = cli_nt_delete_on_close(cli, fnum1, true);
    6123           4 :         if (!NT_STATUS_IS_OK(status)) {
    6124           0 :                 d_printf("(%s) failed to set delete_on_close %s: %s\n",
    6125             :                         __location__, fname_ln, nt_errstr(status));
    6126           0 :                 return false;
    6127             :         }
    6128             : 
    6129           4 :         status = cli_close(cli, fnum1);
    6130           4 :         if (!NT_STATUS_IS_OK(status)) {
    6131           0 :                 printf("close %s failed (%s)\n",
    6132             :                         fname_ln, nt_errstr(status));
    6133           0 :                 return false;
    6134             :         }
    6135             : 
    6136           4 :         status = cli_close(cli, fnum);
    6137           4 :         if (!NT_STATUS_IS_OK(status)) {
    6138           0 :                 printf("close %s failed (%s)\n",
    6139             :                         fname, nt_errstr(status));
    6140           0 :                 return false;
    6141             :         }
    6142             : 
    6143             :         /* Ensure the original file is still there. */
    6144           4 :         status = cli_getatr(cli, fname, NULL, NULL, &t);
    6145           4 :         if (!NT_STATUS_IS_OK(status)) {
    6146           0 :                 printf("%s getatr on file %s failed (%s)\n",
    6147             :                         __location__,
    6148             :                         fname,
    6149             :                         nt_errstr(status));
    6150           0 :                 correct = False;
    6151             :         }
    6152             : 
    6153             :         /* Ensure the link path is gone. */
    6154           4 :         status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
    6155           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    6156           0 :                 printf("%s, getatr for file %s returned wrong error code %s "
    6157             :                         "- should have been deleted\n",
    6158             :                         __location__,
    6159             :                         fname_ln, nt_errstr(status));
    6160           0 :                 correct = False;
    6161             :         }
    6162             : 
    6163           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6164           4 :         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6165             : 
    6166           4 :         if (!torture_close_connection(cli)) {
    6167           0 :                 correct = false;
    6168             :         }
    6169             : 
    6170           4 :         printf("finished deletetest-ln\n");
    6171             : 
    6172           4 :         return correct;
    6173             : }
    6174             : 
    6175             : /*
    6176             :   print out server properties
    6177             :  */
    6178           5 : static bool run_properties(int dummy)
    6179             : {
    6180             :         struct cli_state *cli;
    6181           5 :         bool correct = True;
    6182             : 
    6183           5 :         printf("starting properties test\n");
    6184             : 
    6185           5 :         ZERO_STRUCT(cli);
    6186             : 
    6187           5 :         if (!torture_open_connection(&cli, 0)) {
    6188           0 :                 return False;
    6189             :         }
    6190             : 
    6191           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6192             : 
    6193           5 :         d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
    6194             : 
    6195           5 :         if (!torture_close_connection(cli)) {
    6196           0 :                 correct = False;
    6197             :         }
    6198             : 
    6199           5 :         return correct;
    6200             : }
    6201             : 
    6202             : 
    6203             : 
    6204             : /* FIRST_DESIRED_ACCESS   0xf019f */
    6205             : #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
    6206             :                                FILE_READ_EA|                           /* 0xf */ \
    6207             :                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
    6208             :                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
    6209             :                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
    6210             :                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
    6211             : /* SECOND_DESIRED_ACCESS  0xe0080 */
    6212             : #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6213             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6214             :                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
    6215             : 
    6216             : #if 0
    6217             : #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
    6218             :                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
    6219             :                                FILE_READ_DATA|\
    6220             :                                WRITE_OWNER_ACCESS                      /* */
    6221             : #endif
    6222             : 
    6223             : /*
    6224             :   Test ntcreate calls made by xcopy
    6225             :  */
    6226           5 : static bool run_xcopy(int dummy)
    6227             : {
    6228             :         static struct cli_state *cli1;
    6229           5 :         const char *fname = "\\test.txt";
    6230           5 :         bool correct = True;
    6231             :         uint16_t fnum1, fnum2;
    6232             :         NTSTATUS status;
    6233             : 
    6234           5 :         printf("starting xcopy test\n");
    6235             : 
    6236           5 :         if (!torture_open_connection(&cli1, 0)) {
    6237           0 :                 return False;
    6238             :         }
    6239             : 
    6240           5 :         status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
    6241             :                               FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
    6242             :                               FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
    6243           5 :         if (!NT_STATUS_IS_OK(status)) {
    6244           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6245           0 :                 return False;
    6246             :         }
    6247             : 
    6248           5 :         status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
    6249             :                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    6250             :                              FILE_OPEN, 0x200000, 0, &fnum2, NULL);
    6251           5 :         if (!NT_STATUS_IS_OK(status)) {
    6252           0 :                 printf("second open failed - %s\n", nt_errstr(status));
    6253           0 :                 return False;
    6254             :         }
    6255             : 
    6256           5 :         if (!torture_close_connection(cli1)) {
    6257           0 :                 correct = False;
    6258             :         }
    6259             : 
    6260           5 :         return correct;
    6261             : }
    6262             : 
    6263             : /*
    6264             :   Test rename on files open with share delete and no share delete.
    6265             :  */
    6266           5 : static bool run_rename(int dummy)
    6267             : {
    6268             :         static struct cli_state *cli1;
    6269           5 :         const char *fname = "\\test.txt";
    6270           5 :         const char *fname1 = "\\test1.txt";
    6271           5 :         bool correct = True;
    6272             :         uint16_t fnum1;
    6273             :         uint32_t attr;
    6274             :         NTSTATUS status;
    6275             : 
    6276           5 :         printf("starting rename test\n");
    6277             : 
    6278           5 :         if (!torture_open_connection(&cli1, 0)) {
    6279           0 :                 return False;
    6280             :         }
    6281             : 
    6282           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6283           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6284             : 
    6285           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6286             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    6287             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6288           5 :         if (!NT_STATUS_IS_OK(status)) {
    6289           0 :                 printf("First open failed - %s\n", nt_errstr(status));
    6290           0 :                 return False;
    6291             :         }
    6292             : 
    6293           5 :         status = cli_rename(cli1, fname, fname1, false);
    6294           5 :         if (!NT_STATUS_IS_OK(status)) {
    6295           5 :                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
    6296             :         } else {
    6297           0 :                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
    6298           0 :                 correct = False;
    6299             :         }
    6300             : 
    6301           5 :         status = cli_close(cli1, fnum1);
    6302           5 :         if (!NT_STATUS_IS_OK(status)) {
    6303           0 :                 printf("close - 1 failed (%s)\n", nt_errstr(status));
    6304           0 :                 return False;
    6305             :         }
    6306             : 
    6307           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6308           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6309           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
    6310             : #if 0
    6311             :                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
    6312             : #else
    6313             :                               FILE_SHARE_DELETE|FILE_SHARE_READ,
    6314             : #endif
    6315             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6316           5 :         if (!NT_STATUS_IS_OK(status)) {
    6317           0 :                 printf("Second open failed - %s\n", nt_errstr(status));
    6318           0 :                 return False;
    6319             :         }
    6320             : 
    6321           5 :         status = cli_rename(cli1, fname, fname1, false);
    6322           5 :         if (!NT_STATUS_IS_OK(status)) {
    6323           0 :                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
    6324           0 :                 correct = False;
    6325             :         } else {
    6326           5 :                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
    6327             :         }
    6328             : 
    6329           5 :         status = cli_close(cli1, fnum1);
    6330           5 :         if (!NT_STATUS_IS_OK(status)) {
    6331           0 :                 printf("close - 2 failed (%s)\n", nt_errstr(status));
    6332           0 :                 return False;
    6333             :         }
    6334             : 
    6335           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6336           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6337             : 
    6338           5 :         status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
    6339             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    6340             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6341           5 :         if (!NT_STATUS_IS_OK(status)) {
    6342           0 :                 printf("Third open failed - %s\n", nt_errstr(status));
    6343           0 :                 return False;
    6344             :         }
    6345             : 
    6346             : 
    6347           5 :         status = cli_rename(cli1, fname, fname1, false);
    6348           5 :         if (!NT_STATUS_IS_OK(status)) {
    6349           0 :                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
    6350           0 :                 correct = False;
    6351             :         } else {
    6352           5 :                 printf("Third rename succeeded (SHARE_NONE)\n");
    6353             :         }
    6354             : 
    6355           5 :         status = cli_close(cli1, fnum1);
    6356           5 :         if (!NT_STATUS_IS_OK(status)) {
    6357           0 :                 printf("close - 3 failed (%s)\n", nt_errstr(status));
    6358           0 :                 return False;
    6359             :         }
    6360             : 
    6361           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6362           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6363             : 
    6364             :         /*----*/
    6365             : 
    6366           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6367             :                               FILE_ATTRIBUTE_NORMAL,
    6368             :                               FILE_SHARE_READ | FILE_SHARE_WRITE,
    6369             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6370           5 :         if (!NT_STATUS_IS_OK(status)) {
    6371           0 :                 printf("Fourth open failed - %s\n", nt_errstr(status));
    6372           0 :                 return False;
    6373             :         }
    6374             : 
    6375           5 :         status = cli_rename(cli1, fname, fname1, false);
    6376           5 :         if (!NT_STATUS_IS_OK(status)) {
    6377           5 :                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
    6378             :         } else {
    6379           0 :                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
    6380           0 :                 correct = False;
    6381             :         }
    6382             : 
    6383           5 :         status = cli_close(cli1, fnum1);
    6384           5 :         if (!NT_STATUS_IS_OK(status)) {
    6385           0 :                 printf("close - 4 failed (%s)\n", nt_errstr(status));
    6386           0 :                 return False;
    6387             :         }
    6388             : 
    6389           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6390           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6391             : 
    6392             :         /*--*/
    6393             : 
    6394           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
    6395             :                          FILE_ATTRIBUTE_NORMAL,
    6396             :                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    6397             :                          FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    6398           5 :         if (!NT_STATUS_IS_OK(status)) {
    6399           0 :                 printf("Fifth open failed - %s\n", nt_errstr(status));
    6400           0 :                 return False;
    6401             :         }
    6402             : 
    6403           5 :         status = cli_rename(cli1, fname, fname1, false);
    6404           5 :         if (!NT_STATUS_IS_OK(status)) {
    6405           0 :                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
    6406           0 :                 correct = False;
    6407             :         } else {
    6408           5 :                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
    6409             :         }
    6410             : 
    6411             :         /*--*/
    6412           5 :         status = cli_close(cli1, fnum1);
    6413           5 :         if (!NT_STATUS_IS_OK(status)) {
    6414           0 :                 printf("close - 5 failed (%s)\n", nt_errstr(status));
    6415           0 :                 return False;
    6416             :         }
    6417             : 
    6418             :         /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
    6419           5 :         status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
    6420           5 :         if (!NT_STATUS_IS_OK(status)) {
    6421           0 :                 printf("getatr on file %s failed - %s ! \n",
    6422             :                         fname1, nt_errstr(status));
    6423           0 :                 correct = False;
    6424             :         } else {
    6425           5 :                 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
    6426           0 :                         printf("Renamed file %s has wrong attr 0x%x "
    6427             :                                 "(should be 0x%x)\n",
    6428             :                                 fname1,
    6429             :                                 attr,
    6430             :                                 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
    6431           0 :                         correct = False;
    6432             :                 } else {
    6433           5 :                         printf("Renamed file %s has archive bit set\n", fname1);
    6434             :                 }
    6435             :         }
    6436             : 
    6437           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6438           5 :         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6439             : 
    6440           5 :         if (!torture_close_connection(cli1)) {
    6441           0 :                 correct = False;
    6442             :         }
    6443             : 
    6444           5 :         return correct;
    6445             : }
    6446             : 
    6447             : /*
    6448             :   Test rename into a directory with an ACL denying it.
    6449             :  */
    6450           4 : static bool run_rename_access(int dummy)
    6451             : {
    6452             :         static struct cli_state *cli = NULL;
    6453             :         static struct cli_state *posix_cli = NULL;
    6454           4 :         const char *src = "test.txt";
    6455           4 :         const char *dname = "dir";
    6456           4 :         const char *dst = "dir\\test.txt";
    6457           4 :         const char *dsrc = "test.dir";
    6458           4 :         const char *ddst = "dir\\test.dir";
    6459           4 :         uint16_t fnum = (uint16_t)-1;
    6460           4 :         struct security_descriptor *sd = NULL;
    6461           4 :         struct security_descriptor *newsd = NULL;
    6462             :         NTSTATUS status;
    6463           4 :         TALLOC_CTX *frame = NULL;
    6464             : 
    6465           4 :         frame = talloc_stackframe();
    6466           4 :         printf("starting rename access test\n");
    6467             : 
    6468             :         /* Windows connection. */
    6469           4 :         if (!torture_open_connection(&cli, 0)) {
    6470           0 :                 goto fail;
    6471             :         }
    6472             : 
    6473           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6474             : 
    6475             :         /* Posix connection. */
    6476           4 :         if (!torture_open_connection(&posix_cli, 0)) {
    6477           0 :                 goto fail;
    6478             :         }
    6479             : 
    6480           4 :         smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
    6481             : 
    6482           4 :         status = torture_setup_unix_extensions(posix_cli);
    6483           4 :         if (!NT_STATUS_IS_OK(status)) {
    6484           0 :                 goto fail;
    6485             :         }
    6486             : 
    6487             :         /* Start with a clean slate. */
    6488           4 :         cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6489           4 :         cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6490           4 :         cli_rmdir(cli, dsrc);
    6491           4 :         cli_rmdir(cli, ddst);
    6492           4 :         cli_rmdir(cli, dname);
    6493             : 
    6494             :         /*
    6495             :          * Setup the destination directory with a DENY ACE to
    6496             :          * prevent new files within it.
    6497             :          */
    6498           4 :         status = cli_ntcreate(cli,
    6499             :                                 dname,
    6500             :                                 0,
    6501             :                                 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
    6502             :                                         WRITE_DAC_ACCESS|FILE_READ_DATA|
    6503             :                                         WRITE_OWNER_ACCESS,
    6504             :                                 FILE_ATTRIBUTE_DIRECTORY,
    6505             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
    6506             :                                 FILE_CREATE,
    6507             :                                 FILE_DIRECTORY_FILE,
    6508             :                                 0,
    6509             :                                 &fnum,
    6510             :                                 NULL);
    6511           4 :         if (!NT_STATUS_IS_OK(status)) {
    6512           0 :                 printf("Create of %s - %s\n", dname, nt_errstr(status));
    6513           0 :                 goto fail;
    6514             :         }
    6515             : 
    6516           4 :         status = cli_query_secdesc(cli,
    6517             :                                 fnum,
    6518             :                                 frame,
    6519             :                                 &sd);
    6520           4 :         if (!NT_STATUS_IS_OK(status)) {
    6521           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6522             :                         dname, nt_errstr(status));
    6523           0 :                 goto fail;
    6524             :         }
    6525             : 
    6526           4 :         newsd = security_descriptor_dacl_create(frame,
    6527             :                                         0,
    6528             :                                         NULL,
    6529             :                                         NULL,
    6530             :                                         SID_WORLD,
    6531             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6532             :                                         SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
    6533             :                                         0,
    6534             :                                         NULL);
    6535           4 :         if (newsd == NULL) {
    6536           0 :                 goto fail;
    6537             :         }
    6538           4 :         sd->dacl = security_acl_concatenate(frame,
    6539           4 :                                         newsd->dacl,
    6540           4 :                                         sd->dacl);
    6541           4 :         if (sd->dacl == NULL) {
    6542           0 :                 goto fail;
    6543             :         }
    6544           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6545           4 :         if (!NT_STATUS_IS_OK(status)) {
    6546           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6547             :                         dname, nt_errstr(status));
    6548           0 :                 goto fail;
    6549             :         }
    6550           4 :         status = cli_close(cli, fnum);
    6551           4 :         if (!NT_STATUS_IS_OK(status)) {
    6552           0 :                 printf("close failed for %s (%s)\n",
    6553             :                         dname, nt_errstr(status));
    6554           0 :                 goto fail;
    6555             :         }
    6556             :         /* Now go around the back and chmod to 777 via POSIX. */
    6557           4 :         status = cli_posix_chmod(posix_cli, dname, 0777);
    6558           4 :         if (!NT_STATUS_IS_OK(status)) {
    6559           0 :                 printf("cli_posix_chmod failed for %s (%s)\n",
    6560             :                         dname, nt_errstr(status));
    6561           0 :                 goto fail;
    6562             :         }
    6563             : 
    6564             :         /* Check we can't create a file within dname via Windows. */
    6565           4 :         status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6566           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6567           0 :                 cli_close(posix_cli, fnum);
    6568           0 :                 printf("Create of %s should be ACCESS denied, was %s\n",
    6569             :                         dst, nt_errstr(status));
    6570           0 :                 goto fail;
    6571             :         }
    6572             : 
    6573             :         /* Make the sample file/directory. */
    6574           4 :         status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    6575           4 :         if (!NT_STATUS_IS_OK(status)) {
    6576           0 :                 printf("open of %s failed (%s)\n", src, nt_errstr(status));
    6577           0 :                 goto fail;
    6578             :         }
    6579           4 :         status = cli_close(cli, fnum);
    6580           4 :         if (!NT_STATUS_IS_OK(status)) {
    6581           0 :                 printf("cli_close failed (%s)\n", nt_errstr(status));
    6582           0 :                 goto fail;
    6583             :         }
    6584             : 
    6585           4 :         status = cli_mkdir(cli, dsrc);
    6586           4 :         if (!NT_STATUS_IS_OK(status)) {
    6587           0 :                 printf("cli_mkdir of %s failed (%s)\n",
    6588             :                         dsrc, nt_errstr(status));
    6589           0 :                 goto fail;
    6590             :         }
    6591             : 
    6592             :         /*
    6593             :          * OK - renames of the new file and directory into the
    6594             :          * dst directory should fail.
    6595             :          */
    6596             : 
    6597           4 :         status = cli_rename(cli, src, dst, false);
    6598           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6599           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6600             :                         src, dst, nt_errstr(status));
    6601           0 :                 goto fail;
    6602             :         }
    6603           4 :         status = cli_rename(cli, dsrc, ddst, false);
    6604           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6605           0 :                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
    6606             :                         src, dst, nt_errstr(status));
    6607           0 :                 goto fail;
    6608             :         }
    6609             : 
    6610           4 :         TALLOC_FREE(frame);
    6611           4 :         return true;
    6612             : 
    6613           0 :   fail:
    6614             : 
    6615           0 :         if (posix_cli) {
    6616           0 :                 torture_close_connection(posix_cli);
    6617             :         }
    6618             : 
    6619           0 :         if (cli) {
    6620           0 :                 if (fnum != (uint16_t)-1) {
    6621           0 :                         cli_close(cli, fnum);
    6622             :                 }
    6623           0 :                 cli_unlink(cli, src,
    6624             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6625           0 :                 cli_unlink(cli, dst,
    6626             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6627           0 :                 cli_rmdir(cli, dsrc);
    6628           0 :                 cli_rmdir(cli, ddst);
    6629           0 :                 cli_rmdir(cli, dname);
    6630             : 
    6631           0 :                 torture_close_connection(cli);
    6632             :         }
    6633             : 
    6634           0 :         TALLOC_FREE(frame);
    6635           0 :         return false;
    6636             : }
    6637             : 
    6638             : /*
    6639             :   Test owner rights ACE.
    6640             :  */
    6641           4 : static bool run_owner_rights(int dummy)
    6642             : {
    6643             :         static struct cli_state *cli = NULL;
    6644           4 :         const char *fname = "owner_rights.txt";
    6645           4 :         uint16_t fnum = (uint16_t)-1;
    6646           4 :         struct security_descriptor *sd = NULL;
    6647           4 :         struct security_descriptor *newsd = NULL;
    6648             :         NTSTATUS status;
    6649           4 :         TALLOC_CTX *frame = NULL;
    6650             : 
    6651           4 :         frame = talloc_stackframe();
    6652           4 :         printf("starting owner rights test\n");
    6653             : 
    6654             :         /* Windows connection. */
    6655           4 :         if (!torture_open_connection(&cli, 0)) {
    6656           0 :                 goto fail;
    6657             :         }
    6658             : 
    6659           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    6660             : 
    6661             :         /* Start with a clean slate. */
    6662           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6663             : 
    6664             :         /* Create the test file. */
    6665             :         /* Now try and open for read and write-dac. */
    6666           4 :         status = cli_ntcreate(cli,
    6667             :                                 fname,
    6668             :                                 0,
    6669             :                                 GENERIC_ALL_ACCESS,
    6670             :                                 FILE_ATTRIBUTE_NORMAL,
    6671             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6672             :                                         FILE_SHARE_DELETE,
    6673             :                                 FILE_CREATE,
    6674             :                                 0,
    6675             :                                 0,
    6676             :                                 &fnum,
    6677             :                                 NULL);
    6678           4 :         if (!NT_STATUS_IS_OK(status)) {
    6679           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6680           0 :                 goto fail;
    6681             :         }
    6682             : 
    6683             :         /* Get the original SD. */
    6684           4 :         status = cli_query_secdesc(cli,
    6685             :                                 fnum,
    6686             :                                 frame,
    6687             :                                 &sd);
    6688           4 :         if (!NT_STATUS_IS_OK(status)) {
    6689           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6690             :                         fname, nt_errstr(status));
    6691           0 :                 goto fail;
    6692             :         }
    6693             : 
    6694             :         /*
    6695             :          * Add an "owner-rights" ACE denying WRITE_DATA,
    6696             :          * and an "owner-rights" ACE allowing READ_DATA.
    6697             :          */
    6698             : 
    6699           4 :         newsd = security_descriptor_dacl_create(frame,
    6700             :                                         0,
    6701             :                                         NULL,
    6702             :                                         NULL,
    6703             :                                         SID_OWNER_RIGHTS,
    6704             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6705             :                                         FILE_WRITE_DATA,
    6706             :                                         0,
    6707             :                                         SID_OWNER_RIGHTS,
    6708             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    6709             :                                         FILE_READ_DATA,
    6710             :                                         0,
    6711             :                                         NULL);
    6712           4 :         if (newsd == NULL) {
    6713           0 :                 goto fail;
    6714             :         }
    6715           4 :         sd->dacl = security_acl_concatenate(frame,
    6716           4 :                                         newsd->dacl,
    6717           4 :                                         sd->dacl);
    6718           4 :         if (sd->dacl == NULL) {
    6719           0 :                 goto fail;
    6720             :         }
    6721           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6722           4 :         if (!NT_STATUS_IS_OK(status)) {
    6723           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6724             :                         fname, nt_errstr(status));
    6725           0 :                 goto fail;
    6726             :         }
    6727           4 :         status = cli_close(cli, fnum);
    6728           4 :         if (!NT_STATUS_IS_OK(status)) {
    6729           0 :                 printf("close failed for %s (%s)\n",
    6730             :                         fname, nt_errstr(status));
    6731           0 :                 goto fail;
    6732             :         }
    6733           4 :         fnum = (uint16_t)-1;
    6734             : 
    6735             :         /* Try and open for FILE_WRITE_DATA */
    6736           4 :         status = cli_ntcreate(cli,
    6737             :                                 fname,
    6738             :                                 0,
    6739             :                                 FILE_WRITE_DATA,
    6740             :                                 FILE_ATTRIBUTE_NORMAL,
    6741             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6742             :                                         FILE_SHARE_DELETE,
    6743             :                                 FILE_OPEN,
    6744             :                                 0,
    6745             :                                 0,
    6746             :                                 &fnum,
    6747             :                                 NULL);
    6748           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6749           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6750           0 :                 goto fail;
    6751             :         }
    6752             : 
    6753             :         /* Now try and open for FILE_READ_DATA */
    6754           4 :         status = cli_ntcreate(cli,
    6755             :                                 fname,
    6756             :                                 0,
    6757             :                                 FILE_READ_DATA,
    6758             :                                 FILE_ATTRIBUTE_NORMAL,
    6759             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6760             :                                         FILE_SHARE_DELETE,
    6761             :                                 FILE_OPEN,
    6762             :                                 0,
    6763             :                                 0,
    6764             :                                 &fnum,
    6765             :                                 NULL);
    6766           4 :         if (!NT_STATUS_IS_OK(status)) {
    6767           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6768           0 :                 goto fail;
    6769             :         }
    6770             : 
    6771           4 :         status = cli_close(cli, fnum);
    6772           4 :         if (!NT_STATUS_IS_OK(status)) {
    6773           0 :                 printf("close failed for %s (%s)\n",
    6774             :                         fname, nt_errstr(status));
    6775           0 :                 goto fail;
    6776             :         }
    6777             : 
    6778             :         /* Restore clean slate. */
    6779           4 :         TALLOC_FREE(sd);
    6780           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6781             : 
    6782             :         /* Create the test file. */
    6783           4 :         status = cli_ntcreate(cli,
    6784             :                                 fname,
    6785             :                                 0,
    6786             :                                 GENERIC_ALL_ACCESS,
    6787             :                                 FILE_ATTRIBUTE_NORMAL,
    6788             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6789             :                                         FILE_SHARE_DELETE,
    6790             :                                 FILE_CREATE,
    6791             :                                 0,
    6792             :                                 0,
    6793             :                                 &fnum,
    6794             :                                 NULL);
    6795           4 :         if (!NT_STATUS_IS_OK(status)) {
    6796           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6797           0 :                 goto fail;
    6798             :         }
    6799             : 
    6800             :         /* Get the original SD. */
    6801           4 :         status = cli_query_secdesc(cli,
    6802             :                                 fnum,
    6803             :                                 frame,
    6804             :                                 &sd);
    6805           4 :         if (!NT_STATUS_IS_OK(status)) {
    6806           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6807             :                         fname, nt_errstr(status));
    6808           0 :                 goto fail;
    6809             :         }
    6810             : 
    6811             :         /*
    6812             :          * Add an "owner-rights ACE denying WRITE_DATA,
    6813             :          * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
    6814             :          */
    6815             : 
    6816           4 :         newsd = security_descriptor_dacl_create(frame,
    6817             :                                         0,
    6818             :                                         NULL,
    6819             :                                         NULL,
    6820             :                                         SID_OWNER_RIGHTS,
    6821             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6822             :                                         FILE_WRITE_DATA,
    6823             :                                         0,
    6824             :                                         SID_OWNER_RIGHTS,
    6825             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    6826             :                                         FILE_READ_DATA|FILE_WRITE_DATA,
    6827             :                                         0,
    6828             :                                         NULL);
    6829           4 :         if (newsd == NULL) {
    6830           0 :                 goto fail;
    6831             :         }
    6832           4 :         sd->dacl = security_acl_concatenate(frame,
    6833           4 :                                         newsd->dacl,
    6834           4 :                                         sd->dacl);
    6835           4 :         if (sd->dacl == NULL) {
    6836           0 :                 goto fail;
    6837             :         }
    6838           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6839           4 :         if (!NT_STATUS_IS_OK(status)) {
    6840           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6841             :                         fname, nt_errstr(status));
    6842           0 :                 goto fail;
    6843             :         }
    6844           4 :         status = cli_close(cli, fnum);
    6845           4 :         if (!NT_STATUS_IS_OK(status)) {
    6846           0 :                 printf("close failed for %s (%s)\n",
    6847             :                         fname, nt_errstr(status));
    6848           0 :                 goto fail;
    6849             :         }
    6850           4 :         fnum = (uint16_t)-1;
    6851             : 
    6852             :         /* Try and open for FILE_WRITE_DATA */
    6853           4 :         status = cli_ntcreate(cli,
    6854             :                                 fname,
    6855             :                                 0,
    6856             :                                 FILE_WRITE_DATA,
    6857             :                                 FILE_ATTRIBUTE_NORMAL,
    6858             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6859             :                                         FILE_SHARE_DELETE,
    6860             :                                 FILE_OPEN,
    6861             :                                 0,
    6862             :                                 0,
    6863             :                                 &fnum,
    6864             :                                 NULL);
    6865           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    6866           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6867           0 :                 goto fail;
    6868             :         }
    6869             : 
    6870             :         /* Now try and open for FILE_READ_DATA */
    6871           4 :         status = cli_ntcreate(cli,
    6872             :                                 fname,
    6873             :                                 0,
    6874             :                                 FILE_READ_DATA,
    6875             :                                 FILE_ATTRIBUTE_NORMAL,
    6876             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6877             :                                         FILE_SHARE_DELETE,
    6878             :                                 FILE_OPEN,
    6879             :                                 0,
    6880             :                                 0,
    6881             :                                 &fnum,
    6882             :                                 NULL);
    6883           4 :         if (!NT_STATUS_IS_OK(status)) {
    6884           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6885           0 :                 goto fail;
    6886             :         }
    6887             : 
    6888           4 :         status = cli_close(cli, fnum);
    6889           4 :         if (!NT_STATUS_IS_OK(status)) {
    6890           0 :                 printf("close failed for %s (%s)\n",
    6891             :                         fname, nt_errstr(status));
    6892           0 :                 goto fail;
    6893             :         }
    6894             : 
    6895             :         /* Restore clean slate. */
    6896           4 :         TALLOC_FREE(sd);
    6897           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    6898             : 
    6899             : 
    6900             :         /* Create the test file. */
    6901           4 :         status = cli_ntcreate(cli,
    6902             :                                 fname,
    6903             :                                 0,
    6904             :                                 GENERIC_ALL_ACCESS,
    6905             :                                 FILE_ATTRIBUTE_NORMAL,
    6906             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6907             :                                         FILE_SHARE_DELETE,
    6908             :                                 FILE_CREATE,
    6909             :                                 0,
    6910             :                                 0,
    6911             :                                 &fnum,
    6912             :                                 NULL);
    6913           4 :         if (!NT_STATUS_IS_OK(status)) {
    6914           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    6915           0 :                 goto fail;
    6916             :         }
    6917             : 
    6918             :         /* Get the original SD. */
    6919           4 :         status = cli_query_secdesc(cli,
    6920             :                                 fnum,
    6921             :                                 frame,
    6922             :                                 &sd);
    6923           4 :         if (!NT_STATUS_IS_OK(status)) {
    6924           0 :                 printf("cli_query_secdesc failed for %s (%s)\n",
    6925             :                         fname, nt_errstr(status));
    6926           0 :                 goto fail;
    6927             :         }
    6928             : 
    6929             :         /*
    6930             :          * Add an "authenticated users" ACE allowing READ_DATA,
    6931             :          * add an "owner-rights" denying READ_DATA,
    6932             :          * and an "authenticated users" ACE allowing WRITE_DATA.
    6933             :          */
    6934             : 
    6935           4 :         newsd = security_descriptor_dacl_create(frame,
    6936             :                                         0,
    6937             :                                         NULL,
    6938             :                                         NULL,
    6939             :                                         SID_NT_AUTHENTICATED_USERS,
    6940             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    6941             :                                         FILE_READ_DATA,
    6942             :                                         0,
    6943             :                                         SID_OWNER_RIGHTS,
    6944             :                                         SEC_ACE_TYPE_ACCESS_DENIED,
    6945             :                                         FILE_READ_DATA,
    6946             :                                         0,
    6947             :                                         SID_NT_AUTHENTICATED_USERS,
    6948             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
    6949             :                                         FILE_WRITE_DATA,
    6950             :                                         0,
    6951             :                                         NULL);
    6952           4 :         if (newsd == NULL) {
    6953           0 :                 printf("newsd == NULL\n");
    6954           0 :                 goto fail;
    6955             :         }
    6956           4 :         sd->dacl = security_acl_concatenate(frame,
    6957           4 :                                         newsd->dacl,
    6958           4 :                                         sd->dacl);
    6959           4 :         if (sd->dacl == NULL) {
    6960           0 :                 printf("sd->dacl == NULL\n");
    6961           0 :                 goto fail;
    6962             :         }
    6963           4 :         status = cli_set_secdesc(cli, fnum, sd);
    6964           4 :         if (!NT_STATUS_IS_OK(status)) {
    6965           0 :                 printf("cli_set_secdesc failed for %s (%s)\n",
    6966             :                         fname, nt_errstr(status));
    6967           0 :                 goto fail;
    6968             :         }
    6969           4 :         status = cli_close(cli, fnum);
    6970           4 :         if (!NT_STATUS_IS_OK(status)) {
    6971           0 :                 printf("close failed for %s (%s)\n",
    6972             :                         fname, nt_errstr(status));
    6973           0 :                 goto fail;
    6974             :         }
    6975           4 :         fnum = (uint16_t)-1;
    6976             : 
    6977             :         /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
    6978           4 :         status = cli_ntcreate(cli,
    6979             :                                 fname,
    6980             :                                 0,
    6981             :                                 FILE_READ_DATA|FILE_WRITE_DATA,
    6982             :                                 FILE_ATTRIBUTE_NORMAL,
    6983             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    6984             :                                         FILE_SHARE_DELETE,
    6985             :                                 FILE_OPEN,
    6986             :                                 0,
    6987             :                                 0,
    6988             :                                 &fnum,
    6989             :                                 NULL);
    6990           4 :         if (!NT_STATUS_IS_OK(status)) {
    6991           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    6992           0 :                 goto fail;
    6993             :         }
    6994             : 
    6995           4 :         status = cli_close(cli, fnum);
    6996           4 :         if (!NT_STATUS_IS_OK(status)) {
    6997           0 :                 printf("close failed for %s (%s)\n",
    6998             :                         fname, nt_errstr(status));
    6999           0 :                 goto fail;
    7000             :         }
    7001             : 
    7002           4 :         cli_unlink(cli, fname,
    7003             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7004             : 
    7005           4 :         TALLOC_FREE(frame);
    7006           4 :         return true;
    7007             : 
    7008           0 :   fail:
    7009             : 
    7010           0 :         if (cli) {
    7011           0 :                 if (fnum != (uint16_t)-1) {
    7012           0 :                         cli_close(cli, fnum);
    7013             :                 }
    7014           0 :                 cli_unlink(cli, fname,
    7015             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7016           0 :                 torture_close_connection(cli);
    7017             :         }
    7018             : 
    7019           0 :         TALLOC_FREE(frame);
    7020           0 :         return false;
    7021             : }
    7022             : 
    7023             : /*
    7024             :  * Test SMB1-specific open with SEC_FLAG_SYSTEM_SECURITY.
    7025             :  * Note this test only works with a user with SeSecurityPrivilege set.
    7026             :  *
    7027             :  * NB. This is also tested in samba3.base.createx_access
    7028             :  * but this makes it very explicit what we're looking for.
    7029             :  */
    7030           2 : static bool run_smb1_system_security(int dummy)
    7031             : {
    7032             :         static struct cli_state *cli = NULL;
    7033           2 :         const char *fname = "system_security.txt";
    7034           2 :         uint16_t fnum = (uint16_t)-1;
    7035             :         NTSTATUS status;
    7036           2 :         TALLOC_CTX *frame = NULL;
    7037             : 
    7038           2 :         frame = talloc_stackframe();
    7039           2 :         printf("starting smb1 system security test\n");
    7040             : 
    7041             :         /* SMB1 connection - torture_open_connection() forces this. */
    7042           2 :         if (!torture_open_connection(&cli, 0)) {
    7043           0 :                 goto fail;
    7044             :         }
    7045             : 
    7046           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    7047             : 
    7048             :         /* Start with a clean slate. */
    7049           2 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7050             : 
    7051             :         /* Create the test file. */
    7052           2 :         status = cli_ntcreate(cli,
    7053             :                                 fname,
    7054             :                                 0,
    7055             :                                 GENERIC_ALL_ACCESS,
    7056             :                                 FILE_ATTRIBUTE_NORMAL,
    7057             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7058             :                                         FILE_SHARE_DELETE,
    7059             :                                 FILE_CREATE,
    7060             :                                 0,
    7061             :                                 0,
    7062             :                                 &fnum,
    7063             :                                 NULL);
    7064           2 :         if (!NT_STATUS_IS_OK(status)) {
    7065           0 :                 printf("Create of %s - %s\n", fname, nt_errstr(status));
    7066           0 :                 goto fail;
    7067             :         }
    7068             : 
    7069           2 :         status = cli_close(cli, fnum);
    7070             : 
    7071             :         /* Open with SEC_FLAG_SYSTEM_SECURITY only. */
    7072             :         /*
    7073             :          * On SMB1 this succeeds - SMB2 it fails,
    7074             :          * see the SMB2-SACL test.
    7075             :          */
    7076           2 :         status = cli_ntcreate(cli,
    7077             :                                 fname,
    7078             :                                 0,
    7079             :                                 SEC_FLAG_SYSTEM_SECURITY,
    7080             :                                 FILE_ATTRIBUTE_NORMAL,
    7081             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
    7082             :                                         FILE_SHARE_DELETE,
    7083             :                                 FILE_OPEN,
    7084             :                                 0,
    7085             :                                 0,
    7086             :                                 &fnum,
    7087             :                                 NULL);
    7088           2 :         if (!NT_STATUS_IS_OK(status)) {
    7089           0 :                 printf("Open of %s - %s\n", fname, nt_errstr(status));
    7090           0 :                 goto fail;
    7091             :         }
    7092             : 
    7093           2 :         status = cli_close(cli, fnum);
    7094             : 
    7095           2 :         cli_unlink(cli, fname,
    7096             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7097             : 
    7098           2 :         torture_close_connection(cli);
    7099           2 :         TALLOC_FREE(frame);
    7100           2 :         return true;
    7101             : 
    7102           0 :   fail:
    7103             : 
    7104           0 :         if (cli) {
    7105           0 :                 if (fnum != (uint16_t)-1) {
    7106           0 :                         cli_close(cli, fnum);
    7107             :                 }
    7108           0 :                 cli_unlink(cli, fname,
    7109             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7110           0 :                 torture_close_connection(cli);
    7111             :         }
    7112             : 
    7113           0 :         TALLOC_FREE(frame);
    7114           0 :         return false;
    7115             : }
    7116             : 
    7117           0 : static bool run_pipe_number(int dummy)
    7118             : {
    7119             :         struct cli_state *cli1;
    7120           0 :         const char *pipe_name = "\\SPOOLSS";
    7121             :         uint16_t fnum;
    7122           0 :         int num_pipes = 0;
    7123             :         NTSTATUS status;
    7124             : 
    7125           0 :         printf("starting pipenumber test\n");
    7126           0 :         if (!torture_open_connection(&cli1, 0)) {
    7127           0 :                 return False;
    7128             :         }
    7129             : 
    7130           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7131             :         while(1) {
    7132           0 :                 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
    7133             :                                       FILE_ATTRIBUTE_NORMAL,
    7134             :                                       FILE_SHARE_READ|FILE_SHARE_WRITE,
    7135             :                                       FILE_OPEN_IF, 0, 0, &fnum, NULL);
    7136           0 :                 if (!NT_STATUS_IS_OK(status)) {
    7137           0 :                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
    7138           0 :                         break;
    7139             :                 }
    7140           0 :                 num_pipes++;
    7141           0 :                 printf("\r%6d", num_pipes);
    7142             :         }
    7143             : 
    7144           0 :         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
    7145           0 :         torture_close_connection(cli1);
    7146           0 :         return True;
    7147             : }
    7148             : 
    7149             : /*
    7150             :   Test open mode returns on read-only files.
    7151             :  */
    7152           5 : static bool run_opentest(int dummy)
    7153             : {
    7154             :         static struct cli_state *cli1;
    7155             :         static struct cli_state *cli2;
    7156           5 :         const char *fname = "\\readonly.file";
    7157             :         uint16_t fnum1, fnum2;
    7158             :         char buf[20];
    7159             :         off_t fsize;
    7160           5 :         bool correct = True;
    7161             :         char *tmp_path;
    7162             :         NTSTATUS status;
    7163             : 
    7164           5 :         printf("starting open test\n");
    7165             : 
    7166           5 :         if (!torture_open_connection(&cli1, 0)) {
    7167           0 :                 return False;
    7168             :         }
    7169             : 
    7170           5 :         cli_setatr(cli1, fname, 0, 0);
    7171           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7172             : 
    7173           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7174             : 
    7175           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7176           5 :         if (!NT_STATUS_IS_OK(status)) {
    7177           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7178           0 :                 return False;
    7179             :         }
    7180             : 
    7181           5 :         status = cli_close(cli1, fnum1);
    7182           5 :         if (!NT_STATUS_IS_OK(status)) {
    7183           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7184           0 :                 return False;
    7185             :         }
    7186             : 
    7187           5 :         status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
    7188           5 :         if (!NT_STATUS_IS_OK(status)) {
    7189           0 :                 printf("cli_setatr failed (%s)\n", nt_errstr(status));
    7190           0 :                 return False;
    7191             :         }
    7192             : 
    7193           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7194           5 :         if (!NT_STATUS_IS_OK(status)) {
    7195           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7196           0 :                 return False;
    7197             :         }
    7198             : 
    7199             :         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
    7200           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7201             : 
    7202           5 :         if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
    7203           5 :                         NT_STATUS_ACCESS_DENIED)) {
    7204           4 :                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
    7205             :         }
    7206             : 
    7207           5 :         printf("finished open test 1\n");
    7208             : 
    7209           5 :         cli_close(cli1, fnum1);
    7210             : 
    7211             :         /* Now try not readonly and ensure ERRbadshare is returned. */
    7212             : 
    7213           5 :         cli_setatr(cli1, fname, 0, 0);
    7214             : 
    7215           5 :         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
    7216           5 :         if (!NT_STATUS_IS_OK(status)) {
    7217           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    7218           0 :                 return False;
    7219             :         }
    7220             : 
    7221             :         /* This will fail - but the error should be ERRshare. */
    7222           5 :         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
    7223             : 
    7224           5 :         if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
    7225           5 :                         NT_STATUS_SHARING_VIOLATION)) {
    7226           5 :                 printf("correct error code ERRDOS/ERRbadshare returned\n");
    7227             :         }
    7228             : 
    7229           5 :         status = cli_close(cli1, fnum1);
    7230           5 :         if (!NT_STATUS_IS_OK(status)) {
    7231           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7232           0 :                 return False;
    7233             :         }
    7234             : 
    7235           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7236             : 
    7237           5 :         printf("finished open test 2\n");
    7238             : 
    7239             :         /* Test truncate open disposition on file opened for read. */
    7240           5 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
    7241           5 :         if (!NT_STATUS_IS_OK(status)) {
    7242           0 :                 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
    7243           0 :                 return False;
    7244             :         }
    7245             : 
    7246             :         /* write 20 bytes. */
    7247             : 
    7248           5 :         memset(buf, '\0', 20);
    7249             : 
    7250           5 :         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
    7251           5 :         if (!NT_STATUS_IS_OK(status)) {
    7252           0 :                 printf("write failed (%s)\n", nt_errstr(status));
    7253           0 :                 correct = False;
    7254             :         }
    7255             : 
    7256           5 :         status = cli_close(cli1, fnum1);
    7257           5 :         if (!NT_STATUS_IS_OK(status)) {
    7258           0 :                 printf("(3) close1 failed (%s)\n", nt_errstr(status));
    7259           0 :                 return False;
    7260             :         }
    7261             : 
    7262             :         /* Ensure size == 20. */
    7263           5 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7264           5 :         if (!NT_STATUS_IS_OK(status)) {
    7265           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7266           0 :                 return False;
    7267             :         }
    7268             : 
    7269           5 :         if (fsize != 20) {
    7270           0 :                 printf("(3) file size != 20\n");
    7271           0 :                 return False;
    7272             :         }
    7273             : 
    7274             :         /* Now test if we can truncate a file opened for readonly. */
    7275           5 :         status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
    7276           5 :         if (!NT_STATUS_IS_OK(status)) {
    7277           0 :                 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
    7278           0 :                 return False;
    7279             :         }
    7280             : 
    7281           5 :         status = cli_close(cli1, fnum1);
    7282           5 :         if (!NT_STATUS_IS_OK(status)) {
    7283           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    7284           0 :                 return False;
    7285             :         }
    7286             : 
    7287             :         /* Ensure size == 0. */
    7288           5 :         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
    7289           5 :         if (!NT_STATUS_IS_OK(status)) {
    7290           0 :                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
    7291           0 :                 return False;
    7292             :         }
    7293             : 
    7294           5 :         if (fsize != 0) {
    7295           0 :                 printf("(3) file size != 0\n");
    7296           0 :                 return False;
    7297             :         }
    7298           5 :         printf("finished open test 3\n");
    7299             : 
    7300           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7301             : 
    7302           5 :         printf("Do ctemp tests\n");
    7303           5 :         status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
    7304           5 :         if (!NT_STATUS_IS_OK(status)) {
    7305           0 :                 printf("ctemp failed (%s)\n", nt_errstr(status));
    7306           0 :                 return False;
    7307             :         }
    7308             : 
    7309           5 :         printf("ctemp gave path %s\n", tmp_path);
    7310           5 :         status = cli_close(cli1, fnum1);
    7311           5 :         if (!NT_STATUS_IS_OK(status)) {
    7312           0 :                 printf("close of temp failed (%s)\n", nt_errstr(status));
    7313             :         }
    7314             : 
    7315           5 :         status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7316           5 :         if (!NT_STATUS_IS_OK(status)) {
    7317           0 :                 printf("unlink of temp failed (%s)\n", nt_errstr(status));
    7318             :         }
    7319             : 
    7320             :         /* Test the non-io opens... */
    7321             : 
    7322           5 :         if (!torture_open_connection(&cli2, 1)) {
    7323           0 :                 return False;
    7324             :         }
    7325             : 
    7326           5 :         cli_setatr(cli2, fname, 0, 0);
    7327           5 :         cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7328             : 
    7329           5 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    7330             : 
    7331           5 :         printf("TEST #1 testing 2 non-io opens (no delete)\n");
    7332           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7333             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7334             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7335           5 :         if (!NT_STATUS_IS_OK(status)) {
    7336           0 :                 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7337           0 :                 return False;
    7338             :         }
    7339             : 
    7340           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7341             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7342             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7343           5 :         if (!NT_STATUS_IS_OK(status)) {
    7344           0 :                 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7345           0 :                 return False;
    7346             :         }
    7347             : 
    7348           5 :         status = cli_close(cli1, fnum1);
    7349           5 :         if (!NT_STATUS_IS_OK(status)) {
    7350           0 :                 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7351           0 :                 return False;
    7352             :         }
    7353             : 
    7354           5 :         status = cli_close(cli2, fnum2);
    7355           5 :         if (!NT_STATUS_IS_OK(status)) {
    7356           0 :                 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7357           0 :                 return False;
    7358             :         }
    7359             : 
    7360           5 :         printf("non-io open test #1 passed.\n");
    7361             : 
    7362           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7363             : 
    7364           5 :         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
    7365             : 
    7366           5 :         status = cli_ntcreate(cli1, fname, 0,
    7367             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7368             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7369             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7370           5 :         if (!NT_STATUS_IS_OK(status)) {
    7371           0 :                 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7372           0 :                 return False;
    7373             :         }
    7374             : 
    7375           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7376             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7377             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7378           5 :         if (!NT_STATUS_IS_OK(status)) {
    7379           0 :                 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7380           0 :                 return False;
    7381             :         }
    7382             : 
    7383           5 :         status = cli_close(cli1, fnum1);
    7384           5 :         if (!NT_STATUS_IS_OK(status)) {
    7385           0 :                 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7386           0 :                 return False;
    7387             :         }
    7388             : 
    7389           5 :         status = cli_close(cli2, fnum2);
    7390           5 :         if (!NT_STATUS_IS_OK(status)) {
    7391           0 :                 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7392           0 :                 return False;
    7393             :         }
    7394             : 
    7395           5 :         printf("non-io open test #2 passed.\n");
    7396             : 
    7397           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7398             : 
    7399           5 :         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
    7400             : 
    7401           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
    7402             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7403             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7404           5 :         if (!NT_STATUS_IS_OK(status)) {
    7405           0 :                 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7406           0 :                 return False;
    7407             :         }
    7408             : 
    7409           5 :         status = cli_ntcreate(cli2, fname, 0,
    7410             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7411             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7412             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7413           5 :         if (!NT_STATUS_IS_OK(status)) {
    7414           0 :                 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7415           0 :                 return False;
    7416             :         }
    7417             : 
    7418           5 :         status = cli_close(cli1, fnum1);
    7419           5 :         if (!NT_STATUS_IS_OK(status)) {
    7420           0 :                 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7421           0 :                 return False;
    7422             :         }
    7423             : 
    7424           5 :         status = cli_close(cli2, fnum2);
    7425           5 :         if (!NT_STATUS_IS_OK(status)) {
    7426           0 :                 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7427           0 :                 return False;
    7428             :         }
    7429             : 
    7430           5 :         printf("non-io open test #3 passed.\n");
    7431             : 
    7432           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7433             : 
    7434           5 :         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
    7435             : 
    7436           5 :         status = cli_ntcreate(cli1, fname, 0,
    7437             :                                DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7438             :                                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7439             :                                FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7440           5 :         if (!NT_STATUS_IS_OK(status)) {
    7441           0 :                 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7442           0 :                 return False;
    7443             :         }
    7444             : 
    7445           5 :         status = cli_ntcreate(cli2, fname, 0,
    7446             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7447             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7448             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7449           5 :         if (NT_STATUS_IS_OK(status)) {
    7450           0 :                 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7451           0 :                 return False;
    7452             :         }
    7453             : 
    7454           5 :         printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7455             : 
    7456           5 :         status = cli_close(cli1, fnum1);
    7457           5 :         if (!NT_STATUS_IS_OK(status)) {
    7458           0 :                 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7459           0 :                 return False;
    7460             :         }
    7461             : 
    7462           5 :         printf("non-io open test #4 passed.\n");
    7463             : 
    7464           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7465             : 
    7466           5 :         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
    7467             : 
    7468           5 :         status = cli_ntcreate(cli1, fname, 0,
    7469             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7470             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7471             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7472           5 :         if (!NT_STATUS_IS_OK(status)) {
    7473           0 :                 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7474           0 :                 return False;
    7475             :         }
    7476             : 
    7477           5 :         status = cli_ntcreate(cli2, fname, 0,
    7478             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7479             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
    7480             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7481           5 :         if (!NT_STATUS_IS_OK(status)) {
    7482           0 :                 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7483           0 :                 return False;
    7484             :         }
    7485             : 
    7486           5 :         status = cli_close(cli1, fnum1);
    7487           5 :         if (!NT_STATUS_IS_OK(status)) {
    7488           0 :                 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7489           0 :                 return False;
    7490             :         }
    7491             : 
    7492           5 :         status = cli_close(cli2, fnum2);
    7493           5 :         if (!NT_STATUS_IS_OK(status)) {
    7494           0 :                 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7495           0 :                 return False;
    7496             :         }
    7497             : 
    7498           5 :         printf("non-io open test #5 passed.\n");
    7499             : 
    7500           5 :         printf("TEST #6 testing 1 non-io open, one io open\n");
    7501             : 
    7502           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7503             : 
    7504           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7505             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7506             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7507           5 :         if (!NT_STATUS_IS_OK(status)) {
    7508           0 :                 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7509           0 :                 return False;
    7510             :         }
    7511             : 
    7512           5 :         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
    7513             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
    7514             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7515           5 :         if (!NT_STATUS_IS_OK(status)) {
    7516           0 :                 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7517           0 :                 return False;
    7518             :         }
    7519             : 
    7520           5 :         status = cli_close(cli1, fnum1);
    7521           5 :         if (!NT_STATUS_IS_OK(status)) {
    7522           0 :                 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7523           0 :                 return False;
    7524             :         }
    7525             : 
    7526           5 :         status = cli_close(cli2, fnum2);
    7527           5 :         if (!NT_STATUS_IS_OK(status)) {
    7528           0 :                 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
    7529           0 :                 return False;
    7530             :         }
    7531             : 
    7532           5 :         printf("non-io open test #6 passed.\n");
    7533             : 
    7534           5 :         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
    7535             : 
    7536           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7537             : 
    7538           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
    7539             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
    7540             :                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7541           5 :         if (!NT_STATUS_IS_OK(status)) {
    7542           0 :                 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7543           0 :                 return False;
    7544             :         }
    7545             : 
    7546           5 :         status = cli_ntcreate(cli2, fname, 0,
    7547             :                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
    7548             :                               FILE_ATTRIBUTE_NORMAL,
    7549             :                               FILE_SHARE_READ|FILE_SHARE_DELETE,
    7550             :                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
    7551           5 :         if (NT_STATUS_IS_OK(status)) {
    7552           0 :                 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
    7553           0 :                 return False;
    7554             :         }
    7555             : 
    7556           5 :         printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
    7557             : 
    7558           5 :         status = cli_close(cli1, fnum1);
    7559           5 :         if (!NT_STATUS_IS_OK(status)) {
    7560           0 :                 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
    7561           0 :                 return False;
    7562             :         }
    7563             : 
    7564           5 :         printf("non-io open test #7 passed.\n");
    7565             : 
    7566           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    7567             : 
    7568           5 :         printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
    7569           5 :         status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
    7570             :                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    7571             :                                 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    7572           5 :         if (!NT_STATUS_IS_OK(status)) {
    7573           0 :                 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
    7574           0 :                 correct = false;
    7575           0 :                 goto out;
    7576             :         }
    7577             : 
    7578             :         /* Write to ensure we have to update the file time. */
    7579           5 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    7580             :                               NULL);
    7581           5 :         if (!NT_STATUS_IS_OK(status)) {
    7582           0 :                 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
    7583           0 :                 correct = false;
    7584           0 :                 goto out;
    7585             :         }
    7586             : 
    7587           5 :         status = cli_close(cli1, fnum1);
    7588           5 :         if (!NT_STATUS_IS_OK(status)) {
    7589           0 :                 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
    7590           0 :                 correct = false;
    7591             :         }
    7592             : 
    7593          10 :   out:
    7594             : 
    7595           5 :         if (!torture_close_connection(cli1)) {
    7596           0 :                 correct = False;
    7597             :         }
    7598           5 :         if (!torture_close_connection(cli2)) {
    7599           0 :                 correct = False;
    7600             :         }
    7601             : 
    7602           5 :         return correct;
    7603             : }
    7604             : 
    7605          98 : NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
    7606             : {
    7607             :         uint16_t major, minor;
    7608             :         uint32_t caplow, caphigh;
    7609             :         NTSTATUS status;
    7610             : 
    7611          98 :         if (!SERVER_HAS_UNIX_CIFS(cli)) {
    7612           0 :                 printf("Server doesn't support UNIX CIFS extensions.\n");
    7613           0 :                 return NT_STATUS_NOT_SUPPORTED;
    7614             :         }
    7615             : 
    7616          98 :         status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
    7617             :                                              &caphigh);
    7618          98 :         if (!NT_STATUS_IS_OK(status)) {
    7619           0 :                 printf("Server didn't return UNIX CIFS extensions: %s\n",
    7620             :                        nt_errstr(status));
    7621           0 :                 return status;
    7622             :         }
    7623             : 
    7624          98 :         status = cli_set_unix_extensions_capabilities(cli, major, minor,
    7625             :                                                       caplow, caphigh);
    7626          98 :         if (!NT_STATUS_IS_OK(status)) {
    7627           0 :                 printf("Server doesn't support setting UNIX CIFS extensions: "
    7628             :                        "%s.\n", nt_errstr(status));
    7629           0 :                 return status;
    7630             :         }
    7631             : 
    7632          98 :         return NT_STATUS_OK;
    7633             : }
    7634             : 
    7635             : /*
    7636             :   Test POSIX open /mkdir calls.
    7637             :  */
    7638           4 : static bool run_simple_posix_open_test(int dummy)
    7639             : {
    7640             :         static struct cli_state *cli1;
    7641           4 :         const char *fname = "posix:file";
    7642           4 :         const char *hname = "posix:hlink";
    7643           4 :         const char *sname = "posix:symlink";
    7644           4 :         const char *dname = "posix:dir";
    7645             :         char buf[10];
    7646           4 :         char *target = NULL;
    7647           4 :         uint16_t fnum1 = (uint16_t)-1;
    7648             :         SMB_STRUCT_STAT sbuf;
    7649           4 :         bool correct = false;
    7650             :         NTSTATUS status;
    7651             :         size_t nread;
    7652           4 :         const char *fname_windows = "windows_file";
    7653           4 :         uint16_t fnum2 = (uint16_t)-1;
    7654             : 
    7655           4 :         printf("Starting simple POSIX open test\n");
    7656             : 
    7657           4 :         if (!torture_open_connection(&cli1, 0)) {
    7658           0 :                 return false;
    7659             :         }
    7660             : 
    7661           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    7662             : 
    7663           4 :         status = torture_setup_unix_extensions(cli1);
    7664           4 :         if (!NT_STATUS_IS_OK(status)) {
    7665           0 :                 return false;
    7666             :         }
    7667             : 
    7668           4 :         cli_setatr(cli1, fname, 0, 0);
    7669           4 :         cli_posix_unlink(cli1, fname);
    7670           4 :         cli_setatr(cli1, dname, 0, 0);
    7671           4 :         cli_posix_rmdir(cli1, dname);
    7672           4 :         cli_setatr(cli1, hname, 0, 0);
    7673           4 :         cli_posix_unlink(cli1, hname);
    7674           4 :         cli_setatr(cli1, sname, 0, 0);
    7675           4 :         cli_posix_unlink(cli1, sname);
    7676           4 :         cli_setatr(cli1, fname_windows, 0, 0);
    7677           4 :         cli_posix_unlink(cli1, fname_windows);
    7678             : 
    7679             :         /* Create a directory. */
    7680           4 :         status = cli_posix_mkdir(cli1, dname, 0777);
    7681           4 :         if (!NT_STATUS_IS_OK(status)) {
    7682           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    7683           0 :                 goto out;
    7684             :         }
    7685             : 
    7686           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    7687             :                                 0600, &fnum1);
    7688           4 :         if (!NT_STATUS_IS_OK(status)) {
    7689           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7690           0 :                 goto out;
    7691             :         }
    7692             : 
    7693             :         /* Test ftruncate - set file size. */
    7694           4 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7695           4 :         if (!NT_STATUS_IS_OK(status)) {
    7696           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7697           0 :                 goto out;
    7698             :         }
    7699             : 
    7700             :         /* Ensure st_size == 1000 */
    7701           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7702           4 :         if (!NT_STATUS_IS_OK(status)) {
    7703           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7704           0 :                 goto out;
    7705             :         }
    7706             : 
    7707           4 :         if (sbuf.st_ex_size != 1000) {
    7708           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7709           0 :                 goto out;
    7710             :         }
    7711             : 
    7712             :         /* Ensure st_mode == 0600 */
    7713           4 :         if ((sbuf.st_ex_mode & 07777) != 0600) {
    7714           0 :                 printf("posix_open - bad permissions 0%o != 0600\n",
    7715           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    7716           0 :                 goto out;
    7717             :         }
    7718             : 
    7719             :         /* Test ftruncate - set file size back to zero. */
    7720           4 :         status = cli_ftruncate(cli1, fnum1, 0);
    7721           4 :         if (!NT_STATUS_IS_OK(status)) {
    7722           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7723           0 :                 goto out;
    7724             :         }
    7725             : 
    7726           4 :         status = cli_close(cli1, fnum1);
    7727           4 :         if (!NT_STATUS_IS_OK(status)) {
    7728           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    7729           0 :                 goto out;
    7730             :         }
    7731             : 
    7732             :         /* Now open the file again for read only. */
    7733           4 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7734           4 :         if (!NT_STATUS_IS_OK(status)) {
    7735           0 :                 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
    7736           0 :                 goto out;
    7737             :         }
    7738             : 
    7739             :         /* Now unlink while open. */
    7740           4 :         status = cli_posix_unlink(cli1, fname);
    7741           4 :         if (!NT_STATUS_IS_OK(status)) {
    7742           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    7743           0 :                 goto out;
    7744             :         }
    7745             : 
    7746           4 :         status = cli_close(cli1, fnum1);
    7747           4 :         if (!NT_STATUS_IS_OK(status)) {
    7748           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7749           0 :                 goto out;
    7750             :         }
    7751             : 
    7752             :         /* Ensure the file has gone. */
    7753           4 :         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
    7754           4 :         if (NT_STATUS_IS_OK(status)) {
    7755           0 :                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
    7756           0 :                 goto out;
    7757             :         }
    7758             : 
    7759             :         /* Create again to test open with O_TRUNC. */
    7760           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
    7761           4 :         if (!NT_STATUS_IS_OK(status)) {
    7762           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7763           0 :                 goto out;
    7764             :         }
    7765             : 
    7766             :         /* Test ftruncate - set file size. */
    7767           4 :         status = cli_ftruncate(cli1, fnum1, 1000);
    7768           4 :         if (!NT_STATUS_IS_OK(status)) {
    7769           0 :                 printf("ftruncate failed (%s)\n", nt_errstr(status));
    7770           0 :                 goto out;
    7771             :         }
    7772             : 
    7773             :         /* Ensure st_size == 1000 */
    7774           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7775           4 :         if (!NT_STATUS_IS_OK(status)) {
    7776           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7777           0 :                 goto out;
    7778             :         }
    7779             : 
    7780           4 :         if (sbuf.st_ex_size != 1000) {
    7781           0 :                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
    7782           0 :                 goto out;
    7783             :         }
    7784             : 
    7785           4 :         status = cli_close(cli1, fnum1);
    7786           4 :         if (!NT_STATUS_IS_OK(status)) {
    7787           0 :                 printf("close(2) failed (%s)\n", nt_errstr(status));
    7788           0 :                 goto out;
    7789             :         }
    7790             : 
    7791             :         /* Re-open with O_TRUNC. */
    7792           4 :         status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
    7793           4 :         if (!NT_STATUS_IS_OK(status)) {
    7794           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7795           0 :                 goto out;
    7796             :         }
    7797             : 
    7798             :         /* Ensure st_size == 0 */
    7799           4 :         status = cli_posix_stat(cli1, fname, &sbuf);
    7800           4 :         if (!NT_STATUS_IS_OK(status)) {
    7801           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7802           0 :                 goto out;
    7803             :         }
    7804             : 
    7805           4 :         if (sbuf.st_ex_size != 0) {
    7806           0 :                 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
    7807           0 :                 goto out;
    7808             :         }
    7809             : 
    7810           4 :         status = cli_close(cli1, fnum1);
    7811           4 :         if (!NT_STATUS_IS_OK(status)) {
    7812           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    7813           0 :                 goto out;
    7814             :         }
    7815             : 
    7816           4 :         status = cli_posix_unlink(cli1, fname);
    7817           4 :         if (!NT_STATUS_IS_OK(status)) {
    7818           0 :                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
    7819           0 :                 goto out;
    7820             :         }
    7821             : 
    7822           4 :         status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
    7823           4 :         if (!NT_STATUS_IS_OK(status)) {
    7824           0 :                 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
    7825             :                         dname, nt_errstr(status));
    7826           0 :                 goto out;
    7827             :         }
    7828             : 
    7829           4 :         cli_close(cli1, fnum1);
    7830             : 
    7831             :         /* What happens when we try and POSIX open a directory for write ? */
    7832           4 :         status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
    7833           4 :         if (NT_STATUS_IS_OK(status)) {
    7834           0 :                 printf("POSIX open of directory %s succeeded, "
    7835             :                        "should have failed.\n",
    7836             :                        dname);
    7837           0 :                 goto out;
    7838             :         } else {
    7839           4 :                 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
    7840           4 :                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
    7841           0 :                         goto out;
    7842             :                 }
    7843             :         }
    7844             : 
    7845             :         /* Create the file. */
    7846           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    7847             :                                 0600, &fnum1);
    7848           4 :         if (!NT_STATUS_IS_OK(status)) {
    7849           0 :                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
    7850           0 :                 goto out;
    7851             :         }
    7852             : 
    7853             :         /* Write some data into it. */
    7854           4 :         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
    7855             :                               NULL);
    7856           4 :         if (!NT_STATUS_IS_OK(status)) {
    7857           0 :                 printf("cli_write failed: %s\n", nt_errstr(status));
    7858           0 :                 goto out;
    7859             :         }
    7860             : 
    7861           4 :         cli_close(cli1, fnum1);
    7862             : 
    7863             :         /* Now create a hardlink. */
    7864           4 :         status = cli_posix_hardlink(cli1, fname, hname);
    7865           4 :         if (!NT_STATUS_IS_OK(status)) {
    7866           0 :                 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
    7867           0 :                 goto out;
    7868             :         }
    7869             : 
    7870             :         /* Now create a symlink. */
    7871           4 :         status = cli_posix_symlink(cli1, fname, sname);
    7872           4 :         if (!NT_STATUS_IS_OK(status)) {
    7873           0 :                 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
    7874           0 :                 goto out;
    7875             :         }
    7876             : 
    7877             :         /* Open the hardlink for read. */
    7878           4 :         status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
    7879           4 :         if (!NT_STATUS_IS_OK(status)) {
    7880           0 :                 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
    7881           0 :                 goto out;
    7882             :         }
    7883             : 
    7884           4 :         status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
    7885           4 :         if (!NT_STATUS_IS_OK(status)) {
    7886           0 :                 printf("POSIX read of %s failed (%s)\n", hname,
    7887             :                        nt_errstr(status));
    7888           0 :                 goto out;
    7889           4 :         } else if (nread != 10) {
    7890           0 :                 printf("POSIX read of %s failed. Received %ld, expected %d\n",
    7891             :                        hname, (unsigned long)nread, 10);
    7892           0 :                 goto out;
    7893             :         }
    7894             : 
    7895           4 :         if (memcmp(buf, "TEST DATA\n", 10)) {
    7896           0 :                 printf("invalid data read from hardlink\n");
    7897           0 :                 goto out;
    7898             :         }
    7899             : 
    7900             :         /* Do a POSIX lock/unlock. */
    7901           4 :         status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
    7902           4 :         if (!NT_STATUS_IS_OK(status)) {
    7903           0 :                 printf("POSIX lock failed %s\n", nt_errstr(status));
    7904           0 :                 goto out;
    7905             :         }
    7906             : 
    7907             :         /* Punch a hole in the locked area. */
    7908           4 :         status = cli_posix_unlock(cli1, fnum1, 10, 80);
    7909           4 :         if (!NT_STATUS_IS_OK(status)) {
    7910           0 :                 printf("POSIX unlock failed %s\n", nt_errstr(status));
    7911           0 :                 goto out;
    7912             :         }
    7913             : 
    7914           4 :         cli_close(cli1, fnum1);
    7915             : 
    7916             :         /* Open the symlink for read - this should fail. A POSIX
    7917             :            client should not be doing opens on a symlink. */
    7918           4 :         status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
    7919           4 :         if (NT_STATUS_IS_OK(status)) {
    7920           0 :                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
    7921           0 :                 goto out;
    7922             :         } else {
    7923           4 :                 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
    7924           4 :                                 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    7925           0 :                         printf("POSIX open of %s should have failed "
    7926             :                                 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
    7927             :                                 "failed with %s instead.\n",
    7928             :                                 sname, nt_errstr(status));
    7929           0 :                         goto out;
    7930             :                 }
    7931             :         }
    7932             : 
    7933           4 :         status = cli_posix_readlink(cli1, sname, talloc_tos(), &target);
    7934           4 :         if (!NT_STATUS_IS_OK(status)) {
    7935           0 :                 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
    7936           0 :                 goto out;
    7937             :         }
    7938             : 
    7939           4 :         if (strcmp(target, fname) != 0) {
    7940           0 :                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
    7941             :                         sname, fname, target);
    7942           0 :                 goto out;
    7943             :         }
    7944             : 
    7945           4 :         status = cli_posix_rmdir(cli1, dname);
    7946           4 :         if (!NT_STATUS_IS_OK(status)) {
    7947           0 :                 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
    7948           0 :                 goto out;
    7949             :         }
    7950             : 
    7951             :         /* Check directory opens with a specific permission. */
    7952           4 :         status = cli_posix_mkdir(cli1, dname, 0700);
    7953           4 :         if (!NT_STATUS_IS_OK(status)) {
    7954           0 :                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
    7955           0 :                 goto out;
    7956             :         }
    7957             : 
    7958             :         /* Ensure st_mode == 0700 */
    7959           4 :         status = cli_posix_stat(cli1, dname, &sbuf);
    7960           4 :         if (!NT_STATUS_IS_OK(status)) {
    7961           0 :                 printf("stat failed (%s)\n", nt_errstr(status));
    7962           0 :                 goto out;
    7963             :         }
    7964             : 
    7965           4 :         if ((sbuf.st_ex_mode & 07777) != 0700) {
    7966           0 :                 printf("posix_mkdir - bad permissions 0%o != 0700\n",
    7967           0 :                                 (unsigned int)(sbuf.st_ex_mode & 07777));
    7968           0 :                 goto out;
    7969             :         }
    7970             : 
    7971             :         /*
    7972             :          * Now create a Windows file, and attempt a POSIX unlink.
    7973             :          * This should fail with a sharing violation but due to:
    7974             :          *
    7975             :          * [Bug 9571] Unlink after open causes smbd to panic
    7976             :          *
    7977             :          * ensure we've fixed the lock ordering violation.
    7978             :          */
    7979             : 
    7980           4 :         status = cli_ntcreate(cli1, fname_windows, 0,
    7981             :                         FILE_READ_DATA|FILE_WRITE_DATA, 0,
    7982             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    7983             :                         FILE_CREATE,
    7984             :                         0x0, 0x0, &fnum2, NULL);
    7985           4 :         if (!NT_STATUS_IS_OK(status)) {
    7986           0 :                 printf("Windows create of %s failed (%s)\n", fname_windows,
    7987             :                         nt_errstr(status));
    7988           0 :                 goto out;
    7989             :         }
    7990             : 
    7991             :         /* Now try posix_unlink. */
    7992           4 :         status = cli_posix_unlink(cli1, fname_windows);
    7993           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    7994           0 :                 printf("POSIX unlink of %s should fail "
    7995             :                         "with NT_STATUS_SHARING_VIOLATION "
    7996             :                         "got %s instead !\n",
    7997             :                         fname_windows,
    7998             :                         nt_errstr(status));
    7999           0 :                 goto out;
    8000             :         }
    8001             : 
    8002           4 :         cli_close(cli1, fnum2);
    8003             : 
    8004           4 :         printf("Simple POSIX open test passed\n");
    8005           4 :         correct = true;
    8006             : 
    8007           4 :   out:
    8008             : 
    8009           4 :         if (fnum1 != (uint16_t)-1) {
    8010           4 :                 cli_close(cli1, fnum1);
    8011           4 :                 fnum1 = (uint16_t)-1;
    8012             :         }
    8013             : 
    8014           4 :         if (fnum2 != (uint16_t)-1) {
    8015           4 :                 cli_close(cli1, fnum2);
    8016           4 :                 fnum2 = (uint16_t)-1;
    8017             :         }
    8018             : 
    8019           4 :         cli_setatr(cli1, sname, 0, 0);
    8020           4 :         cli_posix_unlink(cli1, sname);
    8021           4 :         cli_setatr(cli1, hname, 0, 0);
    8022           4 :         cli_posix_unlink(cli1, hname);
    8023           4 :         cli_setatr(cli1, fname, 0, 0);
    8024           4 :         cli_posix_unlink(cli1, fname);
    8025           4 :         cli_setatr(cli1, dname, 0, 0);
    8026           4 :         cli_posix_rmdir(cli1, dname);
    8027           4 :         cli_setatr(cli1, fname_windows, 0, 0);
    8028           4 :         cli_posix_unlink(cli1, fname_windows);
    8029             : 
    8030           4 :         if (!torture_close_connection(cli1)) {
    8031           0 :                 correct = false;
    8032             :         }
    8033             : 
    8034           4 :         return correct;
    8035             : }
    8036             : 
    8037             : /*
    8038             :   Test POSIX and Windows ACLs are rejected on symlinks.
    8039             :  */
    8040           4 : static bool run_acl_symlink_test(int dummy)
    8041             : {
    8042             :         static struct cli_state *cli;
    8043           4 :         const char *fname = "posix_file";
    8044           4 :         const char *sname = "posix_symlink";
    8045           4 :         uint16_t fnum = (uint16_t)-1;
    8046           4 :         bool correct = false;
    8047             :         NTSTATUS status;
    8048           4 :         char *posix_acl = NULL;
    8049           4 :         size_t posix_acl_len = 0;
    8050           4 :         char *posix_acl_sym = NULL;
    8051           4 :         size_t posix_acl_len_sym = 0;
    8052           4 :         struct security_descriptor *sd = NULL;
    8053           4 :         TALLOC_CTX *frame = NULL;
    8054             : 
    8055           4 :         frame = talloc_stackframe();
    8056             : 
    8057           4 :         printf("Starting acl symlink test\n");
    8058             : 
    8059           4 :         if (!torture_open_connection(&cli, 0)) {
    8060           0 :                 TALLOC_FREE(frame);
    8061           0 :                 return false;
    8062             :         }
    8063             : 
    8064           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8065             : 
    8066           4 :         status = torture_setup_unix_extensions(cli);
    8067           4 :         if (!NT_STATUS_IS_OK(status)) {
    8068           0 :                 TALLOC_FREE(frame);
    8069           0 :                 return false;
    8070             :         }
    8071             : 
    8072           4 :         cli_setatr(cli, fname, 0, 0);
    8073           4 :         cli_posix_unlink(cli, fname);
    8074           4 :         cli_setatr(cli, sname, 0, 0);
    8075           4 :         cli_posix_unlink(cli, sname);
    8076             : 
    8077           4 :         status = cli_ntcreate(cli,
    8078             :                         fname,
    8079             :                         0,
    8080             :                         READ_CONTROL_ACCESS,
    8081             :                         0,
    8082             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8083             :                         FILE_CREATE,
    8084             :                         0x0,
    8085             :                         0x0,
    8086             :                         &fnum,
    8087             :                         NULL);
    8088             : 
    8089           4 :         if (!NT_STATUS_IS_OK(status)) {
    8090           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8091             :                         fname,
    8092             :                         nt_errstr(status));
    8093           0 :                 goto out;
    8094             :         }
    8095             : 
    8096             :         /* Get the Windows ACL on the file. */
    8097           4 :         status = cli_query_secdesc(cli,
    8098             :                                 fnum,
    8099             :                                 frame,
    8100             :                                 &sd);
    8101           4 :         if (!NT_STATUS_IS_OK(status)) {
    8102           0 :                 printf("cli_query_secdesc failed (%s)\n",
    8103             :                         nt_errstr(status));
    8104           0 :                 goto out;
    8105             :         }
    8106             : 
    8107             :         /* Get the POSIX ACL on the file. */
    8108           4 :         status = cli_posix_getacl(cli,
    8109             :                                 fname,
    8110             :                                 frame,
    8111             :                                 &posix_acl_len,
    8112             :                                 &posix_acl);
    8113             : 
    8114           4 :         if (!NT_STATUS_IS_OK(status)) {
    8115           0 :                 printf("cli_posix_getacl failed (%s)\n",
    8116             :                         nt_errstr(status));
    8117           0 :                 goto out;
    8118             :         }
    8119             : 
    8120           4 :         status = cli_close(cli, fnum);
    8121           4 :         if (!NT_STATUS_IS_OK(status)) {
    8122           0 :                 printf("close failed (%s)\n", nt_errstr(status));
    8123           0 :                 goto out;
    8124             :         }
    8125           4 :         fnum = (uint16_t)-1;
    8126             : 
    8127             :         /* Now create a symlink. */
    8128           4 :         status = cli_posix_symlink(cli, fname, sname);
    8129           4 :         if (!NT_STATUS_IS_OK(status)) {
    8130           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8131             :                         sname,
    8132             :                         fname,
    8133             :                         nt_errstr(status));
    8134           0 :                 goto out;
    8135             :         }
    8136             : 
    8137             :         /* Open a handle on the symlink for SD set/get should fail. */
    8138           4 :         status = cli_ntcreate(cli,
    8139             :                         sname,
    8140             :                         0,
    8141             :                         READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
    8142             :                         0,
    8143             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8144             :                         FILE_OPEN,
    8145             :                         0x0,
    8146             :                         0x0,
    8147             :                         &fnum,
    8148             :                         NULL);
    8149             : 
    8150           4 :         if (NT_STATUS_IS_OK(status)) {
    8151           0 :                 printf("Symlink open for getsd/setsd of %s "
    8152             :                         "succeeded (should fail)\n",
    8153             :                         sname);
    8154           0 :                 goto out;
    8155             :         }
    8156             : 
    8157             :         /* Try a stat-open on the symlink, should also fail. */
    8158           4 :         status = cli_ntcreate(cli,
    8159             :                         sname,
    8160             :                         0,
    8161             :                         FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES,
    8162             :                         0,
    8163             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8164             :                         FILE_OPEN,
    8165             :                         0x0,
    8166             :                         0x0,
    8167             :                         &fnum,
    8168             :                         NULL);
    8169             : 
    8170           4 :         if (NT_STATUS_IS_OK(status)) {
    8171           0 :                 printf("Stat-open of symlink succeeded (should fail)\n");
    8172           0 :                 goto out;
    8173             :         }
    8174             : 
    8175             :         /* Get the POSIX ACL on the symlink pathname. Should fail. */
    8176           4 :         status = cli_posix_getacl(cli,
    8177             :                                 sname,
    8178             :                                 frame,
    8179             :                                 &posix_acl_len_sym,
    8180             :                                 &posix_acl_sym);
    8181             : 
    8182           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8183           0 :                 printf("cli_posix_getacl on a symlink gave %s. "
    8184             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8185             :                         nt_errstr(status));
    8186           0 :                 goto out;
    8187             :         }
    8188             : 
    8189             :         /* Set the POSIX ACL on the symlink pathname. Should fail. */
    8190           4 :         status = cli_posix_setacl(cli,
    8191             :                                 sname,
    8192             :                                 posix_acl,
    8193             :                                 posix_acl_len);
    8194             : 
    8195           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8196           0 :                 printf("cli_posix_setacl on a symlink gave %s. "
    8197             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8198             :                         nt_errstr(status));
    8199           0 :                 goto out;
    8200             :         }
    8201             : 
    8202           4 :         printf("ACL symlink test passed\n");
    8203           4 :         correct = true;
    8204             : 
    8205           4 :   out:
    8206             : 
    8207           4 :         if (fnum != (uint16_t)-1) {
    8208           0 :                 cli_close(cli, fnum);
    8209           0 :                 fnum = (uint16_t)-1;
    8210             :         }
    8211             : 
    8212           4 :         cli_setatr(cli, sname, 0, 0);
    8213           4 :         cli_posix_unlink(cli, sname);
    8214           4 :         cli_setatr(cli, fname, 0, 0);
    8215           4 :         cli_posix_unlink(cli, fname);
    8216             : 
    8217           4 :         if (!torture_close_connection(cli)) {
    8218           0 :                 correct = false;
    8219             :         }
    8220             : 
    8221           4 :         TALLOC_FREE(frame);
    8222           4 :         return correct;
    8223             : }
    8224             : 
    8225             : /*
    8226             :   Test POSIX can delete a file containing streams.
    8227             :  */
    8228           4 : static bool run_posix_stream_delete(int dummy)
    8229             : {
    8230           4 :         struct cli_state *cli1 = NULL;
    8231           4 :         struct cli_state *cli2 = NULL;
    8232           4 :         const char *fname = "streamfile";
    8233           4 :         const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
    8234           4 :         uint16_t fnum1 = (uint16_t)-1;
    8235           4 :         bool correct = false;
    8236             :         NTSTATUS status;
    8237           4 :         TALLOC_CTX *frame = NULL;
    8238             : 
    8239           4 :         frame = talloc_stackframe();
    8240             : 
    8241           4 :         printf("Starting POSIX stream delete test\n");
    8242             : 
    8243           8 :         if (!torture_open_connection(&cli1, 0) ||
    8244           4 :                         !torture_open_connection(&cli2, 1)) {
    8245           0 :                 TALLOC_FREE(frame);
    8246           0 :                 return false;
    8247             :         }
    8248             : 
    8249           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    8250           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    8251             : 
    8252           4 :         status = torture_setup_unix_extensions(cli2);
    8253           4 :         if (!NT_STATUS_IS_OK(status)) {
    8254           0 :                 goto out;
    8255             :         }
    8256             : 
    8257           4 :         cli_setatr(cli1, fname, 0, 0);
    8258           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8259             : 
    8260             :         /* Create the file. */
    8261           4 :         status = cli_ntcreate(cli1,
    8262             :                         fname,
    8263             :                         0,
    8264             :                         READ_CONTROL_ACCESS,
    8265             :                         0,
    8266             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8267             :                         FILE_CREATE,
    8268             :                         0x0,
    8269             :                         0x0,
    8270             :                         &fnum1,
    8271             :                         NULL);
    8272             : 
    8273           4 :         if (!NT_STATUS_IS_OK(status)) {
    8274           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8275             :                         fname,
    8276             :                         nt_errstr(status));
    8277           0 :                 goto out;
    8278             :         }
    8279             : 
    8280           4 :         status = cli_close(cli1, fnum1);
    8281           4 :         if (!NT_STATUS_IS_OK(status)) {
    8282           0 :                 printf("cli_close of %s failed (%s)\n",
    8283             :                         fname,
    8284             :                         nt_errstr(status));
    8285           0 :                 goto out;
    8286             :         }
    8287           4 :         fnum1 = (uint16_t)-1;
    8288             : 
    8289             :         /* Now create the stream. */
    8290           4 :         status = cli_ntcreate(cli1,
    8291             :                         stream_fname,
    8292             :                         0,
    8293             :                         FILE_WRITE_DATA,
    8294             :                         0,
    8295             :                         FILE_SHARE_READ|FILE_SHARE_WRITE,
    8296             :                         FILE_CREATE,
    8297             :                         0x0,
    8298             :                         0x0,
    8299             :                         &fnum1,
    8300             :                         NULL);
    8301             : 
    8302           4 :         if (!NT_STATUS_IS_OK(status)) {
    8303           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8304             :                         stream_fname,
    8305             :                         nt_errstr(status));
    8306           0 :                 goto out;
    8307             :         }
    8308             : 
    8309             :         /* Leave the stream handle open... */
    8310             : 
    8311             :         /* POSIX unlink should fail. */
    8312           4 :         status = cli_posix_unlink(cli2, fname);
    8313           4 :         if (NT_STATUS_IS_OK(status)) {
    8314           0 :                 printf("cli_posix_unlink of %s succeeded, should have failed\n",
    8315             :                         fname);
    8316           0 :                 goto out;
    8317             :         }
    8318             : 
    8319           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    8320           0 :                 printf("cli_posix_unlink of %s failed with (%s) "
    8321             :                         "should have been NT_STATUS_SHARING_VIOLATION\n",
    8322             :                         fname,
    8323             :                         nt_errstr(status));
    8324           0 :                 goto out;
    8325             :         }
    8326             : 
    8327             :         /* Close the stream handle. */
    8328           4 :         status = cli_close(cli1, fnum1);
    8329           4 :         if (!NT_STATUS_IS_OK(status)) {
    8330           0 :                 printf("cli_close of %s failed (%s)\n",
    8331             :                         stream_fname,
    8332             :                         nt_errstr(status));
    8333           0 :                 goto out;
    8334             :         }
    8335           4 :         fnum1 = (uint16_t)-1;
    8336             : 
    8337             :         /* POSIX unlink after stream handle closed should succeed. */
    8338           4 :         status = cli_posix_unlink(cli2, fname);
    8339           4 :         if (!NT_STATUS_IS_OK(status)) {
    8340           0 :                 printf("cli_posix_unlink of %s failed (%s)\n",
    8341             :                         fname,
    8342             :                         nt_errstr(status));
    8343           0 :                 goto out;
    8344             :         }
    8345             : 
    8346           4 :         printf("POSIX stream delete test passed\n");
    8347           4 :         correct = true;
    8348             : 
    8349           4 :   out:
    8350             : 
    8351           4 :         if (fnum1 != (uint16_t)-1) {
    8352           0 :                 cli_close(cli1, fnum1);
    8353           0 :                 fnum1 = (uint16_t)-1;
    8354             :         }
    8355             : 
    8356           4 :         cli_setatr(cli1, fname, 0, 0);
    8357           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    8358             : 
    8359           4 :         if (!torture_close_connection(cli1)) {
    8360           0 :                 correct = false;
    8361             :         }
    8362           4 :         if (!torture_close_connection(cli2)) {
    8363           0 :                 correct = false;
    8364             :         }
    8365             : 
    8366           4 :         TALLOC_FREE(frame);
    8367           4 :         return correct;
    8368             : }
    8369             : 
    8370             : /*
    8371             :   Test setting EA's are rejected on symlinks.
    8372             :  */
    8373           4 : static bool run_ea_symlink_test(int dummy)
    8374             : {
    8375             :         static struct cli_state *cli;
    8376           4 :         const char *fname = "posix_file_ea";
    8377           4 :         const char *sname = "posix_symlink_ea";
    8378           4 :         const char *ea_name = "testea_name";
    8379           4 :         const char *ea_value = "testea_value";
    8380           4 :         uint16_t fnum = (uint16_t)-1;
    8381           4 :         bool correct = false;
    8382             :         NTSTATUS status;
    8383             :         size_t i, num_eas;
    8384           4 :         struct ea_struct *eas = NULL;
    8385           4 :         TALLOC_CTX *frame = NULL;
    8386             : 
    8387           4 :         frame = talloc_stackframe();
    8388             : 
    8389           4 :         printf("Starting EA symlink test\n");
    8390             : 
    8391           4 :         if (!torture_open_connection(&cli, 0)) {
    8392           0 :                 TALLOC_FREE(frame);
    8393           0 :                 return false;
    8394             :         }
    8395             : 
    8396           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8397             : 
    8398           4 :         status = torture_setup_unix_extensions(cli);
    8399           4 :         if (!NT_STATUS_IS_OK(status)) {
    8400           0 :                 TALLOC_FREE(frame);
    8401           0 :                 return false;
    8402             :         }
    8403             : 
    8404           4 :         cli_setatr(cli, fname, 0, 0);
    8405           4 :         cli_posix_unlink(cli, fname);
    8406           4 :         cli_setatr(cli, sname, 0, 0);
    8407           4 :         cli_posix_unlink(cli, sname);
    8408             : 
    8409           4 :         status = cli_ntcreate(cli,
    8410             :                         fname,
    8411             :                         0,
    8412             :                         READ_CONTROL_ACCESS,
    8413             :                         0,
    8414             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    8415             :                         FILE_CREATE,
    8416             :                         0x0,
    8417             :                         0x0,
    8418             :                         &fnum,
    8419             :                         NULL);
    8420             : 
    8421           4 :         if (!NT_STATUS_IS_OK(status)) {
    8422           0 :                 printf("cli_ntcreate of %s failed (%s)\n",
    8423             :                         fname,
    8424             :                         nt_errstr(status));
    8425           0 :                 goto out;
    8426             :         }
    8427             : 
    8428           4 :         status = cli_close(cli, fnum);
    8429           4 :         if (!NT_STATUS_IS_OK(status)) {
    8430           0 :                 printf("close failed (%s)\n",
    8431             :                         nt_errstr(status));
    8432           0 :                 goto out;
    8433             :         }
    8434           4 :         fnum = (uint16_t)-1;
    8435             : 
    8436             :         /* Set an EA on the path. */
    8437           4 :         status = cli_set_ea_path(cli,
    8438             :                                 fname,
    8439             :                                 ea_name,
    8440             :                                 ea_value,
    8441           4 :                                 strlen(ea_value)+1);
    8442             : 
    8443           4 :         if (!NT_STATUS_IS_OK(status)) {
    8444           0 :                 printf("cli_set_ea_path failed (%s)\n",
    8445             :                         nt_errstr(status));
    8446           0 :                 goto out;
    8447             :         }
    8448             : 
    8449             :         /* Now create a symlink. */
    8450           4 :         status = cli_posix_symlink(cli, fname, sname);
    8451           4 :         if (!NT_STATUS_IS_OK(status)) {
    8452           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
    8453             :                         sname,
    8454             :                         fname,
    8455             :                         nt_errstr(status));
    8456           0 :                 goto out;
    8457             :         }
    8458             : 
    8459             :         /* Get the EA list on the path. Should return value set. */
    8460           4 :         status = cli_get_ea_list_path(cli,
    8461             :                                 fname,
    8462             :                                 frame,
    8463             :                                 &num_eas,
    8464             :                                 &eas);
    8465             : 
    8466           4 :         if (!NT_STATUS_IS_OK(status)) {
    8467           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8468             :                         nt_errstr(status));
    8469           0 :                 goto out;
    8470             :         }
    8471             : 
    8472             :         /* Ensure the EA we set is there. */
    8473           4 :         for (i=0; i<num_eas; i++) {
    8474           8 :                 if (strcmp(eas[i].name, ea_name) == 0 &&
    8475           8 :                                 eas[i].value.length == strlen(ea_value)+1 &&
    8476           4 :                                 memcmp(eas[i].value.data,
    8477             :                                         ea_value,
    8478           4 :                                         eas[i].value.length) == 0) {
    8479           4 :                         break;
    8480             :                 }
    8481             :         }
    8482             : 
    8483           4 :         if (i == num_eas) {
    8484           0 :                 printf("Didn't find EA on pathname %s\n",
    8485             :                         fname);
    8486           0 :                 goto out;
    8487             :         }
    8488             : 
    8489           4 :         num_eas = 0;
    8490           4 :         TALLOC_FREE(eas);
    8491             : 
    8492             :         /* Get the EA list on the symlink. Should return empty list. */
    8493           4 :         status = cli_get_ea_list_path(cli,
    8494             :                                 sname,
    8495             :                                 frame,
    8496             :                                 &num_eas,
    8497             :                                 &eas);
    8498             : 
    8499           4 :         if (!NT_STATUS_IS_OK(status)) {
    8500           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8501             :                         nt_errstr(status));
    8502           0 :                 goto out;
    8503             :         }
    8504             : 
    8505           4 :         if (num_eas != 0) {
    8506           0 :                 printf("cli_get_ea_list_path failed (%s)\n",
    8507             :                         nt_errstr(status));
    8508           0 :                 goto out;
    8509             :         }
    8510             : 
    8511             :         /* Set an EA on the symlink. Should fail. */
    8512           4 :         status = cli_set_ea_path(cli,
    8513             :                                 sname,
    8514             :                                 ea_name,
    8515             :                                 ea_value,
    8516           4 :                                 strlen(ea_value)+1);
    8517             : 
    8518           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    8519           0 :                 printf("cli_set_ea_path on a symlink gave %s. "
    8520             :                         "Should be NT_STATUS_ACCESS_DENIED.\n",
    8521             :                         nt_errstr(status));
    8522           0 :                 goto out;
    8523             :         }
    8524             : 
    8525           4 :         printf("EA symlink test passed\n");
    8526           4 :         correct = true;
    8527             : 
    8528           4 :   out:
    8529             : 
    8530           4 :         if (fnum != (uint16_t)-1) {
    8531           0 :                 cli_close(cli, fnum);
    8532           0 :                 fnum = (uint16_t)-1;
    8533             :         }
    8534             : 
    8535           4 :         cli_setatr(cli, sname, 0, 0);
    8536           4 :         cli_posix_unlink(cli, sname);
    8537           4 :         cli_setatr(cli, fname, 0, 0);
    8538           4 :         cli_posix_unlink(cli, fname);
    8539             : 
    8540           4 :         if (!torture_close_connection(cli)) {
    8541           0 :                 correct = false;
    8542             :         }
    8543             : 
    8544           4 :         TALLOC_FREE(frame);
    8545           4 :         return correct;
    8546             : }
    8547             : 
    8548             : /*
    8549             :   Test POSIX locks are OFD-locks.
    8550             :  */
    8551           4 : static bool run_posix_ofd_lock_test(int dummy)
    8552             : {
    8553             :         static struct cli_state *cli;
    8554           4 :         const char *fname = "posix_file";
    8555           4 :         uint16_t fnum1 = (uint16_t)-1;
    8556           4 :         uint16_t fnum2 = (uint16_t)-1;
    8557           4 :         bool correct = false;
    8558             :         NTSTATUS status;
    8559           4 :         TALLOC_CTX *frame = NULL;
    8560             : 
    8561           4 :         frame = talloc_stackframe();
    8562             : 
    8563           4 :         printf("Starting POSIX ofd-lock test\n");
    8564             : 
    8565           4 :         if (!torture_open_connection(&cli, 0)) {
    8566           0 :                 TALLOC_FREE(frame);
    8567           0 :                 return false;
    8568             :         }
    8569             : 
    8570           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8571             : 
    8572           4 :         status = torture_setup_unix_extensions(cli);
    8573           4 :         if (!NT_STATUS_IS_OK(status)) {
    8574           0 :                 TALLOC_FREE(frame);
    8575           0 :                 return false;
    8576             :         }
    8577             : 
    8578           4 :         cli_setatr(cli, fname, 0, 0);
    8579           4 :         cli_posix_unlink(cli, fname);
    8580             : 
    8581             :         /* Open the file twice. */
    8582           4 :         status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
    8583             :                                 0600, &fnum1);
    8584           4 :         if (!NT_STATUS_IS_OK(status)) {
    8585           0 :                 printf("First POSIX open of %s failed\n", fname);
    8586           0 :                 goto out;
    8587             :         }
    8588             : 
    8589           4 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
    8590           4 :         if (!NT_STATUS_IS_OK(status)) {
    8591           0 :                 printf("First POSIX open of %s failed\n", fname);
    8592           0 :                 goto out;
    8593             :         }
    8594             : 
    8595             :         /* Set a 0-50 lock on fnum1. */
    8596           4 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8597           4 :         if (!NT_STATUS_IS_OK(status)) {
    8598           0 :                 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
    8599           0 :                 goto out;
    8600             :         }
    8601             : 
    8602             :         /* Set a 60-100 lock on fnum2. */
    8603           4 :         status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
    8604           4 :         if (!NT_STATUS_IS_OK(status)) {
    8605           0 :                 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
    8606           0 :                 goto out;
    8607             :         }
    8608             : 
    8609             :         /* close fnum1 - 0-50 lock should go away. */
    8610           4 :         status = cli_close(cli, fnum1);
    8611           4 :         if (!NT_STATUS_IS_OK(status)) {
    8612           0 :                 printf("close failed (%s)\n",
    8613             :                         nt_errstr(status));
    8614           0 :                 goto out;
    8615             :         }
    8616           4 :         fnum1 = (uint16_t)-1;
    8617             : 
    8618             :         /* Change the lock context. */
    8619           4 :         cli_setpid(cli, cli_getpid(cli) + 1);
    8620             : 
    8621             :         /* Re-open fnum1. */
    8622           4 :         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
    8623           4 :         if (!NT_STATUS_IS_OK(status)) {
    8624           0 :                 printf("Third POSIX open of %s failed\n", fname);
    8625           0 :                 goto out;
    8626             :         }
    8627             : 
    8628             :         /* 60-100 lock should still be there. */
    8629           4 :         status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
    8630           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
    8631           0 :                 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
    8632           0 :                 goto out;
    8633             :         }
    8634             : 
    8635             :         /* 0-50 lock should be gone. */
    8636           4 :         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
    8637           4 :         if (!NT_STATUS_IS_OK(status)) {
    8638           0 :                 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
    8639           0 :                 goto out;
    8640             :         }
    8641             : 
    8642           4 :         printf("POSIX OFD lock test passed\n");
    8643           4 :         correct = true;
    8644             : 
    8645           4 :   out:
    8646             : 
    8647           4 :         if (fnum1 != (uint16_t)-1) {
    8648           4 :                 cli_close(cli, fnum1);
    8649           4 :                 fnum1 = (uint16_t)-1;
    8650             :         }
    8651           4 :         if (fnum2 != (uint16_t)-1) {
    8652           4 :                 cli_close(cli, fnum2);
    8653           4 :                 fnum2 = (uint16_t)-1;
    8654             :         }
    8655             : 
    8656           4 :         cli_setatr(cli, fname, 0, 0);
    8657           4 :         cli_posix_unlink(cli, fname);
    8658             : 
    8659           4 :         if (!torture_close_connection(cli)) {
    8660           0 :                 correct = false;
    8661             :         }
    8662             : 
    8663           4 :         TALLOC_FREE(frame);
    8664           4 :         return correct;
    8665             : }
    8666             : 
    8667             : struct posix_blocking_state {
    8668             :         struct tevent_context *ev;
    8669             :         struct cli_state *cli1;
    8670             :         uint16_t fnum1;
    8671             :         struct cli_state *cli2;
    8672             :         uint16_t fnum2;
    8673             :         bool gotblocked;
    8674             :         bool gotecho;
    8675             : };
    8676             : 
    8677             : static void posix_blocking_locked(struct tevent_req *subreq);
    8678             : static void posix_blocking_gotblocked(struct tevent_req *subreq);
    8679             : static void posix_blocking_gotecho(struct tevent_req *subreq);
    8680             : static void posix_blocking_unlocked(struct tevent_req *subreq);
    8681             : 
    8682           4 : static struct tevent_req *posix_blocking_send(
    8683             :         TALLOC_CTX *mem_ctx,
    8684             :         struct tevent_context *ev,
    8685             :         struct cli_state *cli1,
    8686             :         uint16_t fnum1,
    8687             :         struct cli_state *cli2,
    8688             :         uint16_t fnum2)
    8689             : {
    8690           4 :         struct tevent_req *req = NULL, *subreq = NULL;
    8691           4 :         struct posix_blocking_state *state = NULL;
    8692             : 
    8693           4 :         req = tevent_req_create(mem_ctx, &state, struct posix_blocking_state);
    8694           4 :         if (req == NULL) {
    8695           0 :                 return NULL;
    8696             :         }
    8697           4 :         state->ev = ev;
    8698           4 :         state->cli1 = cli1;
    8699           4 :         state->fnum1 = fnum1;
    8700           4 :         state->cli2 = cli2;
    8701           4 :         state->fnum2 = fnum2;
    8702             : 
    8703          12 :         subreq = cli_posix_lock_send(
    8704             :                 state,
    8705           4 :                 state->ev,
    8706           4 :                 state->cli1,
    8707           4 :                 state->fnum1,
    8708             :                 0,
    8709             :                 1,
    8710             :                 false,
    8711             :                 WRITE_LOCK);
    8712           4 :         if (tevent_req_nomem(subreq, req)) {
    8713           0 :                 return tevent_req_post(req, ev);
    8714             :         }
    8715           4 :         tevent_req_set_callback(subreq, posix_blocking_locked, req);
    8716           4 :         return req;
    8717             : }
    8718             : 
    8719           4 : static void posix_blocking_locked(struct tevent_req *subreq)
    8720             : {
    8721           4 :         struct tevent_req *req = tevent_req_callback_data(
    8722             :                 subreq, struct tevent_req);
    8723           4 :         struct posix_blocking_state *state = tevent_req_data(
    8724             :                 req, struct posix_blocking_state);
    8725             :         NTSTATUS status;
    8726             : 
    8727           4 :         status = cli_posix_lock_recv(subreq);
    8728           4 :         TALLOC_FREE(subreq);
    8729           4 :         if (tevent_req_nterror(req, status)) {
    8730           0 :                 return;
    8731             :         }
    8732             : 
    8733           4 :         subreq = cli_posix_lock_send(
    8734             :                 state,
    8735             :                 state->ev,
    8736             :                 state->cli2,
    8737           4 :                 state->fnum2,
    8738             :                 0,
    8739             :                 1,
    8740             :                 true,
    8741             :                 WRITE_LOCK);
    8742           4 :         if (tevent_req_nomem(subreq, req)) {
    8743           0 :                 return;
    8744             :         }
    8745           4 :         tevent_req_set_callback(subreq, posix_blocking_gotblocked, req);
    8746             : 
    8747             :         /* Make sure the blocking request is delivered */
    8748           4 :         subreq = cli_echo_send(
    8749             :                 state,
    8750             :                 state->ev,
    8751             :                 state->cli2,
    8752             :                 1,
    8753           4 :                 (DATA_BLOB) { .data = (uint8_t *)state, .length = 1 });
    8754           4 :         if (tevent_req_nomem(subreq, req)) {
    8755           0 :                 return;
    8756             :         }
    8757           4 :         tevent_req_set_callback(subreq, posix_blocking_gotecho, req);
    8758             : }
    8759             : 
    8760           4 : static void posix_blocking_gotblocked(struct tevent_req *subreq)
    8761             : {
    8762           4 :         struct tevent_req *req = tevent_req_callback_data(
    8763             :                 subreq, struct tevent_req);
    8764           4 :         struct posix_blocking_state *state = tevent_req_data(
    8765             :                 req, struct posix_blocking_state);
    8766             :         NTSTATUS status;
    8767             : 
    8768           4 :         status = cli_posix_lock_recv(subreq);
    8769           4 :         TALLOC_FREE(subreq);
    8770           4 :         if (tevent_req_nterror(req, status)) {
    8771           0 :                 return;
    8772             :         }
    8773           4 :         if (!state->gotecho) {
    8774           0 :                 printf("blocked req got through before echo\n");
    8775           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    8776           0 :                 return;
    8777             :         }
    8778           4 :         tevent_req_done(req);
    8779             : }
    8780             : 
    8781           4 : static void posix_blocking_gotecho(struct tevent_req *subreq)
    8782             : {
    8783           4 :         struct tevent_req *req = tevent_req_callback_data(
    8784             :                 subreq, struct tevent_req);
    8785           4 :         struct posix_blocking_state *state = tevent_req_data(
    8786             :                 req, struct posix_blocking_state);
    8787             :         NTSTATUS status;
    8788             : 
    8789           4 :         status = cli_echo_recv(subreq);
    8790           4 :         TALLOC_FREE(subreq);
    8791           4 :         if (tevent_req_nterror(req, status)) {
    8792           0 :                 return;
    8793             :         }
    8794           4 :         if (state->gotblocked) {
    8795           0 :                 printf("blocked req got through before echo\n");
    8796           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
    8797           0 :                 return;
    8798             :         }
    8799           4 :         state->gotecho = true;
    8800             : 
    8801           4 :         subreq = cli_posix_lock_send(
    8802             :                 state,
    8803             :                 state->ev,
    8804             :                 state->cli1,
    8805           4 :                 state->fnum1,
    8806             :                 0,
    8807             :                 1,
    8808             :                 false,
    8809             :                 UNLOCK_LOCK);
    8810           4 :         if (tevent_req_nomem(subreq, req)) {
    8811           0 :                 return;
    8812             :         }
    8813           4 :         tevent_req_set_callback(subreq, posix_blocking_unlocked, req);
    8814             : }
    8815             : 
    8816           4 : static void posix_blocking_unlocked(struct tevent_req *subreq)
    8817             : {
    8818           4 :         struct tevent_req *req = tevent_req_callback_data(
    8819             :                 subreq, struct tevent_req);
    8820             :         NTSTATUS status;
    8821             : 
    8822           4 :         status = cli_posix_lock_recv(subreq);
    8823           4 :         TALLOC_FREE(subreq);
    8824           4 :         if (tevent_req_nterror(req, status)) {
    8825           0 :                 return;
    8826             :         }
    8827             :         /* tevent_req_done in posix_blocking_gotlocked */
    8828             : }
    8829             : 
    8830           4 : static NTSTATUS posix_blocking_recv(struct tevent_req *req)
    8831             : {
    8832           4 :         return tevent_req_simple_recv_ntstatus(req);
    8833             : }
    8834             : 
    8835           4 : static bool run_posix_blocking_lock(int dummy)
    8836             : {
    8837           4 :         struct tevent_context *ev = NULL;
    8838           4 :         struct cli_state *cli1 = NULL, *cli2 = NULL;
    8839           4 :         const char *fname = "posix_blocking";
    8840           4 :         uint16_t fnum1 = UINT16_MAX, fnum2 = UINT16_MAX;
    8841           4 :         struct tevent_req *req = NULL;
    8842             :         NTSTATUS status;
    8843           4 :         bool ret = false;
    8844             :         bool ok;
    8845             : 
    8846           4 :         printf("Starting posix blocking lock test\n");
    8847             : 
    8848           4 :         ev = samba_tevent_context_init(NULL);
    8849           4 :         if (ev == NULL) {
    8850           0 :                 return false;
    8851             :         }
    8852             : 
    8853           4 :         ok = torture_open_connection(&cli1, 0);
    8854           4 :         if (!ok) {
    8855           0 :                 goto fail;
    8856             :         }
    8857           4 :         ok = torture_open_connection(&cli2, 0);
    8858           4 :         if (!ok) {
    8859           0 :                 goto fail;
    8860             :         }
    8861             : 
    8862           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    8863             : 
    8864           4 :         status = torture_setup_unix_extensions(cli1);
    8865           4 :         if (!NT_STATUS_IS_OK(status)) {
    8866           0 :                 return false;
    8867             :         }
    8868             : 
    8869           4 :         cli_setatr(cli1, fname, 0, 0);
    8870           4 :         cli_posix_unlink(cli1, fname);
    8871             : 
    8872           4 :         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
    8873             :                                 0600, &fnum1);
    8874           4 :         if (!NT_STATUS_IS_OK(status)) {
    8875           0 :                 printf("First POSIX open of %s failed: %s\n",
    8876             :                        fname,
    8877             :                        nt_errstr(status));
    8878           0 :                 goto fail;
    8879             :         }
    8880             : 
    8881           4 :         status = cli_posix_open(cli2, fname, O_RDWR, 0600, &fnum2);
    8882           4 :         if (!NT_STATUS_IS_OK(status)) {
    8883           0 :                 printf("Second POSIX open of %s failed: %s\n",
    8884             :                        fname,
    8885             :                        nt_errstr(status));
    8886           0 :                 goto fail;
    8887             :         }
    8888             : 
    8889           4 :         req = posix_blocking_send(ev, ev, cli1, fnum1, cli2, fnum2);
    8890           4 :         if (req == NULL) {
    8891           0 :                 printf("cli_posix_blocking failed\n");
    8892           0 :                 goto fail;
    8893             :         }
    8894             : 
    8895           4 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
    8896           4 :         if (!ok) {
    8897           0 :                 printf("tevent_req_poll_ntstatus failed: %s\n",
    8898             :                        nt_errstr(status));
    8899           0 :                 goto fail;
    8900             :         }
    8901           4 :         status = posix_blocking_recv(req);
    8902           4 :         TALLOC_FREE(req);
    8903           4 :         if (!NT_STATUS_IS_OK(status)) {
    8904           0 :                 printf("posix_blocking_recv returned %s\n",
    8905             :                        nt_errstr(status));
    8906           0 :                 goto fail;
    8907             :         }
    8908             : 
    8909           4 :         ret = true;
    8910           4 : fail:
    8911             : 
    8912           4 :         if (fnum1 != UINT16_MAX) {
    8913           4 :                 cli_close(cli1, fnum1);
    8914           4 :                 fnum1 = UINT16_MAX;
    8915             :         }
    8916           4 :         if (fnum2 != UINT16_MAX) {
    8917           4 :                 cli_close(cli2, fnum2);
    8918           4 :                 fnum2 = UINT16_MAX;
    8919             :         }
    8920             : 
    8921           4 :         if (cli1 != NULL) {
    8922           4 :                 cli_setatr(cli1, fname, 0, 0);
    8923           4 :                 cli_posix_unlink(cli1, fname);
    8924             :         }
    8925             : 
    8926           4 :         ok = true;
    8927             : 
    8928           4 :         if (cli1 != NULL) {
    8929           4 :                 ok &= torture_close_connection(cli1);
    8930           4 :                 cli1 = NULL;
    8931             :         }
    8932           4 :         if (cli2 != NULL) {
    8933           4 :                 ok &= torture_close_connection(cli2);
    8934           4 :                 cli2 = NULL;
    8935             :         }
    8936             : 
    8937           4 :         if (!ok) {
    8938           0 :                 ret = false;
    8939             :         }
    8940           4 :         TALLOC_FREE(ev);
    8941           4 :         return ret;
    8942             : }
    8943             : 
    8944             : /*
    8945             :   Test POSIX mkdir is case-sensitive.
    8946             :  */
    8947           4 : static bool run_posix_mkdir_test(int dummy)
    8948             : {
    8949             :         static struct cli_state *cli;
    8950           4 :         const char *fname_foo = "POSIX_foo";
    8951           4 :         const char *fname_foo_Foo = "POSIX_foo/Foo";
    8952           4 :         const char *fname_foo_foo = "POSIX_foo/foo";
    8953           4 :         const char *fname_Foo = "POSIX_Foo";
    8954           4 :         const char *fname_Foo_Foo = "POSIX_Foo/Foo";
    8955           4 :         const char *fname_Foo_foo = "POSIX_Foo/foo";
    8956           4 :         bool correct = false;
    8957             :         NTSTATUS status;
    8958           4 :         TALLOC_CTX *frame = NULL;
    8959           4 :         uint16_t fnum = (uint16_t)-1;
    8960             : 
    8961           4 :         frame = talloc_stackframe();
    8962             : 
    8963           4 :         printf("Starting POSIX mkdir test\n");
    8964             : 
    8965           4 :         if (!torture_open_connection(&cli, 0)) {
    8966           0 :                 TALLOC_FREE(frame);
    8967           0 :                 return false;
    8968             :         }
    8969             : 
    8970           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    8971             : 
    8972           4 :         status = torture_setup_unix_extensions(cli);
    8973           4 :         if (!NT_STATUS_IS_OK(status)) {
    8974           0 :                 TALLOC_FREE(frame);
    8975           0 :                 return false;
    8976             :         }
    8977             : 
    8978           4 :         cli_posix_rmdir(cli, fname_foo_foo);
    8979           4 :         cli_posix_rmdir(cli, fname_foo_Foo);
    8980           4 :         cli_posix_rmdir(cli, fname_foo);
    8981             : 
    8982           4 :         cli_posix_rmdir(cli, fname_Foo_foo);
    8983           4 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    8984           4 :         cli_posix_rmdir(cli, fname_Foo);
    8985             : 
    8986             :         /*
    8987             :          * Create a file POSIX_foo then try
    8988             :          * and use it in a directory path by
    8989             :          * doing mkdir POSIX_foo/bar.
    8990             :          * The mkdir should fail with
    8991             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND
    8992             :          */
    8993             : 
    8994           4 :         status = cli_posix_open(cli,
    8995             :                         fname_foo,
    8996             :                         O_RDWR|O_CREAT,
    8997             :                         0666,
    8998             :                         &fnum);
    8999           4 :         if (!NT_STATUS_IS_OK(status)) {
    9000           0 :                 printf("cli_posix_open of %s failed error %s\n",
    9001             :                         fname_foo,
    9002             :                         nt_errstr(status));
    9003           0 :                 goto out;
    9004             :         }
    9005             : 
    9006           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9007           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9008           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9009             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9010             :                         "%s instead\n",
    9011             :                         fname_foo_foo,
    9012             :                         nt_errstr(status));
    9013           0 :                 goto out;
    9014             :         }
    9015             : 
    9016           4 :         status = cli_close(cli, fnum);
    9017           4 :         if (!NT_STATUS_IS_OK(status)) {
    9018           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    9019           0 :                 goto out;
    9020             :         }
    9021           4 :         fnum = (uint16_t)-1;
    9022             : 
    9023           4 :         status = cli_posix_unlink(cli, fname_foo);
    9024           4 :         if (!NT_STATUS_IS_OK(status)) {
    9025           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
    9026             :                         fname_foo,
    9027             :                         nt_errstr(status));
    9028           0 :                 goto out;
    9029             :         }
    9030             : 
    9031             :         /*
    9032             :          * Now we've deleted everything, posix_mkdir, posix_rmdir,
    9033             :          * posix_open, posix_unlink, on
    9034             :          * POSIX_foo/foo should return NT_STATUS_OBJECT_PATH_NOT_FOUND
    9035             :          * not silently create POSIX_foo/foo.
    9036             :          */
    9037             : 
    9038           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9039           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9040           0 :                 printf("cli_posix_mkdir of %s should fail with "
    9041             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9042             :                         "%s instead\n",
    9043             :                         fname_foo_foo,
    9044             :                         nt_errstr(status));
    9045           0 :                 goto out;
    9046             :         }
    9047             : 
    9048           4 :         status = cli_posix_rmdir(cli, fname_foo_foo);
    9049           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9050           0 :                 printf("cli_posix_rmdir of %s should fail with "
    9051             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9052             :                         "%s instead\n",
    9053             :                         fname_foo_foo,
    9054             :                         nt_errstr(status));
    9055           0 :                 goto out;
    9056             :         }
    9057             : 
    9058           4 :         status = cli_posix_open(cli,
    9059             :                         fname_foo_foo,
    9060             :                         O_RDWR|O_CREAT,
    9061             :                         0666,
    9062             :                         &fnum);
    9063           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9064           0 :                 printf("cli_posix_open of %s should fail with "
    9065             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9066             :                         "%s instead\n",
    9067             :                         fname_foo_foo,
    9068             :                         nt_errstr(status));
    9069           0 :                 goto out;
    9070             :         }
    9071             : 
    9072           4 :         status = cli_posix_unlink(cli, fname_foo_foo);
    9073           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
    9074           0 :                 printf("cli_posix_unlink of %s should fail with "
    9075             :                         "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
    9076             :                         "%s instead\n",
    9077             :                         fname_foo_foo,
    9078             :                         nt_errstr(status));
    9079           0 :                 goto out;
    9080             :         }
    9081             : 
    9082           4 :         status = cli_posix_mkdir(cli, fname_foo, 0777);
    9083           4 :         if (!NT_STATUS_IS_OK(status)) {
    9084           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo);
    9085           0 :                 goto out;
    9086             :         }
    9087             : 
    9088           4 :         status = cli_posix_mkdir(cli, fname_Foo, 0777);
    9089           4 :         if (!NT_STATUS_IS_OK(status)) {
    9090           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo);
    9091           0 :                 goto out;
    9092             :         }
    9093             : 
    9094           4 :         status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
    9095           4 :         if (!NT_STATUS_IS_OK(status)) {
    9096           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_foo);
    9097           0 :                 goto out;
    9098             :         }
    9099             : 
    9100           4 :         status = cli_posix_mkdir(cli, fname_foo_Foo, 0777);
    9101           4 :         if (!NT_STATUS_IS_OK(status)) {
    9102           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_foo_Foo);
    9103           0 :                 goto out;
    9104             :         }
    9105             : 
    9106           4 :         status = cli_posix_mkdir(cli, fname_Foo_foo, 0777);
    9107           4 :         if (!NT_STATUS_IS_OK(status)) {
    9108           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_foo);
    9109           0 :                 goto out;
    9110             :         }
    9111             : 
    9112           4 :         status = cli_posix_mkdir(cli, fname_Foo_Foo, 0777);
    9113           4 :         if (!NT_STATUS_IS_OK(status)) {
    9114           0 :                 printf("cli_posix_mkdir of %s failed\n", fname_Foo_Foo);
    9115           0 :                 goto out;
    9116             :         }
    9117             : 
    9118           4 :         printf("POSIX mkdir test passed\n");
    9119           4 :         correct = true;
    9120             : 
    9121           4 :   out:
    9122             : 
    9123           4 :         if (fnum != (uint16_t)-1) {
    9124           0 :                 cli_close(cli, fnum);
    9125           0 :                 fnum = (uint16_t)-1;
    9126             :         }
    9127             : 
    9128           4 :         cli_posix_rmdir(cli, fname_foo_foo);
    9129           4 :         cli_posix_rmdir(cli, fname_foo_Foo);
    9130           4 :         cli_posix_rmdir(cli, fname_foo);
    9131             : 
    9132           4 :         cli_posix_rmdir(cli, fname_Foo_foo);
    9133           4 :         cli_posix_rmdir(cli, fname_Foo_Foo);
    9134           4 :         cli_posix_rmdir(cli, fname_Foo);
    9135             : 
    9136           4 :         if (!torture_close_connection(cli)) {
    9137           0 :                 correct = false;
    9138             :         }
    9139             : 
    9140           4 :         TALLOC_FREE(frame);
    9141           4 :         return correct;
    9142             : }
    9143             : 
    9144             : struct posix_acl_oplock_state {
    9145             :         struct tevent_context *ev;
    9146             :         struct cli_state *cli;
    9147             :         bool *got_break;
    9148             :         bool *acl_ret;
    9149             :         NTSTATUS status;
    9150             : };
    9151             : 
    9152           4 : static void posix_acl_oplock_got_break(struct tevent_req *req)
    9153             : {
    9154           4 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9155             :                 req, struct posix_acl_oplock_state);
    9156             :         uint16_t fnum;
    9157             :         uint8_t level;
    9158             :         NTSTATUS status;
    9159             : 
    9160           4 :         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
    9161           4 :         TALLOC_FREE(req);
    9162           4 :         if (!NT_STATUS_IS_OK(status)) {
    9163           0 :                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
    9164             :                        nt_errstr(status));
    9165           0 :                 return;
    9166             :         }
    9167           4 :         *state->got_break = true;
    9168             : 
    9169           4 :         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
    9170             :                                   NO_OPLOCK);
    9171           4 :         if (req == NULL) {
    9172           0 :                 printf("cli_oplock_ack_send failed\n");
    9173           0 :                 return;
    9174             :         }
    9175             : }
    9176             : 
    9177           4 : static void posix_acl_oplock_got_acl(struct tevent_req *req)
    9178             : {
    9179           4 :         struct posix_acl_oplock_state *state = tevent_req_callback_data(
    9180             :                 req, struct posix_acl_oplock_state);
    9181           4 :         size_t ret_size = 0;
    9182           4 :         char *ret_data = NULL;
    9183             : 
    9184           4 :         state->status = cli_posix_getacl_recv(req,
    9185             :                         state,
    9186             :                         &ret_size,
    9187             :                         &ret_data);
    9188             : 
    9189           4 :         if (!NT_STATUS_IS_OK(state->status)) {
    9190           0 :                 printf("cli_posix_getacl_recv returned %s\n",
    9191             :                         nt_errstr(state->status));
    9192             :         }
    9193           4 :         *state->acl_ret = true;
    9194           4 : }
    9195             : 
    9196           4 : static bool run_posix_acl_oplock_test(int dummy)
    9197             : {
    9198             :         struct tevent_context *ev;
    9199             :         struct cli_state *cli1, *cli2;
    9200             :         struct tevent_req *oplock_req, *getacl_req;
    9201           4 :         const char *fname = "posix_acl_oplock";
    9202             :         uint16_t fnum;
    9203           4 :         int saved_use_oplocks = use_oplocks;
    9204             :         NTSTATUS status;
    9205           4 :         bool correct = true;
    9206           4 :         bool got_break = false;
    9207           4 :         bool acl_ret = false;
    9208             : 
    9209             :         struct posix_acl_oplock_state *state;
    9210             : 
    9211           4 :         printf("starting posix_acl_oplock test\n");
    9212             : 
    9213           4 :         if (!torture_open_connection(&cli1, 0)) {
    9214           0 :                 use_level_II_oplocks = false;
    9215           0 :                 use_oplocks = saved_use_oplocks;
    9216           0 :                 return false;
    9217             :         }
    9218             : 
    9219           4 :         if (!torture_open_connection(&cli2, 1)) {
    9220           0 :                 use_level_II_oplocks = false;
    9221           0 :                 use_oplocks = saved_use_oplocks;
    9222           0 :                 return false;
    9223             :         }
    9224             : 
    9225             :         /* Setup posix on cli2 only. */
    9226           4 :         status = torture_setup_unix_extensions(cli2);
    9227           4 :         if (!NT_STATUS_IS_OK(status)) {
    9228           0 :                 return false;
    9229             :         }
    9230             : 
    9231           4 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9232           4 :         smbXcli_conn_set_sockopt(cli2->conn, sockops);
    9233             : 
    9234           4 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9235             : 
    9236             :         /* Create the file on the Windows connection. */
    9237           4 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
    9238             :                           &fnum);
    9239           4 :         if (!NT_STATUS_IS_OK(status)) {
    9240           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9241           0 :                 return false;
    9242             :         }
    9243             : 
    9244           4 :         status = cli_close(cli1, fnum);
    9245           4 :         if (!NT_STATUS_IS_OK(status)) {
    9246           0 :                 printf("close1 failed (%s)\n", nt_errstr(status));
    9247           0 :                 return false;
    9248             :         }
    9249             : 
    9250           4 :         cli1->use_oplocks = true;
    9251             : 
    9252             :         /* Open with oplock. */
    9253           4 :         status = cli_ntcreate(cli1,
    9254             :                         fname,
    9255             :                         0,
    9256             :                         FILE_READ_DATA,
    9257             :                         FILE_ATTRIBUTE_NORMAL,
    9258             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
    9259             :                         FILE_OPEN,
    9260             :                         0,
    9261             :                         0,
    9262             :                         &fnum,
    9263             :                         NULL);
    9264             : 
    9265           4 :         if (!NT_STATUS_IS_OK(status)) {
    9266           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9267           0 :                 return false;
    9268             :         }
    9269             : 
    9270           4 :         ev = samba_tevent_context_init(talloc_tos());
    9271           4 :         if (ev == NULL) {
    9272           0 :                 printf("tevent_context_init failed\n");
    9273           0 :                 return false;
    9274             :         }
    9275             : 
    9276           4 :         state = talloc_zero(ev, struct posix_acl_oplock_state);
    9277           4 :         if (state == NULL) {
    9278           0 :                 printf("talloc failed\n");
    9279           0 :                 return false;
    9280             :         }
    9281           4 :         state->ev = ev;
    9282           4 :         state->cli = cli1;
    9283           4 :         state->got_break = &got_break;
    9284           4 :         state->acl_ret = &acl_ret;
    9285             : 
    9286           4 :         oplock_req = cli_smb_oplock_break_waiter_send(
    9287             :                 talloc_tos(), ev, cli1);
    9288           4 :         if (oplock_req == NULL) {
    9289           0 :                 printf("cli_smb_oplock_break_waiter_send failed\n");
    9290           0 :                 return false;
    9291             :         }
    9292           4 :         tevent_req_set_callback(oplock_req, posix_acl_oplock_got_break, state);
    9293             : 
    9294             :         /* Get ACL on POSIX connection - should break oplock. */
    9295           4 :         getacl_req = cli_posix_getacl_send(talloc_tos(),
    9296             :                                 ev,
    9297             :                                 cli2,
    9298             :                                 fname);
    9299           4 :         if (getacl_req == NULL) {
    9300           0 :                 printf("cli_posix_getacl_send failed\n");
    9301           0 :                 return false;
    9302             :         }
    9303           4 :         tevent_req_set_callback(getacl_req, posix_acl_oplock_got_acl, state);
    9304             : 
    9305           4 :         while (!got_break || !acl_ret) {
    9306             :                 int ret;
    9307          32 :                 ret = tevent_loop_once(ev);
    9308          32 :                 if (ret == -1) {
    9309           0 :                         printf("tevent_loop_once failed: %s\n",
    9310           0 :                                strerror(errno));
    9311           0 :                         return false;
    9312             :                 }
    9313             :         }
    9314             : 
    9315           4 :         if (!NT_STATUS_IS_OK(state->status)) {
    9316           0 :                 printf("getacl failed (%s)\n", nt_errstr(state->status));
    9317           0 :                 correct = false;
    9318             :         }
    9319             : 
    9320           4 :         status = cli_close(cli1, fnum);
    9321           4 :         if (!NT_STATUS_IS_OK(status)) {
    9322           0 :                 printf("close2 failed (%s)\n", nt_errstr(status));
    9323           0 :                 correct = false;
    9324             :         }
    9325             : 
    9326           4 :         status = cli_unlink(cli1,
    9327             :                         fname,
    9328             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9329           4 :         if (!NT_STATUS_IS_OK(status)) {
    9330           0 :                 printf("unlink failed (%s)\n", nt_errstr(status));
    9331           0 :                 correct = false;
    9332             :         }
    9333             : 
    9334           4 :         if (!torture_close_connection(cli1)) {
    9335           0 :                 correct = false;
    9336             :         }
    9337           4 :         if (!torture_close_connection(cli2)) {
    9338           0 :                 correct = false;
    9339             :         }
    9340             : 
    9341           4 :         if (!got_break) {
    9342           0 :                 correct = false;
    9343             :         }
    9344             : 
    9345           4 :         printf("finished posix acl oplock test\n");
    9346             : 
    9347           4 :         return correct;
    9348             : }
    9349             : 
    9350           4 : static bool run_posix_acl_shareroot_test(int dummy)
    9351             : {
    9352             :         struct cli_state *cli;
    9353             :         NTSTATUS status;
    9354           4 :         bool correct = false;
    9355           4 :         char *posix_acl = NULL;
    9356           4 :         size_t posix_acl_len = 0;
    9357           4 :         uint16_t num_file_acls = 0;
    9358           4 :         uint16_t num_dir_acls = 0;
    9359             :         uint16_t i;
    9360           4 :         uint32_t expected_size = 0;
    9361           4 :         bool got_user = false;
    9362           4 :         bool got_group = false;
    9363           4 :         bool got_other = false;
    9364           4 :         TALLOC_CTX *frame = NULL;
    9365             : 
    9366           4 :         frame = talloc_stackframe();
    9367             : 
    9368           4 :         printf("starting posix_acl_shareroot test\n");
    9369             : 
    9370           4 :         if (!torture_open_connection(&cli, 0)) {
    9371           0 :                 TALLOC_FREE(frame);
    9372           0 :                 return false;
    9373             :         }
    9374             : 
    9375           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9376             : 
    9377           4 :         status = torture_setup_unix_extensions(cli);
    9378           4 :         if (!NT_STATUS_IS_OK(status)) {
    9379           0 :                 printf("Failed to setup unix extensions\n");
    9380           0 :                 goto out;
    9381             :         }
    9382             : 
    9383             :         /* Get the POSIX ACL on the root of the share. */
    9384           4 :         status = cli_posix_getacl(cli,
    9385             :                                 ".",
    9386             :                                 frame,
    9387             :                                 &posix_acl_len,
    9388             :                                 &posix_acl);
    9389             : 
    9390           4 :         if (!NT_STATUS_IS_OK(status)) {
    9391           0 :                 printf("cli_posix_getacl of '.' failed (%s)\n",
    9392             :                         nt_errstr(status));
    9393           0 :                 goto out;
    9394             :         }
    9395             : 
    9396           8 :         if (posix_acl_len < 6 ||
    9397           4 :                         SVAL(posix_acl,0) != SMB_POSIX_ACL_VERSION) {
    9398           0 :                 printf("getfacl ., unknown POSIX acl version %u.\n",
    9399           0 :                         (unsigned int)CVAL(posix_acl,0) );
    9400           0 :                 goto out;
    9401             :         }
    9402             : 
    9403           4 :         num_file_acls = SVAL(posix_acl,2);
    9404           4 :         num_dir_acls = SVAL(posix_acl,4);
    9405           4 :         expected_size = SMB_POSIX_ACL_HEADER_SIZE +
    9406           4 :                                 SMB_POSIX_ACL_ENTRY_SIZE*
    9407           4 :                                 (num_file_acls+num_dir_acls);
    9408             : 
    9409           4 :         if (posix_acl_len != expected_size) {
    9410           0 :                 printf("incorrect POSIX acl buffer size "
    9411             :                         "(should be %u, was %u).\n",
    9412             :                         (unsigned int)expected_size,
    9413             :                         (unsigned int)posix_acl_len);
    9414           0 :                 goto out;
    9415             :         }
    9416             : 
    9417             :         /*
    9418             :          * We don't need to know what the ACL's are
    9419             :          * we just need to know we have at least 3
    9420             :          * file entries (u,g,o).
    9421             :          */
    9422             : 
    9423          16 :         for (i = 0; i < num_file_acls; i++) {
    9424          12 :                 unsigned char tagtype =
    9425          12 :                         CVAL(posix_acl,
    9426             :                                 SMB_POSIX_ACL_HEADER_SIZE+
    9427             :                                 (i*SMB_POSIX_ACL_ENTRY_SIZE));
    9428             : 
    9429          12 :                 switch(tagtype) {
    9430           4 :                         case SMB_POSIX_ACL_USER_OBJ:
    9431           4 :                                 got_user = true;
    9432           4 :                                 break;
    9433           4 :                         case SMB_POSIX_ACL_GROUP_OBJ:
    9434           4 :                                 got_group = true;
    9435           4 :                                 break;
    9436           4 :                         case SMB_POSIX_ACL_OTHER:
    9437           4 :                                 got_other = true;
    9438           4 :                                 break;
    9439           0 :                         default:
    9440           0 :                                 break;
    9441             :                 }
    9442             :         }
    9443             : 
    9444           4 :         if (!got_user) {
    9445           0 :                 printf("Missing user entry\n");
    9446           0 :                 goto out;
    9447             :         }
    9448             : 
    9449           4 :         if (!got_group) {
    9450           0 :                 printf("Missing group entry\n");
    9451           0 :                 goto out;
    9452             :         }
    9453             : 
    9454           4 :         if (!got_other) {
    9455           0 :                 printf("Missing other entry\n");
    9456           0 :                 goto out;
    9457             :         }
    9458             : 
    9459           4 :         correct = true;
    9460             : 
    9461           4 :   out:
    9462             : 
    9463           4 :         if (!torture_close_connection(cli)) {
    9464           0 :                 correct = false;
    9465             :         }
    9466             : 
    9467           4 :         printf("finished posix acl shareroot test\n");
    9468           4 :         TALLOC_FREE(frame);
    9469             : 
    9470           4 :         return correct;
    9471             : }
    9472             : 
    9473             : static uint32_t open_attrs_table[] = {
    9474             :                 FILE_ATTRIBUTE_NORMAL,
    9475             :                 FILE_ATTRIBUTE_ARCHIVE,
    9476             :                 FILE_ATTRIBUTE_READONLY,
    9477             :                 FILE_ATTRIBUTE_HIDDEN,
    9478             :                 FILE_ATTRIBUTE_SYSTEM,
    9479             : 
    9480             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
    9481             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
    9482             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
    9483             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9484             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9485             :                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9486             : 
    9487             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
    9488             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
    9489             :                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
    9490             :                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
    9491             : };
    9492             : 
    9493             : struct trunc_open_results {
    9494             :         unsigned int num;
    9495             :         uint32_t init_attr;
    9496             :         uint32_t trunc_attr;
    9497             :         uint32_t result_attr;
    9498             : };
    9499             : 
    9500             : static struct trunc_open_results attr_results[] = {
    9501             :         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9502             :         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9503             :         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9504             :         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
    9505             :         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
    9506             :         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
    9507             :         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9508             :         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9509             :         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9510             :         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9511             :         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9512             :         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
    9513             :         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9514             :         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9515             :         { 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 },
    9516             :         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9517             :         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9518             :         { 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 },
    9519             :         { 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 },
    9520             :         { 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 },
    9521             :         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9522             :         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
    9523             :         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
    9524             :         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9525             :         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
    9526             :         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
    9527             : };
    9528             : 
    9529           0 : static bool run_openattrtest(int dummy)
    9530             : {
    9531             :         static struct cli_state *cli1;
    9532           0 :         const char *fname = "\\openattr.file";
    9533             :         uint16_t fnum1;
    9534           0 :         bool correct = True;
    9535             :         uint32_t attr;
    9536             :         unsigned int i, j, k, l;
    9537             :         NTSTATUS status;
    9538             : 
    9539           0 :         printf("starting open attr test\n");
    9540             : 
    9541           0 :         if (!torture_open_connection(&cli1, 0)) {
    9542           0 :                 return False;
    9543             :         }
    9544             : 
    9545           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
    9546             : 
    9547           0 :         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
    9548           0 :                 cli_setatr(cli1, fname, 0, 0);
    9549           0 :                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9550             : 
    9551           0 :                 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
    9552             :                                        open_attrs_table[i], FILE_SHARE_NONE,
    9553             :                                        FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
    9554           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9555           0 :                         printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9556           0 :                         return False;
    9557             :                 }
    9558             : 
    9559           0 :                 status = cli_close(cli1, fnum1);
    9560           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9561           0 :                         printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
    9562           0 :                         return False;
    9563             :                 }
    9564             : 
    9565           0 :                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
    9566           0 :                         status = cli_ntcreate(cli1, fname, 0,
    9567             :                                               FILE_READ_DATA|FILE_WRITE_DATA,
    9568             :                                               open_attrs_table[j],
    9569             :                                               FILE_SHARE_NONE, FILE_OVERWRITE,
    9570             :                                               0, 0, &fnum1, NULL);
    9571           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9572           0 :                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9573           0 :                                         if (attr_results[l].num == k) {
    9574           0 :                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
    9575             :                                                                 k, open_attrs_table[i],
    9576             :                                                                 open_attrs_table[j],
    9577             :                                                                 fname, NT_STATUS_V(status), nt_errstr(status));
    9578           0 :                                                 correct = False;
    9579             :                                         }
    9580             :                                 }
    9581             : 
    9582           0 :                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
    9583           0 :                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
    9584             :                                                         k, open_attrs_table[i], open_attrs_table[j],
    9585             :                                                         nt_errstr(status));
    9586           0 :                                         correct = False;
    9587             :                                 }
    9588             : #if 0
    9589             :                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
    9590             : #endif
    9591           0 :                                 k++;
    9592           0 :                                 continue;
    9593             :                         }
    9594             : 
    9595           0 :                         status = cli_close(cli1, fnum1);
    9596           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9597           0 :                                 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
    9598           0 :                                 return False;
    9599             :                         }
    9600             : 
    9601           0 :                         status = cli_getatr(cli1, fname, &attr, NULL, NULL);
    9602           0 :                         if (!NT_STATUS_IS_OK(status)) {
    9603           0 :                                 printf("getatr(2) failed (%s)\n", nt_errstr(status));
    9604           0 :                                 return False;
    9605             :                         }
    9606             : 
    9607             : #if 0
    9608             :                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
    9609             :                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
    9610             : #endif
    9611             : 
    9612           0 :                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
    9613           0 :                                 if (attr_results[l].num == k) {
    9614           0 :                                         if (attr != attr_results[l].result_attr ||
    9615           0 :                                                         open_attrs_table[i] != attr_results[l].init_attr ||
    9616           0 :                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
    9617           0 :                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
    9618             :                                                 open_attrs_table[i],
    9619             :                                                 open_attrs_table[j],
    9620             :                                                 (unsigned int)attr,
    9621             :                                                 attr_results[l].result_attr);
    9622           0 :                                                 correct = False;
    9623             :                                         }
    9624           0 :                                         break;
    9625             :                                 }
    9626             :                         }
    9627           0 :                         k++;
    9628             :                 }
    9629             :         }
    9630             : 
    9631           0 :         cli_setatr(cli1, fname, 0, 0);
    9632           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9633             : 
    9634           0 :         printf("open attr test %s.\n", correct ? "passed" : "failed");
    9635             : 
    9636           0 :         if (!torture_close_connection(cli1)) {
    9637           0 :                 correct = False;
    9638             :         }
    9639           0 :         return correct;
    9640             : }
    9641             : 
    9642           0 : static NTSTATUS list_fn(struct file_info *finfo,
    9643             :                     const char *name, void *state)
    9644             : {
    9645           0 :         int *matched = (int *)state;
    9646           0 :         if (matched != NULL) {
    9647           0 :                 *matched += 1;
    9648             :         }
    9649           0 :         return NT_STATUS_OK;
    9650             : }
    9651             : 
    9652             : /*
    9653             :   test directory listing speed
    9654             :  */
    9655           5 : static bool run_dirtest(int dummy)
    9656             : {
    9657             :         int i;
    9658             :         static struct cli_state *cli;
    9659             :         uint16_t fnum;
    9660             :         struct timeval core_start;
    9661           5 :         bool correct = True;
    9662             :         int matched;
    9663             : 
    9664           5 :         printf("starting directory test\n");
    9665             : 
    9666           5 :         if (!torture_open_connection(&cli, 0)) {
    9667           0 :                 return False;
    9668             :         }
    9669             : 
    9670           5 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
    9671             : 
    9672           5 :         srandom(0);
    9673         505 :         for (i=0;i<torture_numops;i++) {
    9674             :                 fstring fname;
    9675         500 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9676         500 :                 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
    9677           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
    9678           0 :                         return False;
    9679             :                 }
    9680         500 :                 cli_close(cli, fnum);
    9681             :         }
    9682             : 
    9683           5 :         core_start = timeval_current();
    9684             : 
    9685           5 :         matched = 0;
    9686           5 :         cli_list(cli, "a*.*", 0, list_fn, &matched);
    9687           5 :         printf("Matched %d\n", matched);
    9688             : 
    9689           5 :         matched = 0;
    9690           5 :         cli_list(cli, "b*.*", 0, list_fn, &matched);
    9691           5 :         printf("Matched %d\n", matched);
    9692             : 
    9693           5 :         matched = 0;
    9694           5 :         cli_list(cli, "xyzabc", 0, list_fn, &matched);
    9695           5 :         printf("Matched %d\n", matched);
    9696             : 
    9697           5 :         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
    9698             : 
    9699           5 :         srandom(0);
    9700         505 :         for (i=0;i<torture_numops;i++) {
    9701             :                 fstring fname;
    9702         500 :                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
    9703         500 :                 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9704             :         }
    9705             : 
    9706           5 :         if (!torture_close_connection(cli)) {
    9707           0 :                 correct = False;
    9708             :         }
    9709             : 
    9710           5 :         printf("finished dirtest\n");
    9711             : 
    9712           5 :         return correct;
    9713             : }
    9714             : 
    9715           0 : static NTSTATUS del_fn(struct file_info *finfo, const char *mask,
    9716             :                    void *state)
    9717             : {
    9718           0 :         struct cli_state *pcli = (struct cli_state *)state;
    9719             :         fstring fname;
    9720           0 :         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
    9721             : 
    9722           0 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
    9723           0 :                 return NT_STATUS_OK;
    9724             : 
    9725           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
    9726           0 :                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
    9727           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
    9728             :         } else {
    9729           0 :                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
    9730           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
    9731             :         }
    9732           0 :         return NT_STATUS_OK;
    9733             : }
    9734             : 
    9735             : 
    9736             : /*
    9737             :   sees what IOCTLs are supported
    9738             :  */
    9739           5 : bool torture_ioctl_test(int dummy)
    9740             : {
    9741             :         static struct cli_state *cli;
    9742             :         uint16_t device, function;
    9743             :         uint16_t fnum;
    9744           5 :         const char *fname = "\\ioctl.dat";
    9745             :         DATA_BLOB blob;
    9746             :         NTSTATUS status;
    9747             : 
    9748           5 :         if (!torture_open_connection(&cli, 0)) {
    9749           0 :                 return False;
    9750             :         }
    9751             : 
    9752           5 :         printf("starting ioctl test\n");
    9753             : 
    9754           5 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9755             : 
    9756           5 :         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
    9757           5 :         if (!NT_STATUS_IS_OK(status)) {
    9758           0 :                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
    9759           0 :                 return False;
    9760             :         }
    9761             : 
    9762           5 :         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
    9763           5 :         printf("ioctl device info: %s\n", nt_errstr(status));
    9764             : 
    9765           5 :         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
    9766           5 :         printf("ioctl job info: %s\n", nt_errstr(status));
    9767             : 
    9768        1285 :         for (device=0;device<0x100;device++) {
    9769        1280 :                 printf("ioctl test with device = 0x%x\n", device);
    9770      328960 :                 for (function=0;function<0x100;function++) {
    9771      327680 :                         uint32_t code = (device<<16) | function;
    9772             : 
    9773      327680 :                         status = cli_raw_ioctl(cli, fnum, code, &blob);
    9774             : 
    9775      327680 :                         if (NT_STATUS_IS_OK(status)) {
    9776           4 :                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
    9777           4 :                                        (int)blob.length);
    9778           4 :                                 data_blob_free(&blob);
    9779             :                         }
    9780             :                 }
    9781             :         }
    9782             : 
    9783           5 :         if (!torture_close_connection(cli)) {
    9784           0 :                 return False;
    9785             :         }
    9786             : 
    9787           5 :         return True;
    9788             : }
    9789             : 
    9790             : 
    9791             : /*
    9792             :   tries varients of chkpath
    9793             :  */
    9794           5 : bool torture_chkpath_test(int dummy)
    9795             : {
    9796             :         static struct cli_state *cli;
    9797             :         uint16_t fnum;
    9798             :         bool ret;
    9799             :         NTSTATUS status;
    9800             : 
    9801           5 :         if (!torture_open_connection(&cli, 0)) {
    9802           0 :                 return False;
    9803             :         }
    9804             : 
    9805           5 :         printf("starting chkpath test\n");
    9806             : 
    9807             :         /* cleanup from an old run */
    9808           5 :         cli_rmdir(cli, "\\chkpath.dir\\dir2");
    9809           5 :         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9810           5 :         cli_rmdir(cli, "\\chkpath.dir");
    9811             : 
    9812           5 :         status = cli_mkdir(cli, "\\chkpath.dir");
    9813           5 :         if (!NT_STATUS_IS_OK(status)) {
    9814           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
    9815           0 :                 return False;
    9816             :         }
    9817             : 
    9818           5 :         status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
    9819           5 :         if (!NT_STATUS_IS_OK(status)) {
    9820           0 :                 printf("mkdir2 failed : %s\n", nt_errstr(status));
    9821           0 :                 return False;
    9822             :         }
    9823             : 
    9824           5 :         status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
    9825             :                           DENY_NONE, &fnum);
    9826           5 :         if (!NT_STATUS_IS_OK(status)) {
    9827           0 :                 printf("open1 failed (%s)\n", nt_errstr(status));
    9828           0 :                 return False;
    9829             :         }
    9830           5 :         cli_close(cli, fnum);
    9831             : 
    9832           5 :         status = cli_chkpath(cli, "\\chkpath.dir");
    9833           5 :         if (!NT_STATUS_IS_OK(status)) {
    9834           0 :                 printf("chkpath1 failed: %s\n", nt_errstr(status));
    9835           0 :                 ret = False;
    9836             :         }
    9837             : 
    9838           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
    9839           5 :         if (!NT_STATUS_IS_OK(status)) {
    9840           0 :                 printf("chkpath2 failed: %s\n", nt_errstr(status));
    9841           0 :                 ret = False;
    9842             :         }
    9843             : 
    9844           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
    9845           5 :         if (!NT_STATUS_IS_OK(status)) {
    9846           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
    9847           5 :                                   NT_STATUS_NOT_A_DIRECTORY);
    9848             :         } else {
    9849           0 :                 printf("* chkpath on a file should fail\n");
    9850           0 :                 ret = False;
    9851             :         }
    9852             : 
    9853           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
    9854           5 :         if (!NT_STATUS_IS_OK(status)) {
    9855           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
    9856           5 :                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
    9857             :         } else {
    9858           0 :                 printf("* chkpath on a non existent file should fail\n");
    9859           0 :                 ret = False;
    9860             :         }
    9861             : 
    9862           5 :         status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
    9863           5 :         if (!NT_STATUS_IS_OK(status)) {
    9864           5 :                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
    9865           5 :                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
    9866             :         } else {
    9867           0 :                 printf("* chkpath on a non existent component should fail\n");
    9868           0 :                 ret = False;
    9869             :         }
    9870             : 
    9871           5 :         cli_rmdir(cli, "\\chkpath.dir\\dir2");
    9872           5 :         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9873           5 :         cli_rmdir(cli, "\\chkpath.dir");
    9874             : 
    9875           5 :         if (!torture_close_connection(cli)) {
    9876           0 :                 return False;
    9877             :         }
    9878             : 
    9879           5 :         return ret;
    9880             : }
    9881             : 
    9882           0 : static bool run_eatest(int dummy)
    9883             : {
    9884             :         static struct cli_state *cli;
    9885           0 :         const char *fname = "\\eatest.txt";
    9886           0 :         bool correct = True;
    9887             :         uint16_t fnum;
    9888             :         int i;
    9889             :         size_t num_eas;
    9890           0 :         struct ea_struct *ea_list = NULL;
    9891           0 :         TALLOC_CTX *mem_ctx = talloc_init("eatest");
    9892             :         NTSTATUS status;
    9893             : 
    9894           0 :         printf("starting eatest\n");
    9895             : 
    9896           0 :         if (!torture_open_connection(&cli, 0)) {
    9897           0 :                 talloc_destroy(mem_ctx);
    9898           0 :                 return False;
    9899             :         }
    9900             : 
    9901           0 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    9902             : 
    9903           0 :         status = cli_ntcreate(cli, fname, 0,
    9904             :                               FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
    9905             :                               FILE_SHARE_NONE, FILE_OVERWRITE_IF,
    9906             :                               0x4044, 0, &fnum, NULL);
    9907           0 :         if (!NT_STATUS_IS_OK(status)) {
    9908           0 :                 printf("open failed - %s\n", nt_errstr(status));
    9909           0 :                 talloc_destroy(mem_ctx);
    9910           0 :                 return False;
    9911             :         }
    9912             : 
    9913           0 :         for (i = 0; i < 10; i++) {
    9914             :                 fstring ea_name, ea_val;
    9915             : 
    9916           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
    9917           0 :                 memset(ea_val, (char)i+1, i+1);
    9918           0 :                 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
    9919           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9920           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
    9921             :                                nt_errstr(status));
    9922           0 :                         talloc_destroy(mem_ctx);
    9923           0 :                         return False;
    9924             :                 }
    9925             :         }
    9926             : 
    9927           0 :         cli_close(cli, fnum);
    9928           0 :         for (i = 0; i < 10; i++) {
    9929             :                 fstring ea_name, ea_val;
    9930             : 
    9931           0 :                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
    9932           0 :                 memset(ea_val, (char)i+1, i+1);
    9933           0 :                 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
    9934           0 :                 if (!NT_STATUS_IS_OK(status)) {
    9935           0 :                         printf("ea_set of name %s failed - %s\n", ea_name,
    9936             :                                nt_errstr(status));
    9937           0 :                         talloc_destroy(mem_ctx);
    9938           0 :                         return False;
    9939             :                 }
    9940             :         }
    9941             : 
    9942           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
    9943           0 :         if (!NT_STATUS_IS_OK(status)) {
    9944           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
    9945           0 :                 correct = False;
    9946             :         }
    9947             : 
    9948           0 :         printf("num_eas = %d\n", (int)num_eas);
    9949             : 
    9950           0 :         if (num_eas != 20) {
    9951           0 :                 printf("Should be 20 EA's stored... failing.\n");
    9952           0 :                 correct = False;
    9953             :         }
    9954             : 
    9955           0 :         for (i = 0; i < num_eas; i++) {
    9956           0 :                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
    9957           0 :                 dump_data(0, ea_list[i].value.data,
    9958           0 :                           ea_list[i].value.length);
    9959             :         }
    9960             : 
    9961             :         /* Setting EA's to zero length deletes them. Test this */
    9962           0 :         printf("Now deleting all EA's - case indepenent....\n");
    9963             : 
    9964             : #if 1
    9965           0 :         cli_set_ea_path(cli, fname, "", "", 0);
    9966             : #else
    9967             :         for (i = 0; i < 20; i++) {
    9968             :                 fstring ea_name;
    9969             :                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
    9970             :                 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
    9971             :                 if (!NT_STATUS_IS_OK(status)) {
    9972             :                         printf("ea_set of name %s failed - %s\n", ea_name,
    9973             :                                nt_errstr(status));
    9974             :                         talloc_destroy(mem_ctx);
    9975             :                         return False;
    9976             :                 }
    9977             :         }
    9978             : #endif
    9979             : 
    9980           0 :         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
    9981           0 :         if (!NT_STATUS_IS_OK(status)) {
    9982           0 :                 printf("ea_get list failed - %s\n", nt_errstr(status));
    9983           0 :                 correct = False;
    9984             :         }
    9985             : 
    9986           0 :         printf("num_eas = %d\n", (int)num_eas);
    9987           0 :         for (i = 0; i < num_eas; i++) {
    9988           0 :                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
    9989           0 :                 dump_data(0, ea_list[i].value.data,
    9990           0 :                           ea_list[i].value.length);
    9991             :         }
    9992             : 
    9993           0 :         if (num_eas != 0) {
    9994           0 :                 printf("deleting EA's failed.\n");
    9995           0 :                 correct = False;
    9996             :         }
    9997             : 
    9998             :         /* Try and delete a non existent EA. */
    9999           0 :         status = cli_set_ea_path(cli, fname, "foo", "", 0);
   10000           0 :         if (!NT_STATUS_IS_OK(status)) {
   10001           0 :                 printf("deleting non-existent EA 'foo' should succeed. %s\n",
   10002             :                        nt_errstr(status));
   10003           0 :                 correct = False;
   10004             :         }
   10005             : 
   10006           0 :         talloc_destroy(mem_ctx);
   10007           0 :         if (!torture_close_connection(cli)) {
   10008           0 :                 correct = False;
   10009             :         }
   10010             : 
   10011           0 :         return correct;
   10012             : }
   10013             : 
   10014           0 : static bool run_dirtest1(int dummy)
   10015             : {
   10016             :         int i;
   10017             :         static struct cli_state *cli;
   10018             :         uint16_t fnum;
   10019             :         int num_seen;
   10020           0 :         bool correct = True;
   10021             : 
   10022           0 :         printf("starting directory test\n");
   10023             : 
   10024           0 :         if (!torture_open_connection(&cli, 0)) {
   10025           0 :                 return False;
   10026             :         }
   10027             : 
   10028           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   10029             : 
   10030           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10031           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10032           0 :         cli_rmdir(cli, "\\LISTDIR");
   10033           0 :         cli_mkdir(cli, "\\LISTDIR");
   10034             : 
   10035             :         /* Create 1000 files and 1000 directories. */
   10036           0 :         for (i=0;i<1000;i++) {
   10037             :                 fstring fname;
   10038           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
   10039           0 :                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
   10040             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
   10041             :                                    0, 0, &fnum, NULL))) {
   10042           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10043           0 :                         return False;
   10044             :                 }
   10045           0 :                 cli_close(cli, fnum);
   10046             :         }
   10047           0 :         for (i=0;i<1000;i++) {
   10048             :                 fstring fname;
   10049           0 :                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
   10050           0 :                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
   10051           0 :                         fprintf(stderr,"Failed to open %s\n", fname);
   10052           0 :                         return False;
   10053             :                 }
   10054             :         }
   10055             : 
   10056             :         /* Now ensure that doing an old list sees both files and directories. */
   10057           0 :         num_seen = 0;
   10058           0 :         cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10059           0 :         printf("num_seen = %d\n", num_seen );
   10060             :         /* We should see 100 files + 1000 directories + . and .. */
   10061           0 :         if (num_seen != 2002)
   10062           0 :                 correct = False;
   10063             : 
   10064             :         /* Ensure if we have the "must have" bits we only see the
   10065             :          * relevent entries.
   10066             :          */
   10067           0 :         num_seen = 0;
   10068           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10069           0 :         printf("num_seen = %d\n", num_seen );
   10070           0 :         if (num_seen != 1002)
   10071           0 :                 correct = False;
   10072             : 
   10073           0 :         num_seen = 0;
   10074           0 :         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
   10075           0 :         printf("num_seen = %d\n", num_seen );
   10076           0 :         if (num_seen != 1000)
   10077           0 :                 correct = False;
   10078             : 
   10079             :         /* Delete everything. */
   10080           0 :         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
   10081           0 :         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
   10082           0 :         cli_rmdir(cli, "\\LISTDIR");
   10083             : 
   10084             : #if 0
   10085             :         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
   10086             :         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
   10087             :         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
   10088             : #endif
   10089             : 
   10090           0 :         if (!torture_close_connection(cli)) {
   10091           0 :                 correct = False;
   10092             :         }
   10093             : 
   10094           0 :         printf("finished dirtest1\n");
   10095             : 
   10096           0 :         return correct;
   10097             : }
   10098             : 
   10099           0 : static bool run_error_map_extract(int dummy) {
   10100             : 
   10101             :         static struct cli_state *c_dos;
   10102             :         static struct cli_state *c_nt;
   10103             :         NTSTATUS status;
   10104             : 
   10105             :         uint32_t error;
   10106             : 
   10107             :         uint32_t errnum;
   10108             :         uint8_t errclass;
   10109             : 
   10110             :         NTSTATUS nt_status;
   10111             : 
   10112             :         fstring user;
   10113             : 
   10114             :         /* NT-Error connection */
   10115             : 
   10116           0 :         disable_spnego = true;
   10117           0 :         if (!(c_nt = open_nbt_connection())) {
   10118           0 :                 disable_spnego = false;
   10119           0 :                 return False;
   10120             :         }
   10121           0 :         disable_spnego = false;
   10122             : 
   10123           0 :         status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
   10124             :                                  PROTOCOL_NT1);
   10125             : 
   10126           0 :         if (!NT_STATUS_IS_OK(status)) {
   10127           0 :                 printf("%s rejected the NT-error negprot (%s)\n", host,
   10128             :                        nt_errstr(status));
   10129           0 :                 cli_shutdown(c_nt);
   10130           0 :                 return False;
   10131             :         }
   10132             : 
   10133           0 :         status = cli_session_setup_anon(c_nt);
   10134           0 :         if (!NT_STATUS_IS_OK(status)) {
   10135           0 :                 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
   10136           0 :                 return False;
   10137             :         }
   10138             : 
   10139             :         /* DOS-Error connection */
   10140             : 
   10141           0 :         disable_spnego = true;
   10142           0 :         force_dos_errors = true;
   10143           0 :         if (!(c_dos = open_nbt_connection())) {
   10144           0 :                 disable_spnego = false;
   10145           0 :                 force_dos_errors = false;
   10146           0 :                 return False;
   10147             :         }
   10148           0 :         disable_spnego = false;
   10149           0 :         force_dos_errors = false;
   10150             : 
   10151           0 :         status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
   10152             :                                  PROTOCOL_NT1);
   10153           0 :         if (!NT_STATUS_IS_OK(status)) {
   10154           0 :                 printf("%s rejected the DOS-error negprot (%s)\n", host,
   10155             :                        nt_errstr(status));
   10156           0 :                 cli_shutdown(c_dos);
   10157           0 :                 return False;
   10158             :         }
   10159             : 
   10160           0 :         status = cli_session_setup_anon(c_dos);
   10161           0 :         if (!NT_STATUS_IS_OK(status)) {
   10162           0 :                 printf("%s rejected the DOS-error initial session setup (%s)\n",
   10163             :                         host, nt_errstr(status));
   10164           0 :                 return False;
   10165             :         }
   10166             : 
   10167           0 :         c_nt->map_dos_errors = false;
   10168           0 :         c_dos->map_dos_errors = false;
   10169             : 
   10170           0 :         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
   10171           0 :                 struct cli_credentials *user_creds = NULL;
   10172             : 
   10173           0 :                 fstr_sprintf(user, "%X", error);
   10174             : 
   10175           0 :                 user_creds = cli_session_creds_init(talloc_tos(),
   10176             :                                                     user,
   10177             :                                                     workgroup,
   10178             :                                                     NULL, /* realm */
   10179             :                                                     password,
   10180             :                                                     false, /* use_kerberos */
   10181             :                                                     false, /* fallback_after_kerberos */
   10182             :                                                     false, /* use_ccache */
   10183             :                                                     false); /* password_is_nt_hash */
   10184           0 :                 if (user_creds == NULL) {
   10185           0 :                         printf("cli_session_creds_init(%s) failed\n", user);
   10186           0 :                         return false;
   10187             :                 }
   10188             : 
   10189           0 :                 status = cli_session_setup_creds(c_nt, user_creds);
   10190           0 :                 if (NT_STATUS_IS_OK(status)) {
   10191           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10192             :                 }
   10193             : 
   10194             :                 /* Case #1: 32-bit NT errors */
   10195           0 :                 if (!NT_STATUS_IS_DOS(status)) {
   10196           0 :                         nt_status = status;
   10197             :                 } else {
   10198           0 :                         printf("/** Dos error on NT connection! (%s) */\n", 
   10199             :                                nt_errstr(status));
   10200           0 :                         nt_status = NT_STATUS(0xc0000000);
   10201             :                 }
   10202             : 
   10203           0 :                 status = cli_session_setup_creds(c_dos, user_creds);
   10204           0 :                 if (NT_STATUS_IS_OK(status)) {
   10205           0 :                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
   10206             :                 }
   10207             : 
   10208             :                 /* Case #1: 32-bit NT errors */
   10209           0 :                 if (NT_STATUS_IS_DOS(status)) {
   10210           0 :                         printf("/** NT error on DOS connection! (%s) */\n", 
   10211             :                                nt_errstr(status));
   10212           0 :                         errnum = errclass = 0;
   10213             :                 } else {
   10214           0 :                         errclass = NT_STATUS_DOS_CLASS(status);
   10215           0 :                         errnum = NT_STATUS_DOS_CODE(status);
   10216             :                 }
   10217             : 
   10218           0 :                 if (NT_STATUS_V(nt_status) != error) { 
   10219           0 :                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
   10220           0 :                                get_nt_error_c_code(talloc_tos(), NT_STATUS(error)), 
   10221           0 :                                get_nt_error_c_code(talloc_tos(), nt_status));
   10222             :                 }
   10223             : 
   10224           0 :                 printf("\t{%s,\t%s,\t%s},\n", 
   10225             :                        smb_dos_err_class(errclass), 
   10226             :                        smb_dos_err_name(errclass, errnum), 
   10227           0 :                        get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
   10228             : 
   10229           0 :                 TALLOC_FREE(user_creds);
   10230             :         }
   10231           0 :         return True;
   10232             : }
   10233             : 
   10234           0 : static bool run_sesssetup_bench(int dummy)
   10235             : {
   10236             :         static struct cli_state *c;
   10237           0 :         const char *fname = "\\file.dat";
   10238             :         uint16_t fnum;
   10239             :         NTSTATUS status;
   10240             :         int i;
   10241             : 
   10242           0 :         if (!torture_open_connection(&c, 0)) {
   10243           0 :                 return false;
   10244             :         }
   10245             : 
   10246           0 :         status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   10247             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   10248             :                               FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
   10249           0 :         if (!NT_STATUS_IS_OK(status)) {
   10250           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   10251           0 :                 return false;
   10252             :         }
   10253             : 
   10254           0 :         for (i=0; i<torture_numops; i++) {
   10255           0 :                 status = cli_session_setup_creds(c, torture_creds);
   10256           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10257           0 :                         d_printf("(%s) cli_session_setup_creds failed: %s\n",
   10258             :                                  __location__, nt_errstr(status));
   10259           0 :                         return false;
   10260             :                 }
   10261             : 
   10262           0 :                 d_printf("\r%d   ", (int)cli_state_get_uid(c));
   10263             : 
   10264           0 :                 status = cli_ulogoff(c);
   10265           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10266           0 :                         d_printf("(%s) cli_ulogoff failed: %s\n",
   10267             :                                  __location__, nt_errstr(status));
   10268           0 :                         return false;
   10269             :                 }
   10270             :         }
   10271             : 
   10272           0 :         return true;
   10273             : }
   10274             : 
   10275           9 : static bool subst_test(const char *str, const char *user, const char *domain,
   10276             :                        uid_t uid, gid_t gid, const char *expected)
   10277             : {
   10278             :         char *subst;
   10279           9 :         bool result = true;
   10280             : 
   10281           9 :         subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
   10282             : 
   10283           9 :         if (strcmp(subst, expected) != 0) {
   10284           0 :                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
   10285             :                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
   10286             :                        expected);
   10287           0 :                 result = false;
   10288             :         }
   10289             : 
   10290           9 :         TALLOC_FREE(subst);
   10291           9 :         return result;
   10292             : }
   10293             : 
   10294           5 : static void chain1_open_completion(struct tevent_req *req)
   10295             : {
   10296             :         uint16_t fnum;
   10297             :         NTSTATUS status;
   10298           5 :         status = cli_openx_recv(req, &fnum);
   10299           5 :         TALLOC_FREE(req);
   10300             : 
   10301           5 :         d_printf("cli_openx_recv returned %s: %d\n",
   10302             :                  nt_errstr(status),
   10303           5 :                  NT_STATUS_IS_OK(status) ? fnum : -1);
   10304           5 : }
   10305             : 
   10306           5 : static void chain1_write_completion(struct tevent_req *req)
   10307             : {
   10308             :         size_t written;
   10309             :         NTSTATUS status;
   10310           5 :         status = cli_write_andx_recv(req, &written);
   10311           5 :         TALLOC_FREE(req);
   10312             : 
   10313          10 :         d_printf("cli_write_andx_recv returned %s: %d\n",
   10314             :                  nt_errstr(status),
   10315          10 :                  NT_STATUS_IS_OK(status) ? (int)written : -1);
   10316           5 : }
   10317             : 
   10318           5 : static void chain1_close_completion(struct tevent_req *req)
   10319             : {
   10320             :         NTSTATUS status;
   10321           5 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10322             : 
   10323           5 :         status = cli_close_recv(req);
   10324           5 :         *done = true;
   10325             : 
   10326           5 :         TALLOC_FREE(req);
   10327             : 
   10328           5 :         d_printf("cli_close returned %s\n", nt_errstr(status));
   10329           5 : }
   10330             : 
   10331           5 : static bool run_chain1(int dummy)
   10332             : {
   10333             :         struct cli_state *cli1;
   10334           5 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10335             :         struct tevent_req *reqs[3], *smbreqs[3];
   10336           5 :         bool done = false;
   10337           5 :         const char *str = "foobar";
   10338           5 :         const char *fname = "\\test_chain";
   10339             :         NTSTATUS status;
   10340             : 
   10341           5 :         printf("starting chain1 test\n");
   10342           5 :         if (!torture_open_connection(&cli1, 0)) {
   10343           0 :                 return False;
   10344             :         }
   10345             : 
   10346           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10347             : 
   10348           5 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   10349             : 
   10350           5 :         reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, fname,
   10351             :                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
   10352           5 :         if (reqs[0] == NULL) return false;
   10353           5 :         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
   10354             : 
   10355             : 
   10356           5 :         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
   10357           5 :                                         (const uint8_t *)str, 0, strlen(str)+1,
   10358             :                                         smbreqs, 1, &smbreqs[1]);
   10359           5 :         if (reqs[1] == NULL) return false;
   10360           5 :         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
   10361             : 
   10362           5 :         reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
   10363           5 :         if (reqs[2] == NULL) return false;
   10364           5 :         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
   10365             : 
   10366           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10367           5 :         if (!NT_STATUS_IS_OK(status)) {
   10368           0 :                 return false;
   10369             :         }
   10370             : 
   10371          40 :         while (!done) {
   10372          30 :                 tevent_loop_once(evt);
   10373             :         }
   10374             : 
   10375           5 :         torture_close_connection(cli1);
   10376           5 :         return True;
   10377             : }
   10378             : 
   10379           5 : static void chain2_sesssetup_completion(struct tevent_req *req)
   10380             : {
   10381             :         NTSTATUS status;
   10382           5 :         status = cli_session_setup_guest_recv(req);
   10383           5 :         d_printf("sesssetup returned %s\n", nt_errstr(status));
   10384           5 : }
   10385             : 
   10386           5 : static void chain2_tcon_completion(struct tevent_req *req)
   10387             : {
   10388           5 :         bool *done = (bool *)tevent_req_callback_data_void(req);
   10389             :         NTSTATUS status;
   10390           5 :         status = cli_tcon_andx_recv(req);
   10391           5 :         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
   10392           5 :         *done = true;
   10393           5 : }
   10394             : 
   10395           5 : static bool run_chain2(int dummy)
   10396             : {
   10397             :         struct cli_state *cli1;
   10398           5 :         struct tevent_context *evt = samba_tevent_context_init(NULL);
   10399             :         struct tevent_req *reqs[2], *smbreqs[2];
   10400           5 :         bool done = false;
   10401             :         NTSTATUS status;
   10402           5 :         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
   10403             : 
   10404           5 :         printf("starting chain2 test\n");
   10405           5 :         status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
   10406             :                                       port_to_use, SMB_SIGNING_DEFAULT, flags);
   10407           5 :         if (!NT_STATUS_IS_OK(status)) {
   10408           0 :                 return False;
   10409             :         }
   10410             : 
   10411           5 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   10412             : 
   10413           5 :         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
   10414             :                                                  &smbreqs[0]);
   10415           5 :         if (reqs[0] == NULL) return false;
   10416           5 :         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
   10417             : 
   10418           5 :         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
   10419             :                                        "?????", NULL, 0, &smbreqs[1]);
   10420           5 :         if (reqs[1] == NULL) return false;
   10421           5 :         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
   10422             : 
   10423           5 :         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
   10424           5 :         if (!NT_STATUS_IS_OK(status)) {
   10425           0 :                 return false;
   10426             :         }
   10427             : 
   10428          35 :         while (!done) {
   10429          25 :                 tevent_loop_once(evt);
   10430             :         }
   10431             : 
   10432           5 :         torture_close_connection(cli1);
   10433           5 :         return True;
   10434             : }
   10435             : 
   10436             : 
   10437             : struct torture_createdel_state {
   10438             :         struct tevent_context *ev;
   10439             :         struct cli_state *cli;
   10440             : };
   10441             : 
   10442             : static void torture_createdel_created(struct tevent_req *subreq);
   10443             : static void torture_createdel_closed(struct tevent_req *subreq);
   10444             : 
   10445           0 : static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
   10446             :                                                  struct tevent_context *ev,
   10447             :                                                  struct cli_state *cli,
   10448             :                                                  const char *name)
   10449             : {
   10450             :         struct tevent_req *req, *subreq;
   10451             :         struct torture_createdel_state *state;
   10452             : 
   10453           0 :         req = tevent_req_create(mem_ctx, &state,
   10454             :                                 struct torture_createdel_state);
   10455           0 :         if (req == NULL) {
   10456           0 :                 return NULL;
   10457             :         }
   10458           0 :         state->ev = ev;
   10459           0 :         state->cli = cli;
   10460             : 
   10461           0 :         subreq = cli_ntcreate_send(
   10462             :                 state, ev, cli, name, 0,
   10463             :                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
   10464             :                 FILE_ATTRIBUTE_NORMAL,
   10465             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   10466             :                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE,
   10467             :                 SMB2_IMPERSONATION_IMPERSONATION, 0);
   10468             : 
   10469           0 :         if (tevent_req_nomem(subreq, req)) {
   10470           0 :                 return tevent_req_post(req, ev);
   10471             :         }
   10472           0 :         tevent_req_set_callback(subreq, torture_createdel_created, req);
   10473           0 :         return req;
   10474             : }
   10475             : 
   10476           0 : static void torture_createdel_created(struct tevent_req *subreq)
   10477             : {
   10478           0 :         struct tevent_req *req = tevent_req_callback_data(
   10479             :                 subreq, struct tevent_req);
   10480           0 :         struct torture_createdel_state *state = tevent_req_data(
   10481             :                 req, struct torture_createdel_state);
   10482             :         NTSTATUS status;
   10483             :         uint16_t fnum;
   10484             : 
   10485           0 :         status = cli_ntcreate_recv(subreq, &fnum, NULL);
   10486           0 :         TALLOC_FREE(subreq);
   10487           0 :         if (tevent_req_nterror(req, status)) {
   10488           0 :                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
   10489             :                            nt_errstr(status)));
   10490           0 :                 return;
   10491             :         }
   10492             : 
   10493           0 :         subreq = cli_close_send(state, state->ev, state->cli, fnum);
   10494           0 :         if (tevent_req_nomem(subreq, req)) {
   10495           0 :                 return;
   10496             :         }
   10497           0 :         tevent_req_set_callback(subreq, torture_createdel_closed, req);
   10498             : }
   10499             : 
   10500           0 : static void torture_createdel_closed(struct tevent_req *subreq)
   10501             : {
   10502           0 :         struct tevent_req *req = tevent_req_callback_data(
   10503             :                 subreq, struct tevent_req);
   10504             :         NTSTATUS status;
   10505             : 
   10506           0 :         status = cli_close_recv(subreq);
   10507           0 :         if (tevent_req_nterror(req, status)) {
   10508           0 :                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
   10509           0 :                 return;
   10510             :         }
   10511           0 :         tevent_req_done(req);
   10512             : }
   10513             : 
   10514           0 : static NTSTATUS torture_createdel_recv(struct tevent_req *req)
   10515             : {
   10516           0 :         return tevent_req_simple_recv_ntstatus(req);
   10517             : }
   10518             : 
   10519             : struct torture_createdels_state {
   10520             :         struct tevent_context *ev;
   10521             :         struct cli_state *cli;
   10522             :         const char *base_name;
   10523             :         int sent;
   10524             :         int received;
   10525             :         int num_files;
   10526             :         struct tevent_req **reqs;
   10527             : };
   10528             : 
   10529             : static void torture_createdels_done(struct tevent_req *subreq);
   10530             : 
   10531           0 : static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
   10532             :                                                   struct tevent_context *ev,
   10533             :                                                   struct cli_state *cli,
   10534             :                                                   const char *base_name,
   10535             :                                                   int num_parallel,
   10536             :                                                   int num_files)
   10537             : {
   10538             :         struct tevent_req *req;
   10539             :         struct torture_createdels_state *state;
   10540             :         int i;
   10541             : 
   10542           0 :         req = tevent_req_create(mem_ctx, &state,
   10543             :                                 struct torture_createdels_state);
   10544           0 :         if (req == NULL) {
   10545           0 :                 return NULL;
   10546             :         }
   10547           0 :         state->ev = ev;
   10548           0 :         state->cli = cli;
   10549           0 :         state->base_name = talloc_strdup(state, base_name);
   10550           0 :         if (tevent_req_nomem(state->base_name, req)) {
   10551           0 :                 return tevent_req_post(req, ev);
   10552             :         }
   10553           0 :         state->num_files = MAX(num_parallel, num_files);
   10554           0 :         state->sent = 0;
   10555           0 :         state->received = 0;
   10556             : 
   10557           0 :         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
   10558           0 :         if (tevent_req_nomem(state->reqs, req)) {
   10559           0 :                 return tevent_req_post(req, ev);
   10560             :         }
   10561             : 
   10562           0 :         for (i=0; i<num_parallel; i++) {
   10563             :                 char *name;
   10564             : 
   10565           0 :                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10566           0 :                                        state->sent);
   10567           0 :                 if (tevent_req_nomem(name, req)) {
   10568           0 :                         return tevent_req_post(req, ev);
   10569             :                 }
   10570           0 :                 state->reqs[i] = torture_createdel_send(
   10571           0 :                         state->reqs, state->ev, state->cli, name);
   10572           0 :                 if (tevent_req_nomem(state->reqs[i], req)) {
   10573           0 :                         return tevent_req_post(req, ev);
   10574             :                 }
   10575           0 :                 name = talloc_move(state->reqs[i], &name);
   10576           0 :                 tevent_req_set_callback(state->reqs[i],
   10577             :                                         torture_createdels_done, req);
   10578           0 :                 state->sent += 1;
   10579             :         }
   10580           0 :         return req;
   10581             : }
   10582             : 
   10583           0 : static void torture_createdels_done(struct tevent_req *subreq)
   10584             : {
   10585           0 :         struct tevent_req *req = tevent_req_callback_data(
   10586             :                 subreq, struct tevent_req);
   10587           0 :         struct torture_createdels_state *state = tevent_req_data(
   10588             :                 req, struct torture_createdels_state);
   10589           0 :         size_t num_parallel = talloc_array_length(state->reqs);
   10590             :         NTSTATUS status;
   10591             :         char *name;
   10592             :         int i;
   10593             : 
   10594           0 :         status = torture_createdel_recv(subreq);
   10595           0 :         if (!NT_STATUS_IS_OK(status)){
   10596           0 :                 DEBUG(10, ("torture_createdel_recv returned %s\n",
   10597             :                            nt_errstr(status)));
   10598           0 :                 TALLOC_FREE(subreq);
   10599           0 :                 tevent_req_nterror(req, status);
   10600           0 :                 return;
   10601             :         }
   10602             : 
   10603           0 :         for (i=0; i<num_parallel; i++) {
   10604           0 :                 if (subreq == state->reqs[i]) {
   10605           0 :                         break;
   10606             :                 }
   10607             :         }
   10608           0 :         if (i == num_parallel) {
   10609           0 :                 DEBUG(10, ("received something we did not send\n"));
   10610           0 :                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
   10611           0 :                 return;
   10612             :         }
   10613           0 :         TALLOC_FREE(state->reqs[i]);
   10614             : 
   10615           0 :         if (state->sent >= state->num_files) {
   10616           0 :                 tevent_req_done(req);
   10617           0 :                 return;
   10618             :         }
   10619             : 
   10620           0 :         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
   10621             :                                state->sent);
   10622           0 :         if (tevent_req_nomem(name, req)) {
   10623           0 :                 return;
   10624             :         }
   10625           0 :         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
   10626             :                                                 state->cli, name);
   10627           0 :         if (tevent_req_nomem(state->reqs[i], req)) {
   10628           0 :                 return;
   10629             :         }
   10630           0 :         name = talloc_move(state->reqs[i], &name);
   10631           0 :         tevent_req_set_callback(state->reqs[i],      torture_createdels_done, req);
   10632           0 :         state->sent += 1;
   10633             : }
   10634             : 
   10635           0 : static NTSTATUS torture_createdels_recv(struct tevent_req *req)
   10636             : {
   10637           0 :         return tevent_req_simple_recv_ntstatus(req);
   10638             : }
   10639             : 
   10640             : struct swallow_notify_state {
   10641             :         struct tevent_context *ev;
   10642             :         struct cli_state *cli;
   10643             :         uint16_t fnum;
   10644             :         uint32_t completion_filter;
   10645             :         bool recursive;
   10646             :         bool (*fn)(uint32_t action, const char *name, void *priv);
   10647             :         void *priv;
   10648             : };
   10649             : 
   10650             : static void swallow_notify_done(struct tevent_req *subreq);
   10651             : 
   10652           0 : static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
   10653             :                                               struct tevent_context *ev,
   10654             :                                               struct cli_state *cli,
   10655             :                                               uint16_t fnum,
   10656             :                                               uint32_t completion_filter,
   10657             :                                               bool recursive,
   10658             :                                               bool (*fn)(uint32_t action,
   10659             :                                                          const char *name,
   10660             :                                                          void *priv),
   10661             :                                               void *priv)
   10662             : {
   10663             :         struct tevent_req *req, *subreq;
   10664             :         struct swallow_notify_state *state;
   10665             : 
   10666           0 :         req = tevent_req_create(mem_ctx, &state,
   10667             :                                 struct swallow_notify_state);
   10668           0 :         if (req == NULL) {
   10669           0 :                 return NULL;
   10670             :         }
   10671           0 :         state->ev = ev;
   10672           0 :         state->cli = cli;
   10673           0 :         state->fnum = fnum;
   10674           0 :         state->completion_filter = completion_filter;
   10675           0 :         state->recursive = recursive;
   10676           0 :         state->fn = fn;
   10677           0 :         state->priv = priv;
   10678             : 
   10679           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10680           0 :                                  0xffff, state->completion_filter,
   10681           0 :                                  state->recursive);
   10682           0 :         if (tevent_req_nomem(subreq, req)) {
   10683           0 :                 return tevent_req_post(req, ev);
   10684             :         }
   10685           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10686           0 :         return req;
   10687             : }
   10688             : 
   10689           0 : static void swallow_notify_done(struct tevent_req *subreq)
   10690             : {
   10691           0 :         struct tevent_req *req = tevent_req_callback_data(
   10692             :                 subreq, struct tevent_req);
   10693           0 :         struct swallow_notify_state *state = tevent_req_data(
   10694             :                 req, struct swallow_notify_state);
   10695             :         NTSTATUS status;
   10696             :         uint32_t i, num_changes;
   10697             :         struct notify_change *changes;
   10698             : 
   10699           0 :         status = cli_notify_recv(subreq, state, &num_changes, &changes);
   10700           0 :         TALLOC_FREE(subreq);
   10701           0 :         if (!NT_STATUS_IS_OK(status)) {
   10702           0 :                 DEBUG(10, ("cli_notify_recv returned %s\n",
   10703             :                            nt_errstr(status)));
   10704           0 :                 tevent_req_nterror(req, status);
   10705           0 :                 return;
   10706             :         }
   10707             : 
   10708           0 :         for (i=0; i<num_changes; i++) {
   10709           0 :                 state->fn(changes[i].action, changes[i].name, state->priv);
   10710             :         }
   10711           0 :         TALLOC_FREE(changes);
   10712             : 
   10713           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
   10714             :                                  0xffff, state->completion_filter,
   10715           0 :                                  state->recursive);
   10716           0 :         if (tevent_req_nomem(subreq, req)) {
   10717           0 :                 return;
   10718             :         }
   10719           0 :         tevent_req_set_callback(subreq, swallow_notify_done, req);
   10720             : }
   10721             : 
   10722           0 : static bool print_notifies(uint32_t action, const char *name, void *priv)
   10723             : {
   10724           0 :         if (DEBUGLEVEL > 5) {
   10725           0 :                 d_printf("%d %s\n", (int)action, name);
   10726             :         }
   10727           0 :         return true;
   10728             : }
   10729             : 
   10730           0 : static void notify_bench_done(struct tevent_req *req)
   10731             : {
   10732           0 :         int *num_finished = (int *)tevent_req_callback_data_void(req);
   10733           0 :         *num_finished += 1;
   10734           0 : }
   10735             : 
   10736           0 : static bool run_notify_bench(int dummy)
   10737             : {
   10738           0 :         const char *dname = "\\notify-bench";
   10739             :         struct tevent_context *ev;
   10740             :         NTSTATUS status;
   10741             :         uint16_t dnum;
   10742             :         struct tevent_req *req1;
   10743           0 :         struct tevent_req *req2 = NULL;
   10744             :         int i, num_unc_names;
   10745           0 :         int num_finished = 0;
   10746             : 
   10747           0 :         printf("starting notify-bench test\n");
   10748             : 
   10749           0 :         if (use_multishare_conn) {
   10750             :                 char **unc_list;
   10751           0 :                 unc_list = file_lines_load(multishare_conn_fname,
   10752             :                                            &num_unc_names, 0, NULL);
   10753           0 :                 if (!unc_list || num_unc_names <= 0) {
   10754           0 :                         d_printf("Failed to load unc names list from '%s'\n",
   10755             :                                  multishare_conn_fname);
   10756           0 :                         return false;
   10757             :                 }
   10758           0 :                 TALLOC_FREE(unc_list);
   10759             :         } else {
   10760           0 :                 num_unc_names = 1;
   10761             :         }
   10762             : 
   10763           0 :         ev = samba_tevent_context_init(talloc_tos());
   10764           0 :         if (ev == NULL) {
   10765           0 :                 d_printf("tevent_context_init failed\n");
   10766           0 :                 return false;
   10767             :         }
   10768             : 
   10769           0 :         for (i=0; i<num_unc_names; i++) {
   10770             :                 struct cli_state *cli;
   10771             :                 char *base_fname;
   10772             : 
   10773           0 :                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
   10774             :                                              dname, i);
   10775           0 :                 if (base_fname == NULL) {
   10776           0 :                         return false;
   10777             :                 }
   10778             : 
   10779           0 :                 if (!torture_open_connection(&cli, i)) {
   10780           0 :                         return false;
   10781             :                 }
   10782             : 
   10783           0 :                 status = cli_ntcreate(cli, dname, 0,
   10784             :                                       MAXIMUM_ALLOWED_ACCESS,
   10785             :                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
   10786             :                                       FILE_SHARE_DELETE,
   10787             :                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
   10788             :                                       &dnum, NULL);
   10789             : 
   10790           0 :                 if (!NT_STATUS_IS_OK(status)) {
   10791           0 :                         d_printf("Could not create %s: %s\n", dname,
   10792             :                                  nt_errstr(status));
   10793           0 :                         return false;
   10794             :                 }
   10795             : 
   10796           0 :                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
   10797             :                                            FILE_NOTIFY_CHANGE_FILE_NAME |
   10798             :                                            FILE_NOTIFY_CHANGE_DIR_NAME |
   10799             :                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
   10800             :                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
   10801             :                                            false, print_notifies, NULL);
   10802           0 :                 if (req1 == NULL) {
   10803           0 :                         d_printf("Could not create notify request\n");
   10804           0 :                         return false;
   10805             :                 }
   10806             : 
   10807           0 :                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
   10808             :                                                base_fname, 10, torture_numops);
   10809           0 :                 if (req2 == NULL) {
   10810           0 :                         d_printf("Could not create createdels request\n");
   10811           0 :                         return false;
   10812             :                 }
   10813           0 :                 TALLOC_FREE(base_fname);
   10814             : 
   10815           0 :                 tevent_req_set_callback(req2, notify_bench_done,
   10816             :                                         &num_finished);
   10817             :         }
   10818             : 
   10819           0 :         while (num_finished < num_unc_names) {
   10820             :                 int ret;
   10821           0 :                 ret = tevent_loop_once(ev);
   10822           0 :                 if (ret != 0) {
   10823           0 :                         d_printf("tevent_loop_once failed\n");
   10824           0 :                         return false;
   10825             :                 }
   10826             :         }
   10827             : 
   10828           0 :         if (!tevent_req_poll(req2, ev)) {
   10829           0 :                 d_printf("tevent_req_poll failed\n");
   10830             :         }
   10831             : 
   10832           0 :         status = torture_createdels_recv(req2);
   10833           0 :         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
   10834             : 
   10835           0 :         return true;
   10836             : }
   10837             : 
   10838           0 : static bool run_mangle1(int dummy)
   10839             : {
   10840             :         struct cli_state *cli;
   10841           0 :         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
   10842             :         uint16_t fnum;
   10843             :         fstring alt_name;
   10844             :         NTSTATUS status;
   10845             :         time_t change_time, access_time, write_time;
   10846             :         off_t size;
   10847             :         uint32_t attr;
   10848             : 
   10849           0 :         printf("starting mangle1 test\n");
   10850           0 :         if (!torture_open_connection(&cli, 0)) {
   10851           0 :                 return False;
   10852             :         }
   10853             : 
   10854           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   10855             : 
   10856           0 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   10857             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   10858             :                               0, 0, &fnum, NULL);
   10859           0 :         if (!NT_STATUS_IS_OK(status)) {
   10860           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   10861           0 :                 return false;
   10862             :         }
   10863           0 :         cli_close(cli, fnum);
   10864             : 
   10865           0 :         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
   10866           0 :         if (!NT_STATUS_IS_OK(status)) {
   10867           0 :                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
   10868             :                          nt_errstr(status));
   10869           0 :                 return false;
   10870             :         }
   10871           0 :         d_printf("alt_name: %s\n", alt_name);
   10872             : 
   10873           0 :         status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
   10874           0 :         if (!NT_STATUS_IS_OK(status)) {
   10875           0 :                 d_printf("cli_openx(%s) failed: %s\n", alt_name,
   10876             :                          nt_errstr(status));
   10877           0 :                 return false;
   10878             :         }
   10879           0 :         cli_close(cli, fnum);
   10880             : 
   10881           0 :         status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
   10882             :                                 &write_time, &size, &attr);
   10883           0 :         if (!NT_STATUS_IS_OK(status)) {
   10884           0 :                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
   10885             :                          nt_errstr(status));
   10886           0 :                 return false;
   10887             :         }
   10888             : 
   10889           0 :         return true;
   10890             : }
   10891             : 
   10892           2 : static NTSTATUS mangle_illegal_list_shortname_fn(struct file_info *f,
   10893             :                                                  const char *mask,
   10894             :                                                  void *state)
   10895             : {
   10896           2 :         if (f->short_name == NULL) {
   10897           2 :                 return NT_STATUS_OK;
   10898             :         }
   10899             : 
   10900           0 :         if (strlen(f->short_name) == 0) {
   10901           0 :                 return NT_STATUS_OK;
   10902             :         }
   10903             : 
   10904           0 :         printf("unexpected shortname: %s\n", f->short_name);
   10905             : 
   10906           0 :         return NT_STATUS_OBJECT_NAME_INVALID;
   10907             : }
   10908             : 
   10909           2 : static NTSTATUS mangle_illegal_list_name_fn(struct file_info *f,
   10910             :                                             const char *mask,
   10911             :                                             void *state)
   10912             : {
   10913           2 :         char *name = state;
   10914             : 
   10915           2 :         printf("name: %s\n", f->name);
   10916           2 :         fstrcpy(name, f->name);
   10917           2 :         return NT_STATUS_OK;
   10918             : }
   10919             : 
   10920           2 : static bool run_mangle_illegal(int dummy)
   10921             : {
   10922           2 :         struct cli_state *cli = NULL;
   10923           2 :         struct cli_state *cli_posix = NULL;
   10924           2 :         const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
   10925           2 :         const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
   10926           2 :         char *mangled_path = NULL;
   10927             :         uint16_t fnum;
   10928             :         fstring name;
   10929             :         fstring alt_name;
   10930             :         NTSTATUS status;
   10931             : 
   10932           2 :         printf("starting mangle-illegal test\n");
   10933             : 
   10934           2 :         if (!torture_open_connection(&cli, 0)) {
   10935           0 :                 return False;
   10936             :         }
   10937             : 
   10938           2 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   10939             : 
   10940           2 :         if (!torture_open_connection(&cli_posix, 0)) {
   10941           0 :                 return false;
   10942             :         }
   10943             : 
   10944           2 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   10945             : 
   10946           2 :         status = torture_setup_unix_extensions(cli_posix);
   10947           2 :         if (!NT_STATUS_IS_OK(status)) {
   10948           0 :                 return false;
   10949             :         }
   10950             : 
   10951           2 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   10952           2 :         status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
   10953           2 :         if (!NT_STATUS_IS_OK(status)) {
   10954           0 :                 printf("mkdir1 failed : %s\n", nt_errstr(status));
   10955           0 :                 return False;
   10956             :         }
   10957             : 
   10958             :         /*
   10959             :          * Create a file with illegal NTFS characters and test that we
   10960             :          * get a usable mangled name
   10961             :          */
   10962             : 
   10963           2 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   10964           2 :         cli_posix_unlink(cli_posix, illegal_fname);
   10965             : 
   10966           2 :         status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
   10967             :                                 0600, &fnum);
   10968           2 :         if (!NT_STATUS_IS_OK(status)) {
   10969           0 :                 printf("POSIX create of %s failed (%s)\n",
   10970             :                        illegal_fname, nt_errstr(status));
   10971           0 :                 return false;
   10972             :         }
   10973             : 
   10974           2 :         status = cli_close(cli_posix, fnum);
   10975           2 :         if (!NT_STATUS_IS_OK(status)) {
   10976           0 :                 printf("close failed (%s)\n", nt_errstr(status));
   10977           0 :                 return false;
   10978             :         }
   10979             : 
   10980           2 :         status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
   10981           2 :         if (!NT_STATUS_IS_OK(status)) {
   10982           0 :                 d_printf("cli_list failed: %s\n", nt_errstr(status));
   10983           0 :                 return false;
   10984             :         }
   10985             : 
   10986           2 :         mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
   10987           2 :         if (mangled_path == NULL) {
   10988           0 :                 return false;
   10989             :         }
   10990             : 
   10991           2 :         status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
   10992           2 :         if (!NT_STATUS_IS_OK(status)) {
   10993           0 :                 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
   10994           0 :                 TALLOC_FREE(mangled_path);
   10995           0 :                 return false;
   10996             :         }
   10997           2 :         TALLOC_FREE(mangled_path);
   10998           2 :         cli_close(cli, fnum);
   10999             : 
   11000           2 :         cli_setatr(cli_posix, illegal_fname, 0, 0);
   11001           2 :         cli_posix_unlink(cli_posix, illegal_fname);
   11002             : 
   11003             :         /*
   11004             :          * Create a file with a long name and check that we got *no* short name.
   11005             :          */
   11006             : 
   11007           2 :         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
   11008             :                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11009             :                               0, 0, &fnum, NULL);
   11010           2 :         if (!NT_STATUS_IS_OK(status)) {
   11011           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11012           0 :                 return false;
   11013             :         }
   11014           2 :         cli_close(cli, fnum);
   11015             : 
   11016           2 :         status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
   11017           2 :         if (!NT_STATUS_IS_OK(status)) {
   11018           0 :                 d_printf("cli_list failed\n");
   11019           0 :                 return false;
   11020             :         }
   11021             : 
   11022           2 :         cli_unlink(cli, fname, 0);
   11023           2 :         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
   11024             : 
   11025           2 :         if (!torture_close_connection(cli_posix)) {
   11026           0 :                 return false;
   11027             :         }
   11028             : 
   11029           2 :         if (!torture_close_connection(cli)) {
   11030           0 :                 return false;
   11031             :         }
   11032             : 
   11033           2 :         return true;
   11034             : }
   11035             : 
   11036           0 : static size_t null_source(uint8_t *buf, size_t n, void *priv)
   11037             : {
   11038           0 :         size_t *to_pull = (size_t *)priv;
   11039           0 :         size_t thistime = *to_pull;
   11040             : 
   11041           0 :         thistime = MIN(thistime, n);
   11042           0 :         if (thistime == 0) {
   11043           0 :                 return 0;
   11044             :         }
   11045             : 
   11046           0 :         memset(buf, 0, thistime);
   11047           0 :         *to_pull -= thistime;
   11048           0 :         return thistime;
   11049             : }
   11050             : 
   11051           0 : static bool run_windows_write(int dummy)
   11052             : {
   11053             :         struct cli_state *cli1;
   11054             :         uint16_t fnum;
   11055             :         int i;
   11056           0 :         bool ret = false;
   11057           0 :         const char *fname = "\\writetest.txt";
   11058             :         struct timeval start_time;
   11059             :         double seconds;
   11060             :         double kbytes;
   11061             :         NTSTATUS status;
   11062             : 
   11063           0 :         printf("starting windows_write test\n");
   11064           0 :         if (!torture_open_connection(&cli1, 0)) {
   11065           0 :                 return False;
   11066             :         }
   11067             : 
   11068           0 :         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
   11069           0 :         if (!NT_STATUS_IS_OK(status)) {
   11070           0 :                 printf("open failed (%s)\n", nt_errstr(status));
   11071           0 :                 return False;
   11072             :         }
   11073             : 
   11074           0 :         smbXcli_conn_set_sockopt(cli1->conn, sockops);
   11075             : 
   11076           0 :         start_time = timeval_current();
   11077             : 
   11078           0 :         for (i=0; i<torture_numops; i++) {
   11079           0 :                 uint8_t c = 0;
   11080           0 :                 off_t start = i * torture_blocksize;
   11081           0 :                 size_t to_pull = torture_blocksize - 1;
   11082             : 
   11083           0 :                 status = cli_writeall(cli1, fnum, 0, &c,
   11084           0 :                                       start + torture_blocksize - 1, 1, NULL);
   11085           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11086           0 :                         printf("cli_write failed: %s\n", nt_errstr(status));
   11087           0 :                         goto fail;
   11088             :                 }
   11089             : 
   11090           0 :                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
   11091             :                                   null_source, &to_pull);
   11092           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11093           0 :                         printf("cli_push returned: %s\n", nt_errstr(status));
   11094           0 :                         goto fail;
   11095             :                 }
   11096             :         }
   11097             : 
   11098           0 :         seconds = timeval_elapsed(&start_time);
   11099           0 :         kbytes = (double)torture_blocksize * torture_numops;
   11100           0 :         kbytes /= 1024;
   11101             : 
   11102           0 :         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
   11103           0 :                (double)seconds, (int)(kbytes/seconds));
   11104             : 
   11105           0 :         ret = true;
   11106           0 :  fail:
   11107           0 :         cli_close(cli1, fnum);
   11108           0 :         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11109           0 :         torture_close_connection(cli1);
   11110           0 :         return ret;
   11111             : }
   11112             : 
   11113          64 : static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
   11114             : {
   11115          64 :         size_t max_pdu = 0x1FFFF;
   11116             : 
   11117          64 :         if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
   11118          32 :                 max_pdu = 0xFFFFFF;
   11119             :         }
   11120             : 
   11121          64 :         if (smb1cli_conn_signing_is_active(cli->conn)) {
   11122          32 :                 max_pdu = 0x1FFFF;
   11123             :         }
   11124             : 
   11125          64 :         if (smb1cli_conn_encryption_on(cli->conn)) {
   11126          16 :                 max_pdu = CLI_BUFFER_SIZE;
   11127             :         }
   11128             : 
   11129          64 :         if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
   11130           8 :                 len_requested &= 0xFFFF;
   11131             :         }
   11132             : 
   11133          64 :         return MIN(len_requested,
   11134             :                    max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
   11135             : }
   11136             : 
   11137          64 : static bool check_read_call(struct cli_state *cli,
   11138             :                             uint16_t fnum,
   11139             :                             uint8_t *buf,
   11140             :                             size_t len_requested)
   11141             : {
   11142             :         NTSTATUS status;
   11143          64 :         struct tevent_req *subreq = NULL;
   11144          64 :         ssize_t len_read = 0;
   11145          64 :         size_t len_expected = 0;
   11146          64 :         struct tevent_context *ev = NULL;
   11147             : 
   11148          64 :         ev = samba_tevent_context_init(talloc_tos());
   11149          64 :         if (ev == NULL) {
   11150           0 :                 return false;
   11151             :         }
   11152             : 
   11153          64 :         subreq = cli_read_andx_send(talloc_tos(),
   11154             :                                     ev,
   11155             :                                     cli,
   11156             :                                     fnum,
   11157             :                                     0,
   11158             :                                     len_requested);
   11159             : 
   11160          64 :         if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
   11161           0 :                 return false;
   11162             :         }
   11163             : 
   11164          64 :         status = cli_read_andx_recv(subreq, &len_read, &buf);
   11165          64 :         if (!NT_STATUS_IS_OK(status)) {
   11166           0 :                 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
   11167           0 :                 return false;
   11168             :         }
   11169             : 
   11170          64 :         TALLOC_FREE(subreq);
   11171          64 :         TALLOC_FREE(ev);
   11172             : 
   11173          64 :         len_expected = calc_expected_return(cli, len_requested);
   11174             : 
   11175          64 :         if (len_expected > 0x10000 && len_read == 0x10000) {
   11176             :                 /* Windows servers only return a max of 0x10000,
   11177             :                    doesn't matter if you set CAP_LARGE_READX in
   11178             :                    the client sessionsetupX call or not. */
   11179          12 :                 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
   11180             :                         (unsigned int)len_requested);
   11181          52 :         } else if (len_read != len_expected) {
   11182           0 :                 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
   11183             :                         (unsigned int)len_requested,
   11184             :                         (unsigned int)len_read,
   11185             :                         (unsigned int)len_expected);
   11186           0 :                 return false;
   11187             :         } else {
   11188          52 :                 d_printf("Correct read reply.\n");
   11189             :         }
   11190             : 
   11191          64 :         return true;
   11192             : }
   11193             : 
   11194             : /* Test large readX variants. */
   11195           8 : static bool large_readx_tests(struct cli_state *cli,
   11196             :                                 uint16_t fnum,
   11197             :                                 uint8_t *buf)
   11198             : {
   11199             :         /* A read of 0xFFFF0001 should *always* return 1 byte. */
   11200           8 :         if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
   11201           0 :                 return false;
   11202             :         }
   11203             :         /* A read of 0x10000 should return 0x10000 bytes. */
   11204           8 :         if (check_read_call(cli, fnum, buf,    0x10000) == false) {
   11205           0 :                 return false;
   11206             :         }
   11207             :         /* A read of 0x10000 should return 0x10001 bytes. */
   11208           8 :         if (check_read_call(cli, fnum, buf,    0x10001) == false) {
   11209           0 :                 return false;
   11210             :         }
   11211             :         /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
   11212             :            the requested number of bytes. */
   11213           8 :         if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
   11214           0 :                 return false;
   11215             :         }
   11216             :         /* A read of 1MB should return 1MB bytes (on Samba). */
   11217           8 :         if (check_read_call(cli, fnum, buf,   0x100000) == false) {
   11218           0 :                 return false;
   11219             :         }
   11220             : 
   11221           8 :         if (check_read_call(cli, fnum, buf,    0x20001) == false) {
   11222           0 :                 return false;
   11223             :         }
   11224           8 :         if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
   11225           0 :                 return false;
   11226             :         }
   11227           8 :         if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
   11228           0 :                 return false;
   11229             :         }
   11230           8 :         return true;
   11231             : }
   11232             : 
   11233           5 : static bool run_large_readx(int dummy)
   11234             : {
   11235           5 :         uint8_t *buf = NULL;
   11236           5 :         struct cli_state *cli1 = NULL;
   11237           5 :         struct cli_state *cli2 = NULL;
   11238           5 :         bool correct = false;
   11239           5 :         const char *fname = "\\large_readx.dat";
   11240             :         NTSTATUS status;
   11241           5 :         uint16_t fnum1 = UINT16_MAX;
   11242           5 :         uint32_t normal_caps = 0;
   11243           5 :         size_t file_size = 20*1024*1024;
   11244           5 :         TALLOC_CTX *frame = talloc_stackframe();
   11245             :         size_t i;
   11246             :         struct {
   11247             :                 const char *name;
   11248             :                 enum smb_signing_setting signing_setting;
   11249             :                 enum protocol_types protocol;
   11250           5 :         } runs[] = {
   11251             :                 {
   11252             :                         .name = "NT1",
   11253             :                         .signing_setting = SMB_SIGNING_IF_REQUIRED,
   11254             :                         .protocol = PROTOCOL_NT1,
   11255             :                 },{
   11256             :                         .name = "NT1 - SIGNING_REQUIRED",
   11257             :                         .signing_setting = SMB_SIGNING_REQUIRED,
   11258             :                         .protocol = PROTOCOL_NT1,
   11259             :                 },
   11260             :         };
   11261             : 
   11262           5 :         printf("starting large_readx test\n");
   11263             : 
   11264           5 :         if (!torture_open_connection(&cli1, 0)) {
   11265           0 :                 goto out;
   11266             :         }
   11267             : 
   11268           5 :         normal_caps = smb1cli_conn_capabilities(cli1->conn);
   11269             : 
   11270           5 :         if (!(normal_caps & CAP_LARGE_READX)) {
   11271           0 :                 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11272             :                         (unsigned int)normal_caps);
   11273           0 :                 goto out;
   11274             :         }
   11275             : 
   11276             :         /* Create a file of size 4MB. */
   11277           5 :         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
   11278             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11279             :                         0, 0, &fnum1, NULL);
   11280             : 
   11281           5 :         if (!NT_STATUS_IS_OK(status)) {
   11282           0 :                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
   11283           0 :                 goto out;
   11284             :         }
   11285             : 
   11286             :         /* Write file_size bytes. */
   11287           5 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11288           5 :         if (buf == NULL) {
   11289           0 :                 goto out;
   11290             :         }
   11291             : 
   11292           5 :         status = cli_writeall(cli1,
   11293             :                               fnum1,
   11294             :                               0,
   11295             :                               buf,
   11296             :                               0,
   11297             :                               file_size,
   11298             :                               NULL);
   11299           5 :         if (!NT_STATUS_IS_OK(status)) {
   11300           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11301           0 :                 goto out;
   11302             :         }
   11303             : 
   11304           5 :         status = cli_close(cli1, fnum1);
   11305           5 :         if (!NT_STATUS_IS_OK(status)) {
   11306           0 :                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11307           0 :                 goto out;
   11308             :         }
   11309             : 
   11310           5 :         fnum1 = UINT16_MAX;
   11311             : 
   11312          15 :         for (i=0; i < ARRAY_SIZE(runs); i++) {
   11313          10 :                 enum smb_signing_setting saved_signing_setting = signing_state;
   11314          10 :                 uint16_t fnum2 = -1;
   11315             : 
   11316          14 :                 if (do_encrypt &&
   11317           4 :                     (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
   11318             :                 {
   11319           2 :                         d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
   11320           2 :                         continue;
   11321             :                 }
   11322             : 
   11323           8 :                 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
   11324             : 
   11325           8 :                 signing_state = runs[i].signing_setting;
   11326           8 :                 cli2 = open_nbt_connection();
   11327           8 :                 signing_state = saved_signing_setting;
   11328           8 :                 if (cli2 == NULL) {
   11329           0 :                         goto out;
   11330             :                 }
   11331             : 
   11332          16 :                 status = smbXcli_negprot(cli2->conn,
   11333           8 :                                          cli2->timeout,
   11334             :                                          runs[i].protocol,
   11335             :                                          runs[i].protocol);
   11336           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11337           0 :                         goto out;
   11338             :                 }
   11339             : 
   11340           8 :                 status = cli_session_setup_creds(cli2, torture_creds);
   11341           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11342           0 :                         goto out;
   11343             :                 }
   11344             : 
   11345           8 :                 status = cli_tree_connect(cli2,
   11346             :                                         share,
   11347             :                                         "?????",
   11348             :                                         password);
   11349           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11350           0 :                         goto out;
   11351             :                 }
   11352             : 
   11353           8 :                 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
   11354             : 
   11355           8 :                 normal_caps = smb1cli_conn_capabilities(cli2->conn);
   11356             : 
   11357           8 :                 if (!(normal_caps & CAP_LARGE_READX)) {
   11358           0 :                         d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
   11359             :                                 (unsigned int)normal_caps);
   11360           0 :                         goto out;
   11361             :                 }
   11362             : 
   11363           8 :                 if (do_encrypt) {
   11364           2 :                         if (force_cli_encryption(cli2, share) == false) {
   11365           0 :                                 goto out;
   11366             :                         }
   11367           6 :                 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
   11368             :                         uint16_t major, minor;
   11369             :                         uint32_t caplow, caphigh;
   11370             : 
   11371           4 :                         status = cli_unix_extensions_version(cli2,
   11372             :                                                              &major, &minor,
   11373             :                                                              &caplow, &caphigh);
   11374           4 :                         if (!NT_STATUS_IS_OK(status)) {
   11375           0 :                                 goto out;
   11376             :                         }
   11377             :                 }
   11378             : 
   11379           8 :                 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
   11380             :                                 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
   11381             :                                 0, 0, &fnum2, NULL);
   11382           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11383           0 :                         d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
   11384           0 :                         goto out;
   11385             :                 }
   11386             : 
   11387             :                 /* All reads must return less than file_size bytes. */
   11388           8 :                 if (!large_readx_tests(cli2, fnum2, buf)) {
   11389           0 :                         goto out;
   11390             :                 }
   11391             : 
   11392           8 :                 status = cli_close(cli2, fnum2);
   11393           8 :                 if (!NT_STATUS_IS_OK(status)) {
   11394           0 :                         d_printf("cli_close failed: %s\n", nt_errstr(status));
   11395           0 :                         goto out;
   11396             :                 }
   11397           8 :                 fnum2 = -1;
   11398             : 
   11399           8 :                 if (!torture_close_connection(cli2)) {
   11400           0 :                         goto out;
   11401             :                 }
   11402           8 :                 cli2 = NULL;
   11403             :         }
   11404             : 
   11405           5 :         correct = true;
   11406           5 :         printf("Success on large_readx test\n");
   11407             : 
   11408           5 :   out:
   11409             : 
   11410           5 :         if (cli2) {
   11411           0 :                 if (!torture_close_connection(cli2)) {
   11412           0 :                         correct = false;
   11413             :                 }
   11414             :         }
   11415             : 
   11416           5 :         if (cli1) {
   11417           5 :                 if (fnum1 != UINT16_MAX) {
   11418           0 :                         status = cli_close(cli1, fnum1);
   11419           0 :                         if (!NT_STATUS_IS_OK(status)) {
   11420           0 :                                 d_printf("cli_close failed: %s\n", nt_errstr(status));
   11421             :                         }
   11422           0 :                         fnum1 = UINT16_MAX;
   11423             :                 }
   11424             : 
   11425           5 :                 status = cli_unlink(cli1, fname,
   11426             :                                     FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11427           5 :                 if (!NT_STATUS_IS_OK(status)) {
   11428           0 :                         printf("unlink failed (%s)\n", nt_errstr(status));
   11429             :                 }
   11430             : 
   11431           5 :                 if (!torture_close_connection(cli1)) {
   11432           0 :                         correct = false;
   11433             :                 }
   11434             :         }
   11435             : 
   11436           5 :         TALLOC_FREE(frame);
   11437             : 
   11438           5 :         printf("finished large_readx test\n");
   11439           5 :         return correct;
   11440             : }
   11441             : 
   11442          20 : static NTSTATUS msdfs_attribute_list_fn(struct file_info *finfo,
   11443             :                                   const char *mask,
   11444             :                                   void *private_data)
   11445             : {
   11446          20 :         uint32_t *p_attr = (uint32_t *)private_data;
   11447             : 
   11448          20 :         if (strequal(finfo->name, test_filename)) {
   11449           4 :                 *p_attr = finfo->attr;
   11450             :         }
   11451             : 
   11452          20 :         return NT_STATUS_OK;
   11453             : }
   11454             : 
   11455           4 : static bool run_msdfs_attribute(int dummy)
   11456             : {
   11457             :         static struct cli_state *cli;
   11458           4 :         bool correct = false;
   11459           4 :         uint32_t attr = 0;
   11460             :         NTSTATUS status;
   11461             : 
   11462           4 :         printf("Starting MSDFS-ATTRIBUTE test\n");
   11463             : 
   11464           4 :         if (test_filename == NULL || test_filename[0] == '\0') {
   11465           0 :                 printf("MSDFS-ATTRIBUTE test "
   11466             :                         "needs -f filename-of-msdfs-link\n");
   11467           0 :                 return false;
   11468             :         }
   11469             : 
   11470             :         /*
   11471             :          * NB. We use torture_open_connection_flags() not
   11472             :          * torture_open_connection() as the latter forces
   11473             :          * SMB1.
   11474             :          */
   11475           4 :         if (!torture_open_connection_flags(&cli, 0, 0)) {
   11476           0 :                 return false;
   11477             :         }
   11478             : 
   11479           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11480             : 
   11481           4 :         status = cli_list(cli,
   11482             :                         "*",
   11483             :                         FILE_ATTRIBUTE_DIRECTORY,
   11484             :                         msdfs_attribute_list_fn,
   11485             :                         &attr);
   11486             : 
   11487           4 :         if (!NT_STATUS_IS_OK(status)) {
   11488           0 :                 printf("cli_list failed with %s\n",
   11489             :                         nt_errstr(status));
   11490           0 :                 goto out;
   11491             :         }
   11492           4 :         if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
   11493           0 :                 printf("file %s should have "
   11494             :                         "FILE_ATTRIBUTE_REPARSE_POINT set. attr = 0x%x\n",
   11495             :                         test_filename,
   11496             :                         (unsigned int)attr);
   11497           0 :                 goto out;
   11498             :         }
   11499             : 
   11500           4 :         if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
   11501           0 :                 printf("file %s should have "
   11502             :                         "FILE_ATTRIBUTE_DIRECTORY set. attr = 0x%x\n",
   11503             :                         test_filename,
   11504             :                         (unsigned int)attr);
   11505           0 :                 goto out;
   11506             :         }
   11507             : 
   11508           4 :         correct = true;
   11509             : 
   11510           4 :   out:
   11511             : 
   11512           4 :         torture_close_connection(cli);
   11513           4 :         return correct;
   11514             : }
   11515             : 
   11516           0 : static bool run_cli_echo(int dummy)
   11517             : {
   11518             :         struct cli_state *cli;
   11519             :         NTSTATUS status;
   11520             : 
   11521           0 :         printf("starting cli_echo test\n");
   11522           0 :         if (!torture_open_connection(&cli, 0)) {
   11523           0 :                 return false;
   11524             :         }
   11525           0 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11526             : 
   11527           0 :         status = cli_echo(cli, 5, data_blob_const("hello", 5));
   11528             : 
   11529           0 :         d_printf("cli_echo returned %s\n", nt_errstr(status));
   11530             : 
   11531           0 :         torture_close_connection(cli);
   11532           0 :         return NT_STATUS_IS_OK(status);
   11533             : }
   11534             : 
   11535          14 : static int splice_status(off_t written, void *priv)
   11536             : {
   11537          14 :         return true;
   11538             : }
   11539             : 
   11540           7 : static bool run_cli_splice(int dummy)
   11541             : {
   11542           7 :         uint8_t *buf = NULL;
   11543           7 :         struct cli_state *cli1 = NULL;
   11544           7 :         bool correct = false;
   11545           7 :         const char *fname_src = "\\splice_src.dat";
   11546           7 :         const char *fname_dst = "\\splice_dst.dat";
   11547             :         NTSTATUS status;
   11548           7 :         uint16_t fnum1 = UINT16_MAX;
   11549           7 :         uint16_t fnum2 = UINT16_MAX;
   11550           7 :         size_t file_size = 2*1024*1024;
   11551           7 :         size_t splice_size = 1*1024*1024 + 713;
   11552             :         uint8_t digest1[16], digest2[16];
   11553           7 :         off_t written = 0;
   11554           7 :         size_t nread = 0;
   11555           7 :         TALLOC_CTX *frame = talloc_stackframe();
   11556             : 
   11557           7 :         printf("starting cli_splice test\n");
   11558             : 
   11559           7 :         if (!torture_open_connection(&cli1, 0)) {
   11560           0 :                 goto out;
   11561             :         }
   11562             : 
   11563           7 :         cli_unlink(cli1, fname_src,
   11564             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11565           7 :         cli_unlink(cli1, fname_dst,
   11566             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11567             : 
   11568             :         /* Create a file */
   11569           7 :         status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
   11570             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11571             :                         0, 0, &fnum1, NULL);
   11572             : 
   11573           7 :         if (!NT_STATUS_IS_OK(status)) {
   11574           0 :                 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
   11575           0 :                 goto out;
   11576             :         }
   11577             : 
   11578             :         /* Write file_size bytes - must be bigger than splice_size. */
   11579           7 :         buf = talloc_zero_array(frame, uint8_t, file_size);
   11580           7 :         if (buf == NULL) {
   11581           0 :                 d_printf("talloc_fail\n");
   11582           0 :                 goto out;
   11583             :         }
   11584             : 
   11585             :         /* Fill it with random numbers. */
   11586           7 :         generate_random_buffer(buf, file_size);
   11587             : 
   11588             :         /* MD5 the first 1MB + 713 bytes. */
   11589           7 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11590             :                          buf,
   11591             :                          splice_size,
   11592             :                          digest1);
   11593             : 
   11594           7 :         status = cli_writeall(cli1,
   11595             :                               fnum1,
   11596             :                               0,
   11597             :                               buf,
   11598             :                               0,
   11599             :                               file_size,
   11600             :                               NULL);
   11601           7 :         if (!NT_STATUS_IS_OK(status)) {
   11602           0 :                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
   11603           0 :                 goto out;
   11604             :         }
   11605             : 
   11606           7 :         status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
   11607             :                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
   11608             :                         0, 0, &fnum2, NULL);
   11609             : 
   11610           7 :         if (!NT_STATUS_IS_OK(status)) {
   11611           0 :                 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
   11612           0 :                 goto out;
   11613             :         }
   11614             : 
   11615             :         /* Now splice 1MB + 713 bytes. */
   11616           7 :         status = cli_splice(cli1,
   11617             :                                 cli1,
   11618             :                                 fnum1,
   11619             :                                 fnum2,
   11620             :                                 splice_size,
   11621             :                                 0,
   11622             :                                 0,
   11623             :                                 &written,
   11624             :                                 splice_status,
   11625             :                                 NULL);
   11626             : 
   11627           7 :         if (!NT_STATUS_IS_OK(status)) {
   11628           0 :                 d_printf("cli_splice failed: %s\n", nt_errstr(status));
   11629           0 :                 goto out;
   11630             :         }
   11631             : 
   11632             :         /* Clear the old buffer. */
   11633           7 :         memset(buf, '\0', file_size);
   11634             : 
   11635             :         /* Read the new file. */
   11636           7 :         status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
   11637           7 :         if (!NT_STATUS_IS_OK(status)) {
   11638           0 :                 d_printf("cli_read failed: %s\n", nt_errstr(status));
   11639           0 :                 goto out;
   11640             :         }
   11641           7 :         if (nread != splice_size) {
   11642           0 :                 d_printf("bad read of 0x%x, should be 0x%x\n",
   11643             :                         (unsigned int)nread,
   11644             :                         (unsigned int)splice_size);
   11645           0 :                 goto out;
   11646             :         }
   11647             : 
   11648             :         /* MD5 the first 1MB + 713 bytes. */
   11649           7 :         gnutls_hash_fast(GNUTLS_DIG_MD5,
   11650             :                          buf,
   11651             :                          splice_size,
   11652             :                          digest2);
   11653             : 
   11654             :         /* Must be the same. */
   11655           7 :         if (memcmp(digest1, digest2, 16) != 0) {
   11656           0 :                 d_printf("bad MD5 compare\n");
   11657           0 :                 goto out;
   11658             :         }
   11659             : 
   11660           7 :         correct = true;
   11661           7 :         printf("Success on cli_splice test\n");
   11662             : 
   11663           7 :   out:
   11664             : 
   11665           7 :         if (cli1) {
   11666           7 :                 if (fnum1 != UINT16_MAX) {
   11667           7 :                         cli_close(cli1, fnum1);
   11668             :                 }
   11669           7 :                 if (fnum2 != UINT16_MAX) {
   11670           7 :                         cli_close(cli1, fnum2);
   11671             :                 }
   11672             : 
   11673           7 :                 cli_unlink(cli1, fname_src,
   11674             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11675           7 :                 cli_unlink(cli1, fname_dst,
   11676             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11677             : 
   11678           7 :                 if (!torture_close_connection(cli1)) {
   11679           0 :                         correct = false;
   11680             :                 }
   11681             :         }
   11682             : 
   11683           7 :         TALLOC_FREE(frame);
   11684           7 :         return correct;
   11685             : }
   11686             : 
   11687           4 : static bool run_uid_regression_test(int dummy)
   11688             : {
   11689             :         static struct cli_state *cli;
   11690             :         int16_t old_vuid;
   11691             :         int32_t old_cnum;
   11692           4 :         bool correct = True;
   11693           4 :         struct smbXcli_tcon *tcon_copy = NULL;
   11694             :         NTSTATUS status;
   11695             : 
   11696           4 :         printf("starting uid regression test\n");
   11697             : 
   11698           4 :         if (!torture_open_connection(&cli, 0)) {
   11699           0 :                 return False;
   11700             :         }
   11701             : 
   11702           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11703             : 
   11704             :         /* Ok - now save then logoff our current user. */
   11705           4 :         old_vuid = cli_state_get_uid(cli);
   11706             : 
   11707           4 :         status = cli_ulogoff(cli);
   11708           4 :         if (!NT_STATUS_IS_OK(status)) {
   11709           0 :                 d_printf("(%s) cli_ulogoff failed: %s\n",
   11710             :                          __location__, nt_errstr(status));
   11711           0 :                 correct = false;
   11712           0 :                 goto out;
   11713             :         }
   11714             : 
   11715           4 :         cli_state_set_uid(cli, old_vuid);
   11716             : 
   11717             :         /* Try an operation. */
   11718           4 :         status = cli_mkdir(cli, "\\uid_reg_test");
   11719           4 :         if (NT_STATUS_IS_OK(status)) {
   11720           0 :                 d_printf("(%s) cli_mkdir succeeded\n",
   11721             :                          __location__);
   11722           0 :                 correct = false;
   11723           0 :                 goto out;
   11724             :         } else {
   11725             :                 /* Should be bad uid. */
   11726           4 :                 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
   11727           4 :                                  NT_STATUS_USER_SESSION_DELETED)) {
   11728           0 :                         correct = false;
   11729           0 :                         goto out;
   11730             :                 }
   11731             :         }
   11732             : 
   11733           4 :         old_cnum = cli_state_get_tid(cli);
   11734             :         /*
   11735             :          * This is an SMB1-only test.
   11736             :          * Copy the tcon, not "save/restore".
   11737             :          *
   11738             :          * In SMB1 the cli_tdis() below frees
   11739             :          * cli->smb1.tcon so we need a copy
   11740             :          * of the struct to put back for the
   11741             :          * second tdis call with invalid vuid.
   11742             :          *
   11743             :          * This is a test-only hack. Real client code
   11744             :          * uses cli_state_save_tcon()/cli_state_restore_tcon().
   11745             :          */
   11746           4 :         tcon_copy = smbXcli_tcon_copy(cli, cli->smb1.tcon);
   11747           4 :         if (tcon_copy == NULL) {
   11748           0 :                 correct = false;
   11749           0 :                 goto out;
   11750             :         }
   11751             : 
   11752             :         /* Now try a SMBtdis with the invalid vuid set to zero. */
   11753           4 :         cli_state_set_uid(cli, 0);
   11754             : 
   11755             :         /* This should succeed. */
   11756           4 :         status = cli_tdis(cli);
   11757             : 
   11758           4 :         if (NT_STATUS_IS_OK(status)) {
   11759           4 :                 d_printf("First tdis with invalid vuid should succeed.\n");
   11760             :         } else {
   11761           0 :                 d_printf("First tdis failed (%s)\n", nt_errstr(status));
   11762           0 :                 correct = false;
   11763           0 :                 cli->smb1.tcon = tcon_copy;
   11764           0 :                 goto out;
   11765             :         }
   11766             : 
   11767           4 :         cli->smb1.tcon = tcon_copy;
   11768           4 :         cli_state_set_uid(cli, old_vuid);
   11769           4 :         cli_state_set_tid(cli, old_cnum);
   11770             : 
   11771             :         /* This should fail. */
   11772           4 :         status = cli_tdis(cli);
   11773           4 :         if (NT_STATUS_IS_OK(status)) {
   11774           0 :                 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
   11775           0 :                 correct = false;
   11776           0 :                 goto out;
   11777             :         } else {
   11778             :                 /* Should be bad tid. */
   11779           4 :                 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
   11780           4 :                                 NT_STATUS_NETWORK_NAME_DELETED)) {
   11781           0 :                         correct = false;
   11782           0 :                         goto out;
   11783             :                 }
   11784             :         }
   11785             : 
   11786           4 :         cli_rmdir(cli, "\\uid_reg_test");
   11787             : 
   11788           4 :   out:
   11789             : 
   11790           4 :         cli_shutdown(cli);
   11791           4 :         return correct;
   11792             : }
   11793             : 
   11794             : 
   11795             : static const char *illegal_chars = "*\\/?<>|\":";
   11796             : static char force_shortname_chars[] = " +,.[];=\177";
   11797             : 
   11798           8 : static NTSTATUS shortname_del_fn(struct file_info *finfo,
   11799             :                              const char *mask, void *state)
   11800             : {
   11801           8 :         struct cli_state *pcli = (struct cli_state *)state;
   11802             :         fstring fname;
   11803           8 :         NTSTATUS status = NT_STATUS_OK;
   11804             : 
   11805           8 :         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
   11806             : 
   11807           8 :         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
   11808           8 :                 return NT_STATUS_OK;
   11809             : 
   11810           0 :         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
   11811           0 :                 status = cli_rmdir(pcli, fname);
   11812           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11813           0 :                         printf("del_fn: failed to rmdir %s\n,", fname );
   11814             :                 }
   11815             :         } else {
   11816           0 :                 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11817           0 :                 if (!NT_STATUS_IS_OK(status)) {
   11818           0 :                         printf("del_fn: failed to unlink %s\n,", fname );
   11819             :                 }
   11820             :         }
   11821           0 :         return status;
   11822             : }
   11823             : 
   11824             : struct sn_state {
   11825             :         int matched;
   11826             :         int i;
   11827             :         bool val;
   11828             : };
   11829             : 
   11830         348 : static NTSTATUS shortname_list_fn(struct file_info *finfo,
   11831             :                               const char *name, void *state)
   11832             : {
   11833         348 :         struct sn_state *s = (struct sn_state  *)state;
   11834         348 :         int i = s->i;
   11835             : 
   11836             : #if 0
   11837             :         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
   11838             :                 i, finfo->name, finfo->short_name);
   11839             : #endif
   11840             : 
   11841         348 :         if (strchr(force_shortname_chars, i)) {
   11842          36 :                 if (!finfo->short_name) {
   11843             :                         /* Shortname not created when it should be. */
   11844           0 :                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
   11845             :                                 __location__, finfo->name, i);
   11846           0 :                         s->val = true;
   11847             :                 }
   11848         312 :         } else if (finfo->short_name){
   11849             :                 /* Shortname created when it should not be. */
   11850           0 :                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
   11851             :                         __location__, finfo->short_name, finfo->name);
   11852           0 :                 s->val = true;
   11853             :         }
   11854         348 :         s->matched += 1;
   11855         348 :         return NT_STATUS_OK;
   11856             : }
   11857             : 
   11858           4 : static bool run_shortname_test(int dummy)
   11859             : {
   11860             :         static struct cli_state *cli;
   11861           4 :         bool correct = True;
   11862             :         int i;
   11863             :         struct sn_state s;
   11864             :         char fname[40];
   11865             :         NTSTATUS status;
   11866             : 
   11867           4 :         printf("starting shortname test\n");
   11868             : 
   11869           4 :         if (!torture_open_connection(&cli, 0)) {
   11870           0 :                 return False;
   11871             :         }
   11872             : 
   11873           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   11874             : 
   11875           4 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   11876           4 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   11877           4 :         cli_rmdir(cli, "\\shortname");
   11878             : 
   11879           4 :         status = cli_mkdir(cli, "\\shortname");
   11880           4 :         if (!NT_STATUS_IS_OK(status)) {
   11881           0 :                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
   11882             :                         __location__, nt_errstr(status));
   11883           0 :                 correct = false;
   11884           0 :                 goto out;
   11885             :         }
   11886             : 
   11887           4 :         if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
   11888           0 :                 correct = false;
   11889           0 :                 goto out;
   11890             :         }
   11891           4 :         if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
   11892           0 :                 correct = false;
   11893           0 :                 goto out;
   11894             :         }
   11895             : 
   11896           4 :         s.val = false;
   11897             : 
   11898         388 :         for (i = 32; i < 128; i++) {
   11899         384 :                 uint16_t fnum = (uint16_t)-1;
   11900             : 
   11901         384 :                 s.i = i;
   11902             : 
   11903         384 :                 if (strchr(illegal_chars, i)) {
   11904          36 :                         continue;
   11905             :                 }
   11906         348 :                 fname[15] = i;
   11907             : 
   11908         348 :                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
   11909             :                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
   11910             :                                    FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
   11911         348 :                 if (!NT_STATUS_IS_OK(status)) {
   11912           0 :                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
   11913             :                                 __location__, fname, nt_errstr(status));
   11914           0 :                         correct = false;
   11915           0 :                         goto out;
   11916             :                 }
   11917         348 :                 cli_close(cli, fnum);
   11918             : 
   11919         348 :                 s.matched = 0;
   11920         348 :                 status = cli_list(cli, "\\shortname\\test*.*", 0,
   11921             :                                   shortname_list_fn, &s);
   11922         348 :                 if (s.matched != 1) {
   11923           0 :                         d_printf("(%s) failed to list %s: %s\n",
   11924             :                                 __location__, fname, nt_errstr(status));
   11925           0 :                         correct = false;
   11926           0 :                         goto out;
   11927             :                 }
   11928             : 
   11929         348 :                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   11930         348 :                 if (!NT_STATUS_IS_OK(status)) {
   11931           0 :                         d_printf("(%s) failed to delete %s: %s\n",
   11932             :                                 __location__, fname, nt_errstr(status));
   11933           0 :                         correct = false;
   11934           0 :                         goto out;
   11935             :                 }
   11936             : 
   11937         348 :                 if (s.val) {
   11938           0 :                         correct = false;
   11939           0 :                         goto out;
   11940             :                 }
   11941             :         }
   11942             : 
   11943           4 :   out:
   11944             : 
   11945           4 :         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
   11946           4 :         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
   11947           4 :         cli_rmdir(cli, "\\shortname");
   11948           4 :         torture_close_connection(cli);
   11949           4 :         return correct;
   11950             : }
   11951             : 
   11952             : TLDAPRC callback_code;
   11953             : 
   11954         448 : static void pagedsearch_cb(struct tevent_req *req)
   11955             : {
   11956             :         TLDAPRC rc;
   11957             :         struct tldap_message *msg;
   11958             :         char *dn;
   11959             : 
   11960         448 :         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
   11961         448 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   11962           0 :                 d_printf("tldap_search_paged_recv failed: %s\n",
   11963             :                          tldap_rc2string(rc));
   11964           0 :                 callback_code = rc;
   11965           4 :                 return;
   11966             :         }
   11967         448 :         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
   11968           8 :                 TALLOC_FREE(msg);
   11969           8 :                 return;
   11970             :         }
   11971         440 :         if (!tldap_entry_dn(msg, &dn)) {
   11972           0 :                 d_printf("tldap_entry_dn failed\n");
   11973           0 :                 return;
   11974             :         }
   11975         440 :         d_printf("%s\n", dn);
   11976         440 :         TALLOC_FREE(msg);
   11977             : }
   11978             : 
   11979             : enum tldap_extended_val {
   11980             :         EXTENDED_ZERO = 0,
   11981             :         EXTENDED_ONE = 1,
   11982             :         EXTENDED_NONE = 2,
   11983             : };
   11984             : 
   11985             : /*
   11986             :  * Construct an extended dn control with either no value, 0 or 1
   11987             :  *
   11988             :  * No value and 0 are equivalent (non-hyphenated GUID)
   11989             :  * 1 has the hyphenated GUID
   11990             :  */
   11991             : static struct tldap_control *
   11992           6 : tldap_build_extended_control(enum tldap_extended_val val)
   11993             : {
   11994             :         struct tldap_control empty_control;
   11995             :         struct asn1_data *data;
   11996             : 
   11997           6 :         ZERO_STRUCT(empty_control);
   11998             : 
   11999           6 :         if (val != EXTENDED_NONE) {
   12000           4 :                 data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
   12001             : 
   12002           4 :                 if (!data) {
   12003           0 :                         return NULL;
   12004             :                 }
   12005             : 
   12006           4 :                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
   12007           0 :                         return NULL;
   12008             :                 }
   12009             : 
   12010           4 :                 if (!asn1_write_Integer(data, (int)val)) {
   12011           0 :                         return NULL;
   12012             :                 }
   12013             : 
   12014           4 :                 if (!asn1_pop_tag(data)) {
   12015           0 :                         return NULL;
   12016             :                 }
   12017             : 
   12018           4 :                 if (!asn1_blob(data, &empty_control.value)) {
   12019           0 :                         return NULL;
   12020             :                 }
   12021             :         }
   12022             : 
   12023           6 :         empty_control.oid = "1.2.840.113556.1.4.529";
   12024           6 :         empty_control.critical = true;
   12025             : 
   12026           6 :         return tldap_add_control(talloc_tos(), NULL, 0, &empty_control);
   12027             : 
   12028             : }
   12029             : 
   12030           6 : static bool tldap_test_dn_guid_format(struct tldap_context *ld, const char *basedn,
   12031             :                                       enum tldap_extended_val control_val)
   12032             : {
   12033           6 :         struct tldap_control *control = tldap_build_extended_control(control_val);
   12034           6 :         char *dn = NULL;
   12035             :         struct tldap_message **msg;
   12036             :         TLDAPRC rc;
   12037             : 
   12038           6 :         rc = tldap_search(ld, basedn, TLDAP_SCOPE_BASE,
   12039             :                           "(objectClass=*)", NULL, 0, 0,
   12040             :                           control, 1, NULL,
   12041             :                           0, 0, 0, 0, talloc_tos(), &msg);
   12042           6 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12043           0 :                 d_printf("tldap_search for domain DN failed: %s\n",
   12044             :                          tldap_errstr(talloc_tos(), ld, rc));
   12045           0 :                 return false;
   12046             :         }
   12047             : 
   12048           6 :         if (!tldap_entry_dn(msg[0], &dn)) {
   12049           0 :                 d_printf("tldap_search domain DN fetch failed: %s\n",
   12050             :                          tldap_errstr(talloc_tos(), ld, rc));
   12051           0 :                 return false;
   12052             :         }
   12053             : 
   12054           6 :         d_printf("%s\n", dn);
   12055             :         {
   12056             :                 uint32_t time_low;
   12057             :                 uint32_t time_mid, time_hi_and_version;
   12058             :                 uint32_t clock_seq[2];
   12059             :                 uint32_t node[6];
   12060             :                 char next;
   12061             : 
   12062           6 :                 switch (control_val) {
   12063           4 :                 case EXTENDED_NONE:
   12064             :                 case EXTENDED_ZERO:
   12065             :                         /*
   12066             :                          * When reading GUIDs with hyphens, scanf will treat
   12067             :                          * hyphen as a hex character (and counts as part of the
   12068             :                          * width). This creates leftover GUID string which we
   12069             :                          * check will for with 'next' and closing '>'.
   12070             :                          */
   12071           4 :                         if (12 == sscanf(dn, "<GUID=%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x>%c",
   12072             :                                          &time_low, &time_mid,
   12073             :                                          &time_hi_and_version, &clock_seq[0],
   12074             :                                          &clock_seq[1], &node[0], &node[1],
   12075             :                                          &node[2], &node[3], &node[4],
   12076             :                                          &node[5], &next)) {
   12077             :                                 /* This GUID is good */
   12078             :                         } else {
   12079           0 :                                 d_printf("GUID format in control (no hyphens) doesn't match output\n");
   12080           0 :                                 return false;
   12081             :                         }
   12082             : 
   12083           4 :                         break;
   12084           2 :                 case EXTENDED_ONE:
   12085           2 :                         if (12 == sscanf(dn,
   12086             :                                          "<GUID=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x>%c",
   12087             :                                          &time_low, &time_mid,
   12088             :                                          &time_hi_and_version, &clock_seq[0],
   12089             :                                          &clock_seq[1], &node[0], &node[1],
   12090             :                                          &node[2], &node[3], &node[4],
   12091             :                                          &node[5], &next)) {
   12092             :                                 /* This GUID is good */
   12093             :                         } else {
   12094           0 :                                 d_printf("GUID format in control (with hyphens) doesn't match output\n");
   12095           0 :                                 return false;
   12096             :                         }
   12097             : 
   12098           2 :                         break;
   12099           0 :                 default:
   12100           0 :                         return false;
   12101             :                 }
   12102             :         }
   12103             : 
   12104           6 :         return true;
   12105             : }
   12106             : 
   12107           2 : static bool run_tldap(int dummy)
   12108             : {
   12109             :         struct tldap_context *ld;
   12110             :         int fd;
   12111             :         TLDAPRC rc;
   12112             :         NTSTATUS status;
   12113             :         struct sockaddr_storage addr;
   12114             :         struct tevent_context *ev;
   12115             :         struct tevent_req *req;
   12116             :         char *basedn;
   12117             :         const char *filter;
   12118             : 
   12119           2 :         if (!resolve_name(host, &addr, 0, false)) {
   12120           0 :                 d_printf("could not find host %s\n", host);
   12121           0 :                 return false;
   12122             :         }
   12123           2 :         status = open_socket_out(&addr, 389, 9999, &fd);
   12124           2 :         if (!NT_STATUS_IS_OK(status)) {
   12125           0 :                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
   12126           0 :                 return false;
   12127             :         }
   12128             : 
   12129           2 :         ld = tldap_context_create(talloc_tos(), fd);
   12130           2 :         if (ld == NULL) {
   12131           0 :                 close(fd);
   12132           0 :                 d_printf("tldap_context_create failed\n");
   12133           0 :                 return false;
   12134             :         }
   12135             : 
   12136           2 :         rc = tldap_fetch_rootdse(ld);
   12137           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12138           0 :                 d_printf("tldap_fetch_rootdse failed: %s\n",
   12139             :                          tldap_errstr(talloc_tos(), ld, rc));
   12140           0 :                 return false;
   12141             :         }
   12142             : 
   12143           2 :         basedn = tldap_talloc_single_attribute(
   12144             :                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
   12145           2 :         if (basedn == NULL) {
   12146           0 :                 d_printf("no defaultNamingContext\n");
   12147           0 :                 return false;
   12148             :         }
   12149           2 :         d_printf("defaultNamingContext: %s\n", basedn);
   12150             : 
   12151           2 :         ev = samba_tevent_context_init(talloc_tos());
   12152           2 :         if (ev == NULL) {
   12153           0 :                 d_printf("tevent_context_init failed\n");
   12154           0 :                 return false;
   12155             :         }
   12156             : 
   12157           2 :         rc = tldap_gensec_bind(ld, torture_creds, "ldap", host, NULL,
   12158             :                                loadparm_init_s3(talloc_tos(),
   12159             :                                                 loadparm_s3_helpers()),
   12160             :                                GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL);
   12161             : 
   12162           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12163           0 :                 d_printf("tldap_gensec_bind failed\n");
   12164           0 :                 return false;
   12165             :         }
   12166             : 
   12167           2 :         callback_code = TLDAP_SUCCESS;
   12168             : 
   12169           2 :         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
   12170             :                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
   12171             :                                       NULL, 0, 0,
   12172             :                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
   12173           2 :         if (req == NULL) {
   12174           0 :                 d_printf("tldap_search_paged_send failed\n");
   12175           0 :                 return false;
   12176             :         }
   12177           2 :         tevent_req_set_callback(req, pagedsearch_cb, NULL);
   12178             : 
   12179           2 :         tevent_req_poll(req, ev);
   12180             : 
   12181           2 :         TALLOC_FREE(req);
   12182             : 
   12183           2 :         rc = callback_code;
   12184             : 
   12185           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12186           0 :                 d_printf("tldap_search with paging failed: %s\n",
   12187             :                          tldap_errstr(talloc_tos(), ld, rc));
   12188           0 :                 return false;
   12189             :         }
   12190             : 
   12191             :         /* test search filters against rootDSE */
   12192           2 :         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
   12193             :                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
   12194             : 
   12195           2 :         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
   12196             :                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
   12197             :                           talloc_tos(), NULL);
   12198           2 :         if (!TLDAP_RC_IS_SUCCESS(rc)) {
   12199           0 :                 d_printf("tldap_search with complex filter failed: %s\n",
   12200             :                          tldap_errstr(talloc_tos(), ld, rc));
   12201           0 :                 return false;
   12202             :         }
   12203             : 
   12204             :         /*
   12205             :          * Tests to check for regression of:
   12206             :          *
   12207             :          * https://bugzilla.samba.org/show_bug.cgi?id=14029
   12208             :          *
   12209             :          * TLDAP used here to pick apart the original string DN (with GUID)
   12210             :          */
   12211           2 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_NONE)) {
   12212           0 :                 d_printf("tldap_search with extended dn (no val) failed: %s\n",
   12213             :                          tldap_errstr(talloc_tos(), ld, rc));
   12214           0 :                 return false;
   12215             :         }
   12216           2 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ZERO)) {
   12217           0 :                 d_printf("tldap_search with extended dn (0) failed: %s\n",
   12218             :                          tldap_errstr(talloc_tos(), ld, rc));
   12219           0 :                 return false;
   12220             :         }
   12221           2 :         if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ONE)) {
   12222           0 :                 d_printf("tldap_search with extended dn (1) failed: %s\n",
   12223             :                          tldap_errstr(talloc_tos(), ld, rc));
   12224           0 :                 return false;
   12225             :         }
   12226             : 
   12227           2 :         TALLOC_FREE(ld);
   12228           2 :         return true;
   12229             : }
   12230             : 
   12231             : /* Torture test to ensure no regression of :
   12232             : https://bugzilla.samba.org/show_bug.cgi?id=7084
   12233             : */
   12234             : 
   12235           4 : static bool run_dir_createtime(int dummy)
   12236             : {
   12237             :         struct cli_state *cli;
   12238           4 :         const char *dname = "\\testdir_createtime";
   12239           4 :         const char *fname = "\\testdir_createtime\\testfile";
   12240             :         NTSTATUS status;
   12241             :         struct timespec create_time;
   12242             :         struct timespec create_time1;
   12243             :         uint16_t fnum;
   12244           4 :         bool ret = false;
   12245             :         uint64_t ino;
   12246             : 
   12247           4 :         if (!torture_open_connection(&cli, 0)) {
   12248           0 :                 return false;
   12249             :         }
   12250             : 
   12251           4 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12252             :                 /* Ensure ino is zero, SMB2 gets a real one. */
   12253           0 :                 ino = 0;
   12254             :         } else {
   12255             :                 /* Ensure ino is -1, SMB1 never gets a real one. */
   12256           4 :                 ino = (uint64_t)-1;
   12257             :         }
   12258             : 
   12259           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12260           4 :         cli_rmdir(cli, dname);
   12261             : 
   12262           4 :         status = cli_mkdir(cli, dname);
   12263           4 :         if (!NT_STATUS_IS_OK(status)) {
   12264           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12265           0 :                 goto out;
   12266             :         }
   12267             : 
   12268           4 :         status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
   12269             :                                 NULL, NULL, &ino);
   12270           4 :         if (!NT_STATUS_IS_OK(status)) {
   12271           0 :                 printf("cli_qpathinfo2 returned %s\n",
   12272             :                        nt_errstr(status));
   12273           0 :                 goto out;
   12274             :         }
   12275             : 
   12276           4 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
   12277             :                 /* SMB2 should always return an inode. */
   12278           0 :                 if (ino == 0) {
   12279           0 :                         printf("SMB2 bad inode (0)\n");
   12280           0 :                         goto out;
   12281             :                 }
   12282             :         } else {
   12283             :                 /* SMB1 must always return zero here. */
   12284           4 :                 if (ino != 0) {
   12285           0 :                         printf("SMB1 bad inode (!0)\n");
   12286           0 :                         goto out;
   12287             :                 }
   12288             :         }
   12289             : 
   12290             :         /* Sleep 3 seconds, then create a file. */
   12291           4 :         sleep(3);
   12292             : 
   12293           4 :         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
   12294             :                          DENY_NONE, &fnum);
   12295           4 :         if (!NT_STATUS_IS_OK(status)) {
   12296           0 :                 printf("cli_openx failed: %s\n", nt_errstr(status));
   12297           0 :                 goto out;
   12298             :         }
   12299             : 
   12300           4 :         status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
   12301             :                                 NULL, NULL, NULL);
   12302           4 :         if (!NT_STATUS_IS_OK(status)) {
   12303           0 :                 printf("cli_qpathinfo2 (2) returned %s\n",
   12304             :                        nt_errstr(status));
   12305           0 :                 goto out;
   12306             :         }
   12307             : 
   12308           4 :         if (timespec_compare(&create_time1, &create_time)) {
   12309           0 :                 printf("run_dir_createtime: create time was updated (error)\n");
   12310             :         } else {
   12311           4 :                 printf("run_dir_createtime: create time was not updated (correct)\n");
   12312           4 :                 ret = true;
   12313             :         }
   12314             : 
   12315           4 :   out:
   12316             : 
   12317           4 :         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12318           4 :         cli_rmdir(cli, dname);
   12319           4 :         if (!torture_close_connection(cli)) {
   12320           0 :                 ret = false;
   12321             :         }
   12322           4 :         return ret;
   12323             : }
   12324             : 
   12325             : 
   12326           4 : static bool run_streamerror(int dummy)
   12327             : {
   12328             :         struct cli_state *cli;
   12329           4 :         const char *dname = "\\testdir_streamerror";
   12330           4 :         const char *streamname =
   12331             :                 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
   12332             :         NTSTATUS status;
   12333             :         time_t change_time, access_time, write_time;
   12334             :         off_t size;
   12335             :         uint16_t fnum;
   12336             :         uint32_t attr;
   12337           4 :         bool ret = true;
   12338             : 
   12339           4 :         if (!torture_open_connection(&cli, 0)) {
   12340           0 :                 return false;
   12341             :         }
   12342             : 
   12343           4 :         cli_unlink(cli, "\\testdir_streamerror\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12344           4 :         cli_rmdir(cli, dname);
   12345             : 
   12346           4 :         status = cli_mkdir(cli, dname);
   12347           4 :         if (!NT_STATUS_IS_OK(status)) {
   12348           0 :                 printf("mkdir failed: %s\n", nt_errstr(status));
   12349           0 :                 return false;
   12350             :         }
   12351             : 
   12352           4 :         status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
   12353             :                                 &write_time, &size, &attr);
   12354           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12355           0 :                 printf("pathinfo returned %s, expected "
   12356             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12357             :                        nt_errstr(status));
   12358           0 :                 ret = false;
   12359             :         }
   12360             : 
   12361           4 :         status = cli_ntcreate(cli, streamname, 0x16,
   12362             :                               FILE_READ_DATA|FILE_READ_EA|
   12363             :                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
   12364             :                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
   12365             :                               FILE_OPEN, 0, 0, &fnum, NULL);
   12366             : 
   12367           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   12368           0 :                 printf("ntcreate returned %s, expected "
   12369             :                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
   12370             :                        nt_errstr(status));
   12371           0 :                 ret = false;
   12372             :         }
   12373             : 
   12374             : 
   12375           4 :         cli_rmdir(cli, dname);
   12376           4 :         return ret;
   12377             : }
   12378             : 
   12379             : struct pidtest_state {
   12380             :         bool success;
   12381             :         uint16_t vwv[1];
   12382             :         DATA_BLOB data;
   12383             : };
   12384             : 
   12385             : static void pid_echo_done(struct tevent_req *subreq);
   12386             : 
   12387           4 : static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
   12388             :                         struct tevent_context *ev,
   12389             :                         struct cli_state *cli)
   12390             : {
   12391             :         struct tevent_req *req, *subreq;
   12392             :         struct pidtest_state *state;
   12393             : 
   12394           4 :         req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
   12395           4 :         if (req == NULL) {
   12396           0 :                 return NULL;
   12397             :         }
   12398             : 
   12399           4 :         SSVAL(state->vwv, 0, 1);
   12400           4 :         state->data = data_blob_const("hello", 5);
   12401             : 
   12402           8 :         subreq = smb1cli_req_send(state,
   12403             :                                 ev,
   12404             :                                 cli->conn,
   12405             :                                 SMBecho,
   12406             :                                 0, 0, /* *_flags */
   12407             :                                 0, 0, /* *_flags2 */
   12408           4 :                                 cli->timeout,
   12409             :                                 0xDEADBEEF, /* pid */
   12410             :                                 NULL, /* tcon */
   12411             :                                 NULL, /* session */
   12412           4 :                                 ARRAY_SIZE(state->vwv), state->vwv,
   12413           4 :                                 state->data.length, state->data.data);
   12414             : 
   12415           4 :         if (tevent_req_nomem(subreq, req)) {
   12416           0 :                 return tevent_req_post(req, ev);
   12417             :         }
   12418           4 :         tevent_req_set_callback(subreq, pid_echo_done, req);
   12419           4 :         return req;
   12420             : }
   12421             : 
   12422           4 : static void pid_echo_done(struct tevent_req *subreq)
   12423             : {
   12424           4 :         struct tevent_req *req = tevent_req_callback_data(
   12425             :                 subreq, struct tevent_req);
   12426           4 :         struct pidtest_state *state = tevent_req_data(
   12427             :                 req, struct pidtest_state);
   12428             :         NTSTATUS status;
   12429             :         uint32_t num_bytes;
   12430           4 :         uint8_t *bytes = NULL;
   12431           4 :         struct iovec *recv_iov = NULL;
   12432           4 :         uint8_t *phdr = NULL;
   12433           4 :         uint16_t pidlow = 0;
   12434           4 :         uint16_t pidhigh = 0;
   12435           4 :         struct smb1cli_req_expected_response expected[] = {
   12436             :         {
   12437             :                 .status = NT_STATUS_OK,
   12438             :                 .wct    = 1,
   12439             :         },
   12440             :         };
   12441             : 
   12442           4 :         status = smb1cli_req_recv(subreq, state,
   12443             :                                 &recv_iov,
   12444             :                                 &phdr,
   12445             :                                 NULL, /* pwct */
   12446             :                                 NULL, /* pvwv */
   12447             :                                 NULL, /* pvwv_offset */
   12448             :                                 &num_bytes,
   12449             :                                 &bytes,
   12450             :                                 NULL, /* pbytes_offset */
   12451             :                                 NULL, /* pinbuf */
   12452             :                                 expected, ARRAY_SIZE(expected));
   12453             : 
   12454           4 :         TALLOC_FREE(subreq);
   12455             : 
   12456           4 :         if (!NT_STATUS_IS_OK(status)) {
   12457           0 :                 tevent_req_nterror(req, status);
   12458           0 :                 return;
   12459             :         }
   12460             : 
   12461           4 :         if (num_bytes != state->data.length) {
   12462           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12463           0 :                 return;
   12464             :         }
   12465             : 
   12466           4 :         if (memcmp(bytes, state->data.data, num_bytes) != 0) {
   12467           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12468           0 :                 return;
   12469             :         }
   12470             : 
   12471             :         /* Check pid low/high == DEADBEEF */
   12472           4 :         pidlow = SVAL(phdr, HDR_PID);
   12473           4 :         if (pidlow != 0xBEEF){
   12474           0 :                 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
   12475             :                         (unsigned int)pidlow);
   12476           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12477           0 :                 return;
   12478             :         }
   12479           4 :         pidhigh = SVAL(phdr, HDR_PIDHIGH);
   12480           4 :         if (pidhigh != 0xDEAD){
   12481           0 :                 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
   12482             :                         (unsigned int)pidhigh);
   12483           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
   12484           0 :                 return;
   12485             :         }
   12486             : 
   12487           4 :         tevent_req_done(req);
   12488             : }
   12489             : 
   12490           4 : static NTSTATUS pid_echo_recv(struct tevent_req *req)
   12491             : {
   12492           4 :         return tevent_req_simple_recv_ntstatus(req);
   12493             : }
   12494             : 
   12495           4 : static bool run_pidhigh(int dummy)
   12496             : {
   12497           4 :         bool success = false;
   12498           4 :         struct cli_state *cli = NULL;
   12499             :         NTSTATUS status;
   12500           4 :         struct tevent_context *ev = NULL;
   12501           4 :         struct tevent_req *req = NULL;
   12502           4 :         TALLOC_CTX *frame = talloc_stackframe();
   12503             : 
   12504           4 :         printf("starting pid high test\n");
   12505           4 :         if (!torture_open_connection(&cli, 0)) {
   12506           0 :                 return false;
   12507             :         }
   12508           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12509             : 
   12510           4 :         ev = samba_tevent_context_init(frame);
   12511           4 :         if (ev == NULL) {
   12512           0 :                 goto fail;
   12513             :         }
   12514             : 
   12515           4 :         req = pid_echo_send(frame, ev, cli);
   12516           4 :         if (req == NULL) {
   12517           0 :                 goto fail;
   12518             :         }
   12519             : 
   12520           4 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
   12521           0 :                 goto fail;
   12522             :         }
   12523             : 
   12524           4 :         status = pid_echo_recv(req);
   12525           4 :         if (NT_STATUS_IS_OK(status)) {
   12526           4 :                 printf("pid high test ok\n");
   12527           4 :                 success = true;
   12528             :         }
   12529             : 
   12530           4 :  fail:
   12531             : 
   12532           4 :         TALLOC_FREE(frame);
   12533           4 :         torture_close_connection(cli);
   12534           4 :         return success;
   12535             : }
   12536             : 
   12537             : /*
   12538             :   Test Windows open on a bad POSIX symlink.
   12539             :  */
   12540           4 : static bool run_symlink_open_test(int dummy)
   12541             : {
   12542             :         static struct cli_state *cli;
   12543           4 :         const char *fname = "non_existant_file";
   12544           4 :         const char *sname = "dangling_symlink";
   12545           4 :         uint16_t fnum = (uint16_t)-1;
   12546           4 :         bool correct = false;
   12547             :         NTSTATUS status;
   12548           4 :         TALLOC_CTX *frame = NULL;
   12549             : 
   12550           4 :         frame = talloc_stackframe();
   12551             : 
   12552           4 :         printf("Starting Windows bad symlink open test\n");
   12553             : 
   12554           4 :         if (!torture_open_connection(&cli, 0)) {
   12555           0 :                 TALLOC_FREE(frame);
   12556           0 :                 return false;
   12557             :         }
   12558             : 
   12559           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12560             : 
   12561           4 :         status = torture_setup_unix_extensions(cli);
   12562           4 :         if (!NT_STATUS_IS_OK(status)) {
   12563           0 :                 TALLOC_FREE(frame);
   12564           0 :                 return false;
   12565             :         }
   12566             : 
   12567             :         /* Ensure nothing exists. */
   12568           4 :         cli_setatr(cli, fname, 0, 0);
   12569           4 :         cli_posix_unlink(cli, fname);
   12570           4 :         cli_setatr(cli, sname, 0, 0);
   12571           4 :         cli_posix_unlink(cli, sname);
   12572             : 
   12573             :         /* Create a symlink pointing nowhere. */
   12574           4 :         status = cli_posix_symlink(cli, fname, sname);
   12575           4 :         if (!NT_STATUS_IS_OK(status)) {
   12576           0 :                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
   12577             :                         sname,
   12578             :                         fname,
   12579             :                         nt_errstr(status));
   12580           0 :                 goto out;
   12581             :         }
   12582             : 
   12583             :         /* Now ensure that a Windows open doesn't hang. */
   12584           4 :         status = cli_ntcreate(cli,
   12585             :                         sname,
   12586             :                         0,
   12587             :                         FILE_READ_DATA|FILE_WRITE_DATA,
   12588             :                         0,
   12589             :                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
   12590             :                         FILE_OPEN_IF,
   12591             :                         0x0,
   12592             :                         0x0,
   12593             :                         &fnum,
   12594             :                         NULL);
   12595             : 
   12596             :         /*
   12597             :          * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
   12598             :          * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
   12599             :          * we use O_NOFOLLOW on the server or not.
   12600             :          */
   12601           8 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
   12602           4 :             NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
   12603             :         {
   12604           4 :                 correct = true;
   12605             :         } else {
   12606           0 :                 printf("cli_ntcreate of %s returned %s - should return"
   12607             :                                 " either (%s) or (%s)\n",
   12608             :                         sname,
   12609             :                         nt_errstr(status),
   12610           0 :                         nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
   12611           0 :                         nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
   12612           0 :                 goto out;
   12613             :         }
   12614             : 
   12615           4 :         correct = true;
   12616             : 
   12617           4 :   out:
   12618             : 
   12619           4 :         if (fnum != (uint16_t)-1) {
   12620           0 :                 cli_close(cli, fnum);
   12621           0 :                 fnum = (uint16_t)-1;
   12622             :         }
   12623             : 
   12624           4 :         cli_setatr(cli, sname, 0, 0);
   12625           4 :         cli_posix_unlink(cli, sname);
   12626           4 :         cli_setatr(cli, fname, 0, 0);
   12627           4 :         cli_posix_unlink(cli, fname);
   12628             : 
   12629           4 :         if (!torture_close_connection(cli)) {
   12630           0 :                 correct = false;
   12631             :         }
   12632             : 
   12633           4 :         TALLOC_FREE(frame);
   12634           4 :         return correct;
   12635             : }
   12636             : 
   12637          16 : static NTSTATUS smb1_wild_mangle_list_fn(struct file_info *finfo,
   12638             :                                         const char *name,
   12639             :                                         void *state)
   12640             : {
   12641          16 :         char **mangled_name_return = (char **)state;
   12642          16 :         bool is_mangled = strchr(finfo->name, '~');
   12643             : 
   12644          16 :         if (is_mangled) {
   12645           8 :                 *mangled_name_return = talloc_strdup(NULL, finfo->name);
   12646           8 :                 if (*mangled_name_return == NULL) {
   12647           0 :                         return NT_STATUS_NO_MEMORY;
   12648             :                 }
   12649             :         }
   12650          16 :         return NT_STATUS_OK;
   12651             : }
   12652             : 
   12653           4 : static bool run_smb1_wild_mangle_unlink_test(int dummy)
   12654             : {
   12655             :         static struct cli_state *cli_posix = NULL;
   12656             :         static struct cli_state *cli = NULL;
   12657           4 :         uint16_t fnum = (uint16_t)-1;
   12658           4 :         bool correct = false;
   12659           4 :         const char *dname = "smb1_wild_mangle_unlink";
   12660           4 :         const char *aname = "smb1_wild_mangle_unlink/a";
   12661           4 :         const char *star_name = "smb1_wild_mangle_unlink/*";
   12662           4 :         char *windows_unlink_name = NULL;
   12663           4 :         char *mangled_name = NULL;
   12664             :         NTSTATUS status;
   12665             : 
   12666           4 :         printf("Starting SMB1 wild mangle unlink test\n");
   12667             : 
   12668             :         /* Open a Windows connection. */
   12669           4 :         if (!torture_open_connection(&cli, 0)) {
   12670           0 :                 return false;
   12671             :         }
   12672             : 
   12673           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12674             : 
   12675             :         /* Open a POSIX connection. */
   12676           4 :         if (!torture_open_connection(&cli_posix, 0)) {
   12677           0 :                 goto out;
   12678             :         }
   12679             : 
   12680           4 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   12681             : 
   12682           4 :         status = torture_setup_unix_extensions(cli_posix);
   12683           4 :         if (!NT_STATUS_IS_OK(status)) {
   12684           0 :                 printf("server doesn't support POSIX\n");
   12685           0 :                 goto out;
   12686             :         }
   12687             : 
   12688             :         /* Start fresh. */
   12689           4 :         cli_unlink(cli,
   12690             :                 star_name,
   12691             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12692           4 :         cli_rmdir(cli, dname);
   12693             : 
   12694             :         /*
   12695             :          * Create two files - 'a' and '*'.
   12696             :          * We need POSIX extensions for this as '*'
   12697             :          * is not a valid Windows name.
   12698             :          */
   12699             : 
   12700           4 :         status = cli_mkdir(cli, dname);
   12701           4 :         if (!NT_STATUS_IS_OK(status)) {
   12702           0 :                 printf("cli_mkdir of %s returned %s\n",
   12703             :                         dname,
   12704             :                         nt_errstr(status));
   12705           0 :                 goto out;
   12706             :         }
   12707             : 
   12708           4 :         status = cli_posix_open(cli_posix,
   12709             :                                 aname,
   12710             :                                 O_RDWR|O_CREAT|O_EXCL,
   12711             :                                 0660,
   12712             :                                 &fnum);
   12713           4 :         if (!NT_STATUS_IS_OK(status)) {
   12714           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12715             :                         aname,
   12716             :                         nt_errstr(status));
   12717           0 :                 goto out;
   12718             :         }
   12719           4 :         status = cli_close(cli_posix, fnum);
   12720           4 :         if (!NT_STATUS_IS_OK(status)) {
   12721           0 :                 goto out;
   12722             :         }
   12723           4 :         status = cli_posix_open(cli_posix,
   12724             :                                 star_name,
   12725             :                                 O_RDWR|O_CREAT|O_EXCL,
   12726             :                                 0660,
   12727             :                                 &fnum);
   12728           4 :         if (!NT_STATUS_IS_OK(status)) {
   12729           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12730             :                         star_name,
   12731             :                         nt_errstr(status));
   12732           0 :                 goto out;
   12733             :         }
   12734           4 :         status = cli_close(cli_posix, fnum);
   12735           4 :         if (!NT_STATUS_IS_OK(status)) {
   12736           0 :                 goto out;
   12737             :         }
   12738             : 
   12739           4 :         status = cli_list(cli,
   12740             :                         star_name,
   12741             :                         0,
   12742             :                         smb1_wild_mangle_list_fn,
   12743             :                         &mangled_name);
   12744           4 :         if (!NT_STATUS_IS_OK(status)) {
   12745           0 :                 printf("cli_list of %s returned %s\n",
   12746             :                         star_name,
   12747             :                         nt_errstr(status));
   12748           0 :                 goto out;
   12749             :         }
   12750             : 
   12751           4 :         if (mangled_name == NULL) {
   12752           0 :                 goto out;
   12753             :         }
   12754             : 
   12755           4 :         printf("mangled_name = %s\n",
   12756             :                 mangled_name);
   12757             : 
   12758             :         /*
   12759             :          * Try a Windows unlink with the mangled name.
   12760             :          * This should *NOT* unlink the 'a' name.
   12761             :          */
   12762             : 
   12763           4 :         windows_unlink_name = talloc_asprintf(cli_posix,
   12764             :                                         "%s\\%s",
   12765             :                                         dname,
   12766             :                                         mangled_name);
   12767             : 
   12768           4 :         status = cli_unlink(cli, windows_unlink_name, 0);
   12769           4 :         if (!NT_STATUS_IS_OK(status)) {
   12770           0 :                 printf("cli_unlink of %s returned %s\n",
   12771             :                         windows_unlink_name,
   12772             :                         nt_errstr(status));
   12773           0 :                 goto out;
   12774             :         }
   12775             : 
   12776             :         /* Does 'a' still exist ? */
   12777           4 :         status = cli_posix_open(cli_posix,
   12778             :                                 aname,
   12779             :                                 O_RDONLY,
   12780             :                                 0,
   12781             :                                 &fnum);
   12782           4 :         if (!NT_STATUS_IS_OK(status)) {
   12783           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   12784             :                         aname,
   12785             :                         nt_errstr(status));
   12786           0 :                 goto out;
   12787             :         }
   12788             : 
   12789           4 :         status = cli_close(cli_posix, fnum);
   12790           4 :         if (!NT_STATUS_IS_OK(status)) {
   12791           0 :                 goto out;
   12792             :         }
   12793             : 
   12794           4 :         correct = true;
   12795             : 
   12796           4 :   out:
   12797             : 
   12798           4 :         TALLOC_FREE(windows_unlink_name);
   12799           4 :         TALLOC_FREE(mangled_name);
   12800             : 
   12801           4 :         if (cli != NULL) {
   12802           4 :                 cli_unlink(cli,
   12803             :                         star_name,
   12804             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12805           4 :                 cli_rmdir(cli, dname);
   12806           4 :                 torture_close_connection(cli);
   12807             :         }
   12808             : 
   12809           4 :         if (cli_posix != NULL) {
   12810           4 :                 torture_close_connection(cli_posix);
   12811             :         }
   12812             : 
   12813           4 :         return correct;
   12814             : }
   12815             : 
   12816           4 : static bool run_smb1_wild_mangle_rename_test(int dummy)
   12817             : {
   12818             :         static struct cli_state *cli_posix = NULL;
   12819             :         static struct cli_state *cli = NULL;
   12820           4 :         uint16_t fnum = (uint16_t)-1;
   12821           4 :         bool correct = false;
   12822           4 :         const char *dname = "smb1_wild_mangle_rename";
   12823           4 :         const char *fooname = "smb1_wild_mangle_rename/foo";
   12824           4 :         const char *foostar_name = "smb1_wild_mangle_rename/fo*";
   12825           4 :         const char *wild_name = "smb1_wild_mangle_rename/*";
   12826           4 :         char *windows_rename_src = NULL;
   12827           4 :         const char *windows_rename_dst = "smb1_wild_mangle_rename\\ba*";
   12828           4 :         char *mangled_name = NULL;
   12829             :         NTSTATUS status;
   12830             : 
   12831           4 :         printf("Starting SMB1 wild mangle rename test\n");
   12832             : 
   12833           4 :         if (!torture_open_connection(&cli_posix, 0)) {
   12834           0 :                 return false;
   12835             :         }
   12836             : 
   12837           4 :         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
   12838             : 
   12839           4 :         status = torture_setup_unix_extensions(cli_posix);
   12840           4 :         if (!NT_STATUS_IS_OK(status)) {
   12841           0 :                 printf("server doesn't support POSIX\n");
   12842           0 :                 return false;
   12843             :         }
   12844             : 
   12845             :         /* Open a Windows connection. */
   12846           4 :         if (!torture_open_connection(&cli, 0)) {
   12847           0 :                 goto out;
   12848             :         }
   12849             : 
   12850           4 :         smbXcli_conn_set_sockopt(cli->conn, sockops);
   12851             : 
   12852             :         /* Ensure we start from fresh. */
   12853           4 :         cli_unlink(cli,
   12854             :                 wild_name,
   12855             :                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12856           4 :         cli_posix_rmdir(cli_posix, dname);
   12857             : 
   12858             :         /*
   12859             :          * Create two files - 'foo' and 'fo*'.
   12860             :          * We need POSIX extensions for this as 'fo*'
   12861             :          * is not a valid Windows name.
   12862             :          */
   12863             : 
   12864           4 :         status = cli_posix_mkdir(cli_posix, dname, 0770);
   12865           4 :         if (!NT_STATUS_IS_OK(status)) {
   12866           0 :                 printf("cli_posix_mkdir of %s returned %s\n",
   12867             :                         dname,
   12868             :                         nt_errstr(status));
   12869           0 :                 goto out;
   12870             :         }
   12871             : 
   12872           4 :         status = cli_posix_open(cli_posix,
   12873             :                                 fooname,
   12874             :                                 O_RDWR|O_CREAT|O_EXCL,
   12875             :                                 0660,
   12876             :                                 &fnum);
   12877           4 :         if (!NT_STATUS_IS_OK(status)) {
   12878           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12879             :                         fooname,
   12880             :                         nt_errstr(status));
   12881           0 :                 goto out;
   12882             :         }
   12883           4 :         status = cli_close(cli_posix, fnum);
   12884           4 :         if (!NT_STATUS_IS_OK(status)) {
   12885           0 :                 goto out;
   12886             :         }
   12887           4 :         status = cli_posix_open(cli_posix,
   12888             :                                 foostar_name,
   12889             :                                 O_RDWR|O_CREAT|O_EXCL,
   12890             :                                 0660,
   12891             :                                 &fnum);
   12892           4 :         if (!NT_STATUS_IS_OK(status)) {
   12893           0 :                 printf("cli_posix_open (create) of %s returned %s\n",
   12894             :                         foostar_name,
   12895             :                         nt_errstr(status));
   12896           0 :                 goto out;
   12897             :         }
   12898           4 :         status = cli_close(cli_posix, fnum);
   12899           4 :         if (!NT_STATUS_IS_OK(status)) {
   12900           0 :                 goto out;
   12901             :         }
   12902             : 
   12903             :         /*
   12904             :          * Get the mangled name. We can re-use the
   12905             :          * previous smb1_wild_mangle_list_fn for this.
   12906             :          */
   12907             : 
   12908           4 :         status = cli_list(cli,
   12909             :                         wild_name,
   12910             :                         0,
   12911             :                         smb1_wild_mangle_list_fn,
   12912             :                         &mangled_name);
   12913           4 :         if (!NT_STATUS_IS_OK(status)) {
   12914           0 :                 printf("cli_list of %s returned %s\n",
   12915             :                         wild_name,
   12916             :                         nt_errstr(status));
   12917           0 :                 goto out;
   12918             :         }
   12919             : 
   12920           4 :         if (mangled_name == NULL) {
   12921           0 :                 goto out;
   12922             :         }
   12923             : 
   12924           4 :         printf("mangled_name = %s\n",
   12925             :                 mangled_name);
   12926             : 
   12927             :         /*
   12928             :          * Try a Windows rename with the mangled name.
   12929             :          * This should *NOT* rename the 'foo' name.
   12930             :          */
   12931             : 
   12932           4 :         windows_rename_src = talloc_asprintf(cli_posix,
   12933             :                                         "%s\\%s",
   12934             :                                         dname,
   12935             :                                         mangled_name);
   12936             : 
   12937           4 :         status = cli_rename(cli,
   12938             :                         windows_rename_src,
   12939             :                         windows_rename_dst,
   12940             :                         false);
   12941           4 :         if (!NT_STATUS_IS_OK(status)) {
   12942           0 :                 printf("cli_rename of %s -> %s returned %s\n",
   12943             :                         windows_rename_src,
   12944             :                         windows_rename_dst,
   12945             :                         nt_errstr(status));
   12946           0 :                 goto out;
   12947             :         }
   12948             : 
   12949             :         /* Does 'foo' still exist ? */
   12950           4 :         status = cli_posix_open(cli_posix,
   12951             :                                 fooname,
   12952             :                                 O_RDONLY,
   12953             :                                 0,
   12954             :                                 &fnum);
   12955           4 :         if (!NT_STATUS_IS_OK(status)) {
   12956           0 :                 printf("cli_posix_open O_RNONLY of %s returned %s\n",
   12957             :                         fooname,
   12958             :                         nt_errstr(status));
   12959           0 :                 goto out;
   12960             :         }
   12961             : 
   12962           4 :         status = cli_close(cli_posix, fnum);
   12963           4 :         if (!NT_STATUS_IS_OK(status)) {
   12964           0 :                 goto out;
   12965             :         }
   12966             : 
   12967           4 :         correct = true;
   12968             : 
   12969           4 :   out:
   12970             : 
   12971           4 :         TALLOC_FREE(mangled_name);
   12972           4 :         TALLOC_FREE(windows_rename_src);
   12973             : 
   12974           4 :         if (cli != NULL) {
   12975           4 :                 cli_unlink(cli,
   12976             :                         wild_name,
   12977             :                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
   12978           4 :                 torture_close_connection(cli);
   12979             :         }
   12980             : 
   12981           4 :         cli_posix_rmdir(cli_posix, dname);
   12982           4 :         torture_close_connection(cli_posix);
   12983             : 
   12984           4 :         return correct;
   12985             : }
   12986             : 
   12987             : /*
   12988             :  * Only testing minimal time strings, as the others
   12989             :  * need (locale-dependent) guessing at what strftime does and
   12990             :  * even may differ in builds.
   12991             :  */
   12992           1 : static bool timesubst_test(void)
   12993             : {
   12994           1 :         TALLOC_CTX *ctx = NULL;
   12995             :         /* Sa 23. Dez 04:33:20 CET 2017 */
   12996           1 :         const struct timeval tv = { 1514000000, 123 };
   12997           1 :         const char* expect_minimal = "20171223_033320";
   12998           1 :         const char* expect_minus   = "20171223_033320_000123";
   12999             :         char *s;
   13000           1 :         char *env_tz, *orig_tz = NULL;
   13001           1 :         bool result = true;
   13002             : 
   13003           1 :         ctx = talloc_new(NULL);
   13004             : 
   13005           1 :         env_tz = getenv("TZ");
   13006           1 :         if(env_tz) {
   13007           1 :                 orig_tz = talloc_strdup(ctx, env_tz);
   13008             :         }
   13009           1 :         setenv("TZ", "UTC", 1);
   13010             : 
   13011           1 :         s = minimal_timeval_string(ctx, &tv, false);
   13012             : 
   13013           1 :         if(!s || strcmp(s, expect_minimal)) {
   13014           0 :                 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
   13015             :                        "[%s]\n", s ? s : "<nil>", expect_minimal);
   13016           0 :                 result = false;
   13017             :         }
   13018           1 :         TALLOC_FREE(s);
   13019           1 :         s = minimal_timeval_string(ctx, &tv, true);
   13020           1 :         if(!s || strcmp(s, expect_minus)) {
   13021           0 :                 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
   13022             :                        "[%s]\n", s ? s : "<nil>", expect_minus);
   13023           0 :                 result = false;
   13024             :         }
   13025           1 :         TALLOC_FREE(s);
   13026             : 
   13027           1 :         if(orig_tz) {
   13028           1 :                 setenv("TZ", orig_tz, 1);
   13029             :         }
   13030             : 
   13031           1 :         TALLOC_FREE(ctx);
   13032           1 :         return result;
   13033             : }
   13034             : 
   13035           1 : static bool run_local_substitute(int dummy)
   13036             : {
   13037           1 :         bool ok = true;
   13038             : 
   13039           1 :         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
   13040           1 :         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
   13041           1 :         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
   13042           1 :         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
   13043           1 :         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
   13044           1 :         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
   13045           1 :         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
   13046           1 :         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
   13047           1 :         ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
   13048             :         /* Substitution depends on current time, so better test the underlying
   13049             :            formatting function. At least covers %t. */
   13050           1 :         ok &= timesubst_test();
   13051             : 
   13052             :         /* Different captialization rules in sub_basic... */
   13053             : 
   13054           2 :         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
   13055           1 :                        "blaDOM") == 0);
   13056             : 
   13057           1 :         return ok;
   13058             : }
   13059             : 
   13060           1 : static bool run_local_base64(int dummy)
   13061             : {
   13062             :         int i;
   13063           1 :         bool ret = true;
   13064             : 
   13065        2000 :         for (i=1; i<2000; i++) {
   13066             :                 DATA_BLOB blob1, blob2;
   13067             :                 char *b64;
   13068             : 
   13069        1999 :                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
   13070        1999 :                 blob1.length = i;
   13071        1999 :                 generate_random_buffer(blob1.data, blob1.length);
   13072             : 
   13073        1999 :                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
   13074        1999 :                 if (b64 == NULL) {
   13075           0 :                         d_fprintf(stderr, "base64_encode_data_blob failed "
   13076             :                                   "for %d bytes\n", i);
   13077           0 :                         ret = false;
   13078             :                 }
   13079        1999 :                 blob2 = base64_decode_data_blob(b64);
   13080        1999 :                 TALLOC_FREE(b64);
   13081             : 
   13082        1999 :                 if (data_blob_cmp(&blob1, &blob2)) {
   13083           0 :                         d_fprintf(stderr, "data_blob_cmp failed for %d "
   13084             :                                   "bytes\n", i);
   13085           0 :                         ret = false;
   13086             :                 }
   13087        1999 :                 TALLOC_FREE(blob1.data);
   13088        1999 :                 data_blob_free(&blob2);
   13089             :         }
   13090           1 :         return ret;
   13091             : }
   13092             : 
   13093     1000000 : static void parse_fn(const struct gencache_timeout *t,
   13094             :                      DATA_BLOB blob,
   13095             :                      void *private_data)
   13096             : {
   13097     1000000 :         return;
   13098             : }
   13099             : 
   13100           1 : static bool run_local_gencache(int dummy)
   13101             : {
   13102             :         char *val;
   13103             :         time_t tm;
   13104             :         DATA_BLOB blob;
   13105             :         char v;
   13106             :         struct memcache *mem;
   13107             :         int i;
   13108             : 
   13109           1 :         mem = memcache_init(NULL, 0);
   13110           1 :         if (mem == NULL) {
   13111           0 :                 d_printf("%s: memcache_init failed\n", __location__);
   13112           0 :                 return false;
   13113             :         }
   13114           1 :         memcache_set_global(mem);
   13115             : 
   13116           1 :         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
   13117           0 :                 d_printf("%s: gencache_set() failed\n", __location__);
   13118           0 :                 return False;
   13119             :         }
   13120             : 
   13121           1 :         if (!gencache_get("foo", NULL, NULL, NULL)) {
   13122           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13123           0 :                 return False;
   13124             :         }
   13125             : 
   13126     1000000 :         for (i=0; i<1000000; i++) {
   13127     1000000 :                 gencache_parse("foo", parse_fn, NULL);
   13128             :         }
   13129             : 
   13130           1 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13131           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13132           0 :                 return False;
   13133             :         }
   13134           1 :         TALLOC_FREE(val);
   13135             : 
   13136           1 :         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
   13137           0 :                 d_printf("%s: gencache_get() failed\n", __location__);
   13138           0 :                 return False;
   13139             :         }
   13140             : 
   13141           1 :         if (strcmp(val, "bar") != 0) {
   13142           0 :                 d_printf("%s: gencache_get() returned %s, expected %s\n",
   13143             :                          __location__, val, "bar");
   13144           0 :                 TALLOC_FREE(val);
   13145           0 :                 return False;
   13146             :         }
   13147             : 
   13148           1 :         TALLOC_FREE(val);
   13149             : 
   13150           1 :         if (!gencache_del("foo")) {
   13151           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13152           0 :                 return False;
   13153             :         }
   13154           1 :         if (gencache_del("foo")) {
   13155           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13156             :                          __location__);
   13157           0 :                 return False;
   13158             :         }
   13159             : 
   13160           1 :         if (gencache_get("foo", talloc_tos(), &val, &tm)) {
   13161           0 :                 d_printf("%s: gencache_get() on deleted entry "
   13162             :                          "succeeded\n", __location__);
   13163           0 :                 return False;
   13164             :         }
   13165             : 
   13166           1 :         blob = data_blob_string_const_null("bar");
   13167           1 :         tm = time(NULL) + 60;
   13168             : 
   13169           1 :         if (!gencache_set_data_blob("foo", blob, tm)) {
   13170           0 :                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
   13171           0 :                 return False;
   13172             :         }
   13173             : 
   13174           1 :         if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13175           0 :                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
   13176           0 :                 return False;
   13177             :         }
   13178             : 
   13179           1 :         if (strcmp((const char *)blob.data, "bar") != 0) {
   13180           0 :                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
   13181           0 :                          __location__, (const char *)blob.data, "bar");
   13182           0 :                 data_blob_free(&blob);
   13183           0 :                 return False;
   13184             :         }
   13185             : 
   13186           1 :         data_blob_free(&blob);
   13187             : 
   13188           1 :         if (!gencache_del("foo")) {
   13189           0 :                 d_printf("%s: gencache_del() failed\n", __location__);
   13190           0 :                 return False;
   13191             :         }
   13192           1 :         if (gencache_del("foo")) {
   13193           0 :                 d_printf("%s: second gencache_del() succeeded\n",
   13194             :                          __location__);
   13195           0 :                 return False;
   13196             :         }
   13197             : 
   13198           1 :         if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
   13199           0 :                 d_printf("%s: gencache_get_data_blob() on deleted entry "
   13200             :                          "succeeded\n", __location__);
   13201           0 :                 return False;
   13202             :         }
   13203             : 
   13204           1 :         v = 1;
   13205           1 :         blob.data = (uint8_t *)&v;
   13206           1 :         blob.length = sizeof(v);
   13207             : 
   13208           1 :         if (!gencache_set_data_blob("blob", blob, tm)) {
   13209           0 :                 d_printf("%s: gencache_set_data_blob() failed\n",
   13210             :                          __location__);
   13211           0 :                 return false;
   13212             :         }
   13213           1 :         if (gencache_get("blob", talloc_tos(), &val, &tm)) {
   13214           0 :                 d_printf("%s: gencache_get succeeded\n", __location__);
   13215           0 :                 return false;
   13216             :         }
   13217             : 
   13218           0 :         return True;
   13219             : }
   13220             : 
   13221           1 : static bool rbt_testflags(struct db_context *db, const char *key,
   13222             :                           const char *value)
   13223             : {
   13224           1 :         bool ret = false;
   13225             :         NTSTATUS status;
   13226             :         struct db_record *rec;
   13227             : 
   13228           1 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13229           1 :         if (rec == NULL) {
   13230           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13231           0 :                 goto done;
   13232             :         }
   13233             : 
   13234           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13235           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
   13236           0 :                 d_fprintf(stderr, "store TDB_MODIFY unexpected status: %s\n",
   13237             :                           nt_errstr(status));
   13238           0 :                 goto done;
   13239             :         }
   13240             : 
   13241           1 :         status = dbwrap_record_store(rec, string_tdb_data("overwriteme"),
   13242             :                                      TDB_INSERT);
   13243           1 :         if (!NT_STATUS_IS_OK(status)) {
   13244           0 :                 d_fprintf(stderr, "store TDB_INSERT failed: %s\n",
   13245             :                           nt_errstr(status));
   13246           0 :                 goto done;
   13247             :         }
   13248             : 
   13249           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_INSERT);
   13250           1 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
   13251           0 :                 d_fprintf(stderr, "store TDB_INSERT unexpected status: %s\n",
   13252             :                           nt_errstr(status));
   13253           0 :                 goto done;
   13254             :         }
   13255             : 
   13256           1 :         status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
   13257           1 :         if (!NT_STATUS_IS_OK(status)) {
   13258           0 :                 d_fprintf(stderr, "store TDB_MODIFY failed: %s\n",
   13259             :                           nt_errstr(status));
   13260           0 :                 goto done;
   13261             :         }
   13262             : 
   13263           0 :         ret = true;
   13264           1 : done:
   13265           1 :         TALLOC_FREE(rec);
   13266           1 :         return ret;
   13267             : }
   13268             : 
   13269        1998 : static bool rbt_testval(struct db_context *db, const char *key,
   13270             :                         const char *value)
   13271             : {
   13272             :         struct db_record *rec;
   13273        1998 :         TDB_DATA data = string_tdb_data(value);
   13274        1998 :         bool ret = false;
   13275             :         NTSTATUS status;
   13276             :         TDB_DATA dbvalue;
   13277             : 
   13278        1998 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13279        1998 :         if (rec == NULL) {
   13280           0 :                 d_fprintf(stderr, "fetch_locked failed\n");
   13281           0 :                 goto done;
   13282             :         }
   13283        1998 :         status = dbwrap_record_store(rec, data, 0);
   13284        1998 :         if (!NT_STATUS_IS_OK(status)) {
   13285           0 :                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
   13286           0 :                 goto done;
   13287             :         }
   13288        1998 :         TALLOC_FREE(rec);
   13289             : 
   13290        1998 :         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
   13291        1998 :         if (rec == NULL) {
   13292           0 :                 d_fprintf(stderr, "second fetch_locked failed\n");
   13293           0 :                 goto done;
   13294             :         }
   13295             : 
   13296        1998 :         dbvalue = dbwrap_record_get_value(rec);
   13297        1998 :         if ((dbvalue.dsize != data.dsize)
   13298        1998 :             || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
   13299           0 :                 d_fprintf(stderr, "Got wrong data back\n");
   13300           0 :                 goto done;
   13301             :         }
   13302             : 
   13303           0 :         ret = true;
   13304        1998 :  done:
   13305        1998 :         TALLOC_FREE(rec);
   13306        1998 :         return ret;
   13307             : }
   13308             : 
   13309        1000 : static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
   13310             : {
   13311        1000 :         int *count2 = (int *)private_data;
   13312        1000 :         (*count2)++;
   13313        1000 :         return 0;
   13314             : }
   13315             : 
   13316        1000 : static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
   13317             : {
   13318        1000 :         int *count2 = (int *)private_data;
   13319        1000 :         (*count2)++;
   13320        1000 :         dbwrap_record_delete(rec);
   13321        1000 :         return 0;
   13322             : }
   13323             : 
   13324           1 : static bool run_local_rbtree(int dummy)
   13325             : {
   13326             :         struct db_context *db;
   13327           1 :         bool ret = false;
   13328             :         int i;
   13329             :         NTSTATUS status;
   13330           1 :         int count = 0;
   13331           1 :         int count2 = 0;
   13332             : 
   13333           1 :         db = db_open_rbt(NULL);
   13334             : 
   13335           1 :         if (db == NULL) {
   13336           0 :                 d_fprintf(stderr, "db_open_rbt failed\n");
   13337           0 :                 return false;
   13338             :         }
   13339             : 
   13340           1 :         if (!rbt_testflags(db, "firstkey", "firstval")) {
   13341           0 :                 goto done;
   13342             :         }
   13343             : 
   13344         999 :         for (i = 0; i < 999; i++) {
   13345             :                 char key[sizeof("key-9223372036854775807")];
   13346             :                 char value[sizeof("value-9223372036854775807")];
   13347             : 
   13348        1998 :                 snprintf(key, sizeof(key), "key%ld", random());
   13349        1998 :                 snprintf(value, sizeof(value) ,"value%ld", random());
   13350             : 
   13351         999 :                 if (!rbt_testval(db, key, value)) {
   13352           0 :                         goto done;
   13353             :                 }
   13354             : 
   13355        1998 :                 snprintf(value, sizeof(value) ,"value%ld", random());
   13356             : 
   13357         999 :                 if (!rbt_testval(db, key, value)) {
   13358           0 :                         goto done;
   13359             :                 }
   13360             :         }
   13361             : 
   13362           1 :         ret = true;
   13363           1 :         count = 0; count2 = 0;
   13364           1 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13365             :                                       &count2, &count);
   13366           2 :         printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13367           1 :         if ((count != count2) || (count != 1000)) {
   13368           0 :                 ret = false;
   13369             :         }
   13370           1 :         count = 0; count2 = 0;
   13371           1 :         status = dbwrap_traverse(db, local_rbtree_traverse_delete,
   13372             :                                  &count2, &count);
   13373           2 :         printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13374           1 :         if ((count != count2) || (count != 1000)) {
   13375           0 :                 ret = false;
   13376             :         }
   13377           1 :         count = 0; count2 = 0;
   13378           1 :         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
   13379             :                                       &count2, &count);
   13380           2 :         printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
   13381           1 :         if ((count != count2) || (count != 0)) {
   13382           0 :                 ret = false;
   13383             :         }
   13384             : 
   13385           2 :  done:
   13386           1 :         TALLOC_FREE(db);
   13387           1 :         return ret;
   13388             : }
   13389             : 
   13390             : 
   13391             : /*
   13392             :   local test for character set functions
   13393             : 
   13394             :   This is a very simple test for the functionality in convert_string_error()
   13395             :  */
   13396           1 : static bool run_local_convert_string(int dummy)
   13397             : {
   13398           1 :         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
   13399           1 :         const char *test_strings[2] = { "March", "M\303\244rz" };
   13400             :         char dst[7];
   13401             :         int i;
   13402             : 
   13403           6 :         for (i=0; i<2; i++) {
   13404           2 :                 const char *str = test_strings[i];
   13405           2 :                 int len = strlen(str);
   13406             :                 size_t converted_size;
   13407             :                 bool ret;
   13408             : 
   13409           2 :                 memset(dst, 'X', sizeof(dst));
   13410             : 
   13411             :                 /* first try with real source length */
   13412           2 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13413             :                                            str, len,
   13414             :                                            dst, sizeof(dst),
   13415             :                                            &converted_size);
   13416           2 :                 if (ret != true) {
   13417           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13418           0 :                         goto failed;
   13419             :                 }
   13420             : 
   13421           2 :                 if (converted_size != len) {
   13422           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13423             :                                   str, len, (int)converted_size);
   13424           0 :                         goto failed;
   13425             :                 }
   13426             : 
   13427           2 :                 if (strncmp(str, dst, converted_size) != 0) {
   13428           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13429           0 :                         goto failed;
   13430             :                 }
   13431             : 
   13432           2 :                 if (strlen(str) != converted_size) {
   13433           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13434           0 :                                   (int)strlen(str), (int)converted_size);
   13435           0 :                         goto failed;
   13436             :                 }
   13437             : 
   13438           2 :                 if (dst[converted_size] != 'X') {
   13439           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13440           0 :                         goto failed;
   13441             :                 }
   13442             : 
   13443             :                 /* now with srclen==-1, this causes the nul to be
   13444             :                  * converted too */
   13445           2 :                 ret = convert_string_error(CH_UNIX, CH_UTF8,
   13446             :                                            str, -1,
   13447             :                                            dst, sizeof(dst),
   13448             :                                            &converted_size);
   13449           2 :                 if (ret != true) {
   13450           0 :                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
   13451           0 :                         goto failed;
   13452             :                 }
   13453             : 
   13454           2 :                 if (converted_size != len+1) {
   13455           0 :                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
   13456             :                                   str, len, (int)converted_size);
   13457           0 :                         goto failed;
   13458             :                 }
   13459             : 
   13460           2 :                 if (strncmp(str, dst, converted_size) != 0) {
   13461           0 :                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
   13462           0 :                         goto failed;
   13463             :                 }
   13464             : 
   13465           0 :                 if (len+1 != converted_size) {
   13466           0 :                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
   13467             :                                   len+1, (int)converted_size);
   13468           0 :                         goto failed;
   13469             :                 }
   13470             : 
   13471           2 :                 if (dst[converted_size] != 'X') {
   13472           0 :                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
   13473           0 :                         goto failed;
   13474             :                 }
   13475             : 
   13476             :         }
   13477             : 
   13478             : 
   13479           1 :         TALLOC_FREE(tmp_ctx);
   13480           0 :         return true;
   13481           0 : failed:
   13482           0 :         TALLOC_FREE(tmp_ctx);
   13483           0 :         return false;
   13484             : }
   13485             : 
   13486           1 : static bool run_local_string_to_sid(int dummy) {
   13487             :         struct dom_sid sid;
   13488             : 
   13489           1 :         if (string_to_sid(&sid, "S--1-5-32-545")) {
   13490           0 :                 printf("allowing S--1-5-32-545\n");
   13491           0 :                 return false;
   13492             :         }
   13493           1 :         if (string_to_sid(&sid, "S-1-5-32-+545")) {
   13494           0 :                 printf("allowing S-1-5-32-+545\n");
   13495           0 :                 return false;
   13496             :         }
   13497           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")) {
   13498           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");
   13499           0 :                 return false;
   13500             :         }
   13501           1 :         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
   13502           0 :                 printf("allowing S-1-5-32-545-abc\n");
   13503           0 :                 return false;
   13504             :         }
   13505           1 :         if (string_to_sid(&sid, "S-300-5-32-545")) {
   13506           0 :                 printf("allowing S-300-5-32-545\n");
   13507           0 :                 return false;
   13508             :         }
   13509           1 :         if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
   13510           0 :                 printf("allowing S-1-0xfffffffffffffe-32-545\n");
   13511           0 :                 return false;
   13512             :         }
   13513           1 :         if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
   13514           0 :                 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
   13515           0 :                 return false;
   13516             :         }
   13517           1 :         if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
   13518           0 :                 printf("could not parse S-1-0xfffffffffffe-32-545\n");
   13519           0 :                 return false;
   13520             :         }
   13521           1 :         if (!string_to_sid(&sid, "S-1-5-32-545")) {
   13522           0 :                 printf("could not parse S-1-5-32-545\n");
   13523           0 :                 return false;
   13524             :         }
   13525           1 :         if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
   13526             :                 struct dom_sid_buf buf;
   13527           0 :                 printf("mis-parsed S-1-5-32-545 as %s\n",
   13528             :                        dom_sid_str_buf(&sid, &buf));
   13529           0 :                 return false;
   13530             :         }
   13531           0 :         return true;
   13532             : }
   13533             : 
   13534           3 : static bool sid_to_string_test(const char *expected) {
   13535             :         char *str;
   13536           3 :         bool res = true;
   13537             :         struct dom_sid sid;
   13538             : 
   13539           3 :         if (!string_to_sid(&sid, expected)) {
   13540           0 :                 printf("could not parse %s\n", expected);
   13541           0 :                 return false;
   13542             :         }
   13543             : 
   13544           3 :         str = dom_sid_string(NULL, &sid);
   13545           3 :         if (strcmp(str, expected)) {
   13546           0 :                 printf("Comparison failed (%s != %s)\n", str, expected);
   13547           0 :                 res = false;
   13548             :         }
   13549           3 :         TALLOC_FREE(str);
   13550           3 :         return res;
   13551             : }
   13552             : 
   13553           1 : static bool run_local_sid_to_string(int dummy) {
   13554           1 :         if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
   13555           0 :                 return false;
   13556           1 :         if (!sid_to_string_test("S-1-545"))
   13557           0 :                 return false;
   13558           1 :         if (!sid_to_string_test("S-255-3840-1-1-1-1"))
   13559           0 :                 return false;
   13560           1 :         return true;
   13561             : }
   13562             : 
   13563           1 : static bool run_local_binary_to_sid(int dummy) {
   13564             :         ssize_t ret;
   13565           1 :         struct dom_sid *sid = talloc(NULL, struct dom_sid);
   13566             :         static const uint8_t good_binary_sid[] = {
   13567             :                 0x1, /* revision number */
   13568             :                 15, /* num auths */
   13569             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13570             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13571             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13572             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13573             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13574             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13575             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13576             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13577             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13578             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13579             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13580             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13581             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13582             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13583             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13584             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13585             :         };
   13586             : 
   13587             :         static const uint8_t long_binary_sid[] = {
   13588             :                 0x1, /* revision number */
   13589             :                 15, /* num auths */
   13590             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13591             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13592             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13593             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13594             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13595             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13596             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13597             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13598             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13599             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13600             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13601             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13602             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13603             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13604             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13605             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13606             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13607             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13608             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13609             :         };
   13610             : 
   13611             :         static const uint8_t long_binary_sid2[] = {
   13612             :                 0x1, /* revision number */
   13613             :                 32, /* num auths */
   13614             :                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
   13615             :                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
   13616             :                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
   13617             :                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
   13618             :                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
   13619             :                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
   13620             :                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
   13621             :                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
   13622             :                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
   13623             :                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
   13624             :                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
   13625             :                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
   13626             :                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
   13627             :                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
   13628             :                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
   13629             :                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
   13630             :                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
   13631             :                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
   13632             :                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
   13633             :                 0x1, 0x1, 0x1, 0x1, /* auth[18] */
   13634             :                 0x1, 0x1, 0x1, 0x1, /* auth[19] */
   13635             :                 0x1, 0x1, 0x1, 0x1, /* auth[20] */
   13636             :                 0x1, 0x1, 0x1, 0x1, /* auth[21] */
   13637             :                 0x1, 0x1, 0x1, 0x1, /* auth[22] */
   13638             :                 0x1, 0x1, 0x1, 0x1, /* auth[23] */
   13639             :                 0x1, 0x1, 0x1, 0x1, /* auth[24] */
   13640             :                 0x1, 0x1, 0x1, 0x1, /* auth[25] */
   13641             :                 0x1, 0x1, 0x1, 0x1, /* auth[26] */
   13642             :                 0x1, 0x1, 0x1, 0x1, /* auth[27] */
   13643             :                 0x1, 0x1, 0x1, 0x1, /* auth[28] */
   13644             :                 0x1, 0x1, 0x1, 0x1, /* auth[29] */
   13645             :                 0x1, 0x1, 0x1, 0x1, /* auth[30] */
   13646             :                 0x1, 0x1, 0x1, 0x1, /* auth[31] */
   13647             :         };
   13648             : 
   13649           1 :         ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid);
   13650           1 :         if (ret == -1) {
   13651           0 :                 return false;
   13652             :         }
   13653           1 :         ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid);
   13654           1 :         if (ret != -1) {
   13655           0 :                 return false;
   13656             :         }
   13657           1 :         ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid);
   13658           1 :         if (ret != -1) {
   13659           0 :                 return false;
   13660             :         }
   13661           1 :         return true;
   13662             : }
   13663             : 
   13664             : /* Split a path name into filename and stream name components. Canonicalise
   13665             :  * such that an implicit $DATA token is always explicit.
   13666             :  *
   13667             :  * The "specification" of this function can be found in the
   13668             :  * run_local_stream_name() function in torture.c, I've tried those
   13669             :  * combinations against a W2k3 server.
   13670             :  */
   13671             : 
   13672           8 : static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
   13673             :                                        char **pbase, char **pstream)
   13674             : {
   13675           8 :         char *base = NULL;
   13676           8 :         char *stream = NULL;
   13677             :         char *sname; /* stream name */
   13678             :         const char *stype; /* stream type */
   13679             : 
   13680           8 :         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
   13681             : 
   13682           8 :         sname = strchr_m(fname, ':');
   13683             : 
   13684           8 :         if (sname == NULL) {
   13685           1 :                 if (pbase != NULL) {
   13686           1 :                         base = talloc_strdup(mem_ctx, fname);
   13687           1 :                         NT_STATUS_HAVE_NO_MEMORY(base);
   13688             :                 }
   13689           0 :                 goto done;
   13690             :         }
   13691             : 
   13692           7 :         if (pbase != NULL) {
   13693           7 :                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
   13694           7 :                 NT_STATUS_HAVE_NO_MEMORY(base);
   13695             :         }
   13696             : 
   13697           7 :         sname += 1;
   13698             : 
   13699           7 :         stype = strchr_m(sname, ':');
   13700             : 
   13701           7 :         if (stype == NULL) {
   13702           2 :                 sname = talloc_strdup(mem_ctx, sname);
   13703           2 :                 stype = "$DATA";
   13704             :         }
   13705             :         else {
   13706           5 :                 if (strcasecmp_m(stype, ":$DATA") != 0) {
   13707             :                         /*
   13708             :                          * If there is an explicit stream type, so far we only
   13709             :                          * allow $DATA. Is there anything else allowed? -- vl
   13710             :                          */
   13711           3 :                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
   13712           3 :                         TALLOC_FREE(base);
   13713           3 :                         return NT_STATUS_OBJECT_NAME_INVALID;
   13714             :                 }
   13715           2 :                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
   13716           2 :                 stype += 1;
   13717             :         }
   13718             : 
   13719           4 :         if (sname == NULL) {
   13720           0 :                 TALLOC_FREE(base);
   13721           0 :                 return NT_STATUS_NO_MEMORY;
   13722             :         }
   13723             : 
   13724           4 :         if (sname[0] == '\0') {
   13725             :                 /*
   13726             :                  * no stream name, so no stream
   13727             :                  */
   13728           0 :                 goto done;
   13729             :         }
   13730             : 
   13731           3 :         if (pstream != NULL) {
   13732           3 :                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
   13733           3 :                 if (stream == NULL) {
   13734           0 :                         TALLOC_FREE(sname);
   13735           0 :                         TALLOC_FREE(base);
   13736           0 :                         return NT_STATUS_NO_MEMORY;
   13737             :                 }
   13738             :                 /*
   13739             :                  * upper-case the type field
   13740             :                  */
   13741           3 :                 (void)strupper_m(strchr_m(stream, ':')+1);
   13742             :         }
   13743             : 
   13744           6 :  done:
   13745           5 :         if (pbase != NULL) {
   13746           5 :                 *pbase = base;
   13747             :         }
   13748           5 :         if (pstream != NULL) {
   13749           5 :                 *pstream = stream;
   13750             :         }
   13751           5 :         return NT_STATUS_OK;
   13752             : }
   13753             : 
   13754           8 : static bool test_stream_name(const char *fname, const char *expected_base,
   13755             :                              const char *expected_stream,
   13756             :                              NTSTATUS expected_status)
   13757             : {
   13758             :         NTSTATUS status;
   13759           8 :         char *base = NULL;
   13760           8 :         char *stream = NULL;
   13761             : 
   13762           8 :         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
   13763           8 :         if (!NT_STATUS_EQUAL(status, expected_status)) {
   13764           0 :                 goto error;
   13765             :         }
   13766             : 
   13767           8 :         if (!NT_STATUS_IS_OK(status)) {
   13768           0 :                 return true;
   13769             :         }
   13770             : 
   13771           5 :         if (base == NULL) goto error;
   13772             : 
   13773           5 :         if (strcmp(expected_base, base) != 0) goto error;
   13774             : 
   13775           5 :         if ((expected_stream != NULL) && (stream == NULL)) goto error;
   13776           5 :         if ((expected_stream == NULL) && (stream != NULL)) goto error;
   13777             : 
   13778           5 :         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
   13779           0 :                 goto error;
   13780             : 
   13781           5 :         TALLOC_FREE(base);
   13782           5 :         TALLOC_FREE(stream);
   13783           0 :         return true;
   13784             : 
   13785           0 :  error:
   13786           0 :         d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
   13787             :                   fname, expected_base ? expected_base : "<NULL>",
   13788             :                   expected_stream ? expected_stream : "<NULL>",
   13789             :                   nt_errstr(expected_status));
   13790           0 :         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
   13791           0 :                   base ? base : "<NULL>", stream ? stream : "<NULL>",
   13792             :                   nt_errstr(status));
   13793           0 :         TALLOC_FREE(base);
   13794           0 :         TALLOC_FREE(stream);
   13795           0 :         return false;
   13796             : }
   13797             : 
   13798           1 : static bool run_local_stream_name(int dummy)
   13799             : {
   13800           1 :         bool ret = true;
   13801             : 
   13802           1 :         ret &= test_stream_name(
   13803           1 :                 "bla", "bla", NULL, NT_STATUS_OK);
   13804           1 :         ret &= test_stream_name(
   13805           1 :                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
   13806           1 :         ret &= test_stream_name(
   13807           1 :                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   13808           1 :         ret &= test_stream_name(
   13809           1 :                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
   13810           1 :         ret &= test_stream_name(
   13811           1 :                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
   13812           1 :         ret &= test_stream_name(
   13813           1 :                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
   13814           1 :         ret &= test_stream_name(
   13815           1 :                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
   13816           1 :         ret &= test_stream_name(
   13817           1 :                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
   13818             : 
   13819           1 :         return ret;
   13820             : }
   13821             : 
   13822           2 : static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
   13823             : {
   13824           2 :         if (a.length != b.length) {
   13825           0 :                 printf("a.length=%d != b.length=%d\n",
   13826           0 :                        (int)a.length, (int)b.length);
   13827           0 :                 return false;
   13828             :         }
   13829           2 :         if (memcmp(a.data, b.data, a.length) != 0) {
   13830           0 :                 printf("a.data and b.data differ\n");
   13831           0 :                 return false;
   13832             :         }
   13833           0 :         return true;
   13834             : }
   13835             : 
   13836           1 : static bool run_local_memcache(int dummy)
   13837             : {
   13838             :         struct memcache *cache;
   13839             :         DATA_BLOB k1, k2, k3, k4, k5;
   13840             :         DATA_BLOB d1, d3;
   13841             :         DATA_BLOB v1, v3;
   13842             : 
   13843             :         TALLOC_CTX *mem_ctx;
   13844           1 :         char *ptr1 = NULL;
   13845           1 :         char *ptr2 = NULL;
   13846           1 :         char *ptr3 = NULL;
   13847             : 
   13848             :         char *str1, *str2;
   13849             :         size_t size1, size2;
   13850           1 :         bool ret = false;
   13851             : 
   13852           1 :         mem_ctx = talloc_init("foo");
   13853           1 :         if (mem_ctx == NULL) {
   13854           0 :                 return false;
   13855             :         }
   13856             : 
   13857             :         /* STAT_CACHE TESTS */
   13858             : 
   13859           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   13860             : 
   13861           1 :         if (cache == NULL) {
   13862           0 :                 printf("memcache_init failed\n");
   13863           0 :                 return false;
   13864             :         }
   13865             : 
   13866           1 :         d1 = data_blob_const("d1", 2);
   13867           1 :         d3 = data_blob_const("d3", 2);
   13868             : 
   13869           1 :         k1 = data_blob_const("d1", 2);
   13870           1 :         k2 = data_blob_const("d2", 2);
   13871           1 :         k3 = data_blob_const("d3", 2);
   13872           1 :         k4 = data_blob_const("d4", 2);
   13873           1 :         k5 = data_blob_const("d5", 2);
   13874             : 
   13875           1 :         memcache_add(cache, STAT_CACHE, k1, d1);
   13876             : 
   13877           1 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
   13878           0 :                 printf("could not find k1\n");
   13879           0 :                 return false;
   13880             :         }
   13881           1 :         if (!data_blob_equal(d1, v1)) {
   13882           0 :                 return false;
   13883             :         }
   13884             : 
   13885           1 :         memcache_add(cache, STAT_CACHE, k1, d3);
   13886             : 
   13887           1 :         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
   13888           0 :                 printf("could not find replaced k1\n");
   13889           0 :                 return false;
   13890             :         }
   13891           1 :         if (!data_blob_equal(d3, v3)) {
   13892           0 :                 return false;
   13893             :         }
   13894             : 
   13895           1 :         TALLOC_FREE(cache);
   13896             : 
   13897             :         /* GETWD_CACHE TESTS */
   13898           1 :         str1 = talloc_strdup(mem_ctx, "string1");
   13899           1 :         if (str1 == NULL) {
   13900           0 :                 return false;
   13901             :         }
   13902           1 :         ptr2 = str1; /* Keep an alias for comparison. */
   13903             : 
   13904           1 :         str2 = talloc_strdup(mem_ctx, "string2");
   13905           1 :         if (str2 == NULL) {
   13906           0 :                 return false;
   13907             :         }
   13908             : 
   13909           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   13910           1 :         if (cache == NULL) {
   13911           0 :                 printf("memcache_init failed\n");
   13912           0 :                 return false;
   13913             :         }
   13914             : 
   13915           1 :         memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
   13916             :         /* str1 == NULL now. */
   13917           1 :         ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   13918           1 :         if (ptr1 == NULL) {
   13919           0 :                 printf("could not find k2\n");
   13920           0 :                 return false;
   13921             :         }
   13922           1 :         if (ptr1 != ptr2) {
   13923           0 :                 printf("fetch of k2 got wrong string\n");
   13924           0 :                 return false;
   13925             :         }
   13926             : 
   13927             :         /* Add a blob to ensure k2 gets purged. */
   13928           1 :         d3 = data_blob_talloc_zero(mem_ctx, 180);
   13929           1 :         memcache_add(cache, STAT_CACHE, k3, d3);
   13930             : 
   13931           1 :         ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
   13932           1 :         if (ptr2 != NULL) {
   13933           0 :                 printf("Did find k2, should have been purged\n");
   13934           0 :                 return false;
   13935             :         }
   13936             : 
   13937             :         /*
   13938             :          * Test that talloc size also is accounted in memcache and
   13939             :          * causes purge of other object.
   13940             :          */
   13941             : 
   13942           1 :         str1 = talloc_zero_size(mem_ctx, 100);
   13943           1 :         str2 = talloc_zero_size(mem_ctx, 100);
   13944             : 
   13945           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   13946           1 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str1);
   13947             : 
   13948           1 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   13949           1 :         if (ptr3 != NULL) {
   13950           0 :                 printf("Did find k4, should have been purged\n");
   13951           0 :                 return false;
   13952             :         }
   13953             : 
   13954             :         /*
   13955             :          * Test that adding a duplicate non-talloced
   13956             :          * key/value on top of a talloced key/value takes account
   13957             :          * of the talloc_freed value size.
   13958             :          */
   13959           1 :         TALLOC_FREE(cache);
   13960           1 :         TALLOC_FREE(mem_ctx);
   13961             : 
   13962           1 :         mem_ctx = talloc_init("key_replace");
   13963           1 :         if (mem_ctx == NULL) {
   13964           0 :                 return false;
   13965             :         }
   13966             : 
   13967           1 :         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
   13968           1 :         if (cache == NULL) {
   13969           0 :                 return false;
   13970             :         }
   13971             : 
   13972             :         /*
   13973             :          * Add a 100 byte talloced string. This will
   13974             :          * store a (4 or 8 byte) pointer and record the
   13975             :          * total talloced size.
   13976             :          */
   13977           1 :         str1 = talloc_zero_size(mem_ctx, 100);
   13978           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   13979             :         /*
   13980             :          * Now overwrite with a small talloced
   13981             :          * value. This should fit in the existing size
   13982             :          * and the total talloced size should be removed
   13983             :          * from the cache size.
   13984             :          */
   13985           1 :         str1 = talloc_zero_size(mem_ctx, 2);
   13986           1 :         memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
   13987             :         /*
   13988             :          * Now store a 20 byte string. If the
   13989             :          * total talloced size wasn't accounted for
   13990             :          * and removed in the overwrite, then this
   13991             :          * will evict k4.
   13992             :          */
   13993           1 :         str2 = talloc_zero_size(mem_ctx, 20);
   13994           1 :         memcache_add_talloc(cache, GETWD_CACHE, k5, &str2);
   13995             : 
   13996           1 :         ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
   13997           1 :         if (ptr3 == NULL) {
   13998           0 :                 printf("Did not find k4, should not have been purged\n");
   13999           0 :                 return false;
   14000             :         }
   14001             : 
   14002           1 :         TALLOC_FREE(cache);
   14003           1 :         TALLOC_FREE(mem_ctx);
   14004             : 
   14005           1 :         mem_ctx = talloc_init("foo");
   14006           1 :         if (mem_ctx == NULL) {
   14007           0 :                 return false;
   14008             :         }
   14009             : 
   14010           1 :         cache = memcache_init(NULL, 0);
   14011           1 :         if (cache == NULL) {
   14012           0 :                 return false;
   14013             :         }
   14014             : 
   14015           1 :         str1 = talloc_strdup(mem_ctx, "string1");
   14016           1 :         if (str1 == NULL) {
   14017           0 :                 return false;
   14018             :         }
   14019           1 :         str2 = talloc_strdup(mem_ctx, "string2");
   14020           1 :         if (str2 == NULL) {
   14021           0 :                 return false;
   14022             :         }
   14023           1 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14024             :                             data_blob_string_const("torture"), &str1);
   14025           1 :         size1 = talloc_total_size(cache);
   14026             : 
   14027           1 :         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
   14028             :                             data_blob_string_const("torture"), &str2);
   14029           1 :         size2 = talloc_total_size(cache);
   14030             : 
   14031           2 :         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
   14032             : 
   14033           1 :         if (size2 > size1) {
   14034           0 :                 printf("memcache leaks memory!\n");
   14035           0 :                 goto fail;
   14036             :         }
   14037             : 
   14038           0 :         ret = true;
   14039           1 :  fail:
   14040           1 :         TALLOC_FREE(cache);
   14041           1 :         return ret;
   14042             : }
   14043             : 
   14044         200 : static void wbclient_done(struct tevent_req *req)
   14045             : {
   14046             :         wbcErr wbc_err;
   14047             :         struct winbindd_response *wb_resp;
   14048         200 :         int *i = (int *)tevent_req_callback_data_void(req);
   14049             : 
   14050         200 :         wbc_err = wb_trans_recv(req, req, &wb_resp);
   14051         200 :         TALLOC_FREE(req);
   14052         200 :         *i += 1;
   14053         200 :         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
   14054         200 : }
   14055             : 
   14056           2 : static bool run_wbclient_multi_ping(int dummy)
   14057             : {
   14058             :         struct tevent_context *ev;
   14059             :         struct wb_context **wb_ctx;
   14060             :         struct winbindd_request wb_req;
   14061           2 :         bool result = false;
   14062             :         int i, j;
   14063             : 
   14064           2 :         BlockSignals(True, SIGPIPE);
   14065             : 
   14066           2 :         ev = tevent_context_init(talloc_tos());
   14067           2 :         if (ev == NULL) {
   14068           0 :                 goto fail;
   14069             :         }
   14070             : 
   14071           2 :         wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
   14072           2 :         if (wb_ctx == NULL) {
   14073           0 :                 goto fail;
   14074             :         }
   14075             : 
   14076           2 :         ZERO_STRUCT(wb_req);
   14077           2 :         wb_req.cmd = WINBINDD_PING;
   14078             : 
   14079           2 :         d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
   14080             : 
   14081           4 :         for (i=0; i<torture_nprocs; i++) {
   14082           2 :                 wb_ctx[i] = wb_context_init(ev, NULL);
   14083           2 :                 if (wb_ctx[i] == NULL) {
   14084           0 :                         goto fail;
   14085             :                 }
   14086         202 :                 for (j=0; j<torture_numops; j++) {
   14087             :                         struct tevent_req *req;
   14088         200 :                         req = wb_trans_send(ev, ev, wb_ctx[i],
   14089         200 :                                             (j % 2) == 0, &wb_req);
   14090         200 :                         if (req == NULL) {
   14091           0 :                                 goto fail;
   14092             :                         }
   14093         200 :                         tevent_req_set_callback(req, wbclient_done, &i);
   14094             :                 }
   14095             :         }
   14096             : 
   14097           2 :         i = 0;
   14098             : 
   14099         819 :         while (i < torture_nprocs * torture_numops) {
   14100         816 :                 tevent_loop_once(ev);
   14101             :         }
   14102             : 
   14103           2 :         result = true;
   14104           2 :  fail:
   14105           2 :         TALLOC_FREE(ev);
   14106           2 :         return result;
   14107             : }
   14108             : 
   14109           0 : static bool dbtrans_inc(struct db_context *db)
   14110             : {
   14111             :         struct db_record *rec;
   14112             :         uint32_t val;
   14113           0 :         bool ret = false;
   14114             :         NTSTATUS status;
   14115             :         TDB_DATA value;
   14116             : 
   14117           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14118           0 :         if (rec == NULL) {
   14119           0 :                 printf(__location__ "fetch_lock failed\n");
   14120           0 :                 return false;
   14121             :         }
   14122             : 
   14123           0 :         value = dbwrap_record_get_value(rec);
   14124             : 
   14125           0 :         if (value.dsize != sizeof(uint32_t)) {
   14126           0 :                 printf(__location__ "value.dsize = %d\n",
   14127           0 :                        (int)value.dsize);
   14128           0 :                 goto fail;
   14129             :         }
   14130             : 
   14131           0 :         memcpy(&val, value.dptr, sizeof(val));
   14132           0 :         val += 1;
   14133             : 
   14134           0 :         status = dbwrap_record_store(
   14135             :                 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
   14136           0 :         if (!NT_STATUS_IS_OK(status)) {
   14137           0 :                 printf(__location__ "store failed: %s\n",
   14138             :                        nt_errstr(status));
   14139           0 :                 goto fail;
   14140             :         }
   14141             : 
   14142           0 :         ret = true;
   14143           0 : fail:
   14144           0 :         TALLOC_FREE(rec);
   14145           0 :         return ret;
   14146             : }
   14147             : 
   14148           0 : static bool run_local_dbtrans(int dummy)
   14149             : {
   14150             :         struct db_context *db;
   14151             :         struct db_record *rec;
   14152             :         NTSTATUS status;
   14153             :         uint32_t initial;
   14154             :         int res;
   14155             :         TDB_DATA value;
   14156             : 
   14157           0 :         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
   14158             :                      O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
   14159             :                      DBWRAP_FLAG_NONE);
   14160           0 :         if (db == NULL) {
   14161           0 :                 printf("Could not open transtest.db\n");
   14162           0 :                 return false;
   14163             :         }
   14164             : 
   14165           0 :         res = dbwrap_transaction_start(db);
   14166           0 :         if (res != 0) {
   14167           0 :                 printf(__location__ "transaction_start failed\n");
   14168           0 :                 return false;
   14169             :         }
   14170             : 
   14171           0 :         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
   14172           0 :         if (rec == NULL) {
   14173           0 :                 printf(__location__ "fetch_lock failed\n");
   14174           0 :                 return false;
   14175             :         }
   14176             : 
   14177           0 :         value = dbwrap_record_get_value(rec);
   14178             : 
   14179           0 :         if (value.dptr == NULL) {
   14180           0 :                 initial = 0;
   14181           0 :                 status = dbwrap_record_store(
   14182             :                         rec, make_tdb_data((uint8_t *)&initial,
   14183             :                                            sizeof(initial)),
   14184             :                         0);
   14185           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14186           0 :                         printf(__location__ "store returned %s\n",
   14187             :                                nt_errstr(status));
   14188           0 :                         return false;
   14189             :                 }
   14190             :         }
   14191             : 
   14192           0 :         TALLOC_FREE(rec);
   14193             : 
   14194           0 :         res = dbwrap_transaction_commit(db);
   14195           0 :         if (res != 0) {
   14196           0 :                 printf(__location__ "transaction_commit failed\n");
   14197           0 :                 return false;
   14198             :         }
   14199             : 
   14200           0 :         while (true) {
   14201             :                 uint32_t val, val2;
   14202             :                 int i;
   14203             : 
   14204           0 :                 res = dbwrap_transaction_start(db);
   14205           0 :                 if (res != 0) {
   14206           0 :                         printf(__location__ "transaction_start failed\n");
   14207           0 :                         break;
   14208             :                 }
   14209             : 
   14210           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
   14211           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14212           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14213             :                                nt_errstr(status));
   14214           0 :                         break;
   14215             :                 }
   14216             : 
   14217           0 :                 for (i=0; i<10; i++) {
   14218           0 :                         if (!dbtrans_inc(db)) {
   14219           0 :                                 return false;
   14220             :                         }
   14221             :                 }
   14222             : 
   14223           0 :                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
   14224           0 :                 if (!NT_STATUS_IS_OK(status)) {
   14225           0 :                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
   14226             :                                nt_errstr(status));
   14227           0 :                         break;
   14228             :                 }
   14229             : 
   14230           0 :                 if (val2 != val + 10) {
   14231           0 :                         printf(__location__ "val=%d, val2=%d\n",
   14232             :                                (int)val, (int)val2);
   14233           0 :                         break;
   14234             :                 }
   14235             : 
   14236           0 :                 printf("val2=%d\r", val2);
   14237             : 
   14238           0 :                 res = dbwrap_transaction_commit(db);
   14239           0 :                 if (res != 0) {
   14240           0 :                         printf(__location__ "transaction_commit failed\n");
   14241           0 :                         break;
   14242             :                 }
   14243             :         }
   14244             : 
   14245           0 :         TALLOC_FREE(db);
   14246           0 :         return true;
   14247             : }
   14248             : 
   14249             : /*
   14250             :  * Just a dummy test to be run under a debugger. There's no real way
   14251             :  * to inspect the tevent_poll specific function from outside of
   14252             :  * tevent_poll.c.
   14253             :  */
   14254             : 
   14255           1 : static bool run_local_tevent_poll(int dummy)
   14256             : {
   14257             :         struct tevent_context *ev;
   14258             :         struct tevent_fd *fd1, *fd2;
   14259           1 :         bool result = false;
   14260             : 
   14261           1 :         ev = tevent_context_init_byname(NULL, "poll");
   14262           1 :         if (ev == NULL) {
   14263           0 :                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
   14264           0 :                 goto fail;
   14265             :         }
   14266             : 
   14267           1 :         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
   14268           1 :         if (fd1 == NULL) {
   14269           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14270           0 :                 goto fail;
   14271             :         }
   14272           1 :         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
   14273           1 :         if (fd2 == NULL) {
   14274           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14275           0 :                 goto fail;
   14276             :         }
   14277           1 :         TALLOC_FREE(fd2);
   14278             : 
   14279           1 :         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
   14280           1 :         if (fd2 == NULL) {
   14281           0 :                 d_fprintf(stderr, "tevent_add_fd failed\n");
   14282           0 :                 goto fail;
   14283             :         }
   14284             : 
   14285           0 :         result = true;
   14286           1 : fail:
   14287           1 :         TALLOC_FREE(ev);
   14288           1 :         return result;
   14289             : }
   14290             : 
   14291           1 : static bool run_local_hex_encode_buf(int dummy)
   14292             : {
   14293             :         char buf[17];
   14294             :         uint8_t src[8];
   14295             :         int i;
   14296             : 
   14297           9 :         for (i=0; i<sizeof(src); i++) {
   14298           8 :                 src[i] = i;
   14299             :         }
   14300           1 :         hex_encode_buf(buf, src, sizeof(src));
   14301           1 :         if (strcmp(buf, "0001020304050607") != 0) {
   14302           0 :                 return false;
   14303             :         }
   14304           1 :         hex_encode_buf(buf, NULL, 0);
   14305           1 :         if (buf[0] != '\0') {
   14306           0 :                 return false;
   14307             :         }
   14308           1 :         return true;
   14309             : }
   14310             : 
   14311             : static const char *remove_duplicate_addrs2_test_strings_vector[] = {
   14312             :         "0.0.0.0",
   14313             :         "::0",
   14314             :         "1.2.3.1",
   14315             :         "0.0.0.0",
   14316             :         "0.0.0.0",
   14317             :         "1.2.3.2",
   14318             :         "1.2.3.3",
   14319             :         "1.2.3.4",
   14320             :         "1.2.3.5",
   14321             :         "::0",
   14322             :         "1.2.3.6",
   14323             :         "1.2.3.7",
   14324             :         "::0",
   14325             :         "::0",
   14326             :         "::0",
   14327             :         "1.2.3.8",
   14328             :         "1.2.3.9",
   14329             :         "1.2.3.10",
   14330             :         "1.2.3.11",
   14331             :         "1.2.3.12",
   14332             :         "1.2.3.13",
   14333             :         "1001:1111:1111:1000:0:1111:1111:1111",
   14334             :         "1.2.3.1",
   14335             :         "1.2.3.2",
   14336             :         "1.2.3.3",
   14337             :         "1.2.3.12",
   14338             :         "::0",
   14339             :         "::0"
   14340             : };
   14341             : 
   14342             : static const char *remove_duplicate_addrs2_test_strings_result[] = {
   14343             :         "1.2.3.1",
   14344             :         "1.2.3.2",
   14345             :         "1.2.3.3",
   14346             :         "1.2.3.4",
   14347             :         "1.2.3.5",
   14348             :         "1.2.3.6",
   14349             :         "1.2.3.7",
   14350             :         "1.2.3.8",
   14351             :         "1.2.3.9",
   14352             :         "1.2.3.10",
   14353             :         "1.2.3.11",
   14354             :         "1.2.3.12",
   14355             :         "1.2.3.13",
   14356             :         "1001:1111:1111:1000:0:1111:1111:1111"
   14357             : };
   14358             : 
   14359           1 : static bool run_local_remove_duplicate_addrs2(int dummy)
   14360             : {
   14361             :         struct samba_sockaddr test_vector[28];
   14362             :         size_t count, i;
   14363             : 
   14364             :         /* Construct the sockaddr_storage test vector. */
   14365          29 :         for (i = 0; i < 28; i++) {
   14366             :                 struct addrinfo hints;
   14367          28 :                 struct addrinfo *res = NULL;
   14368             :                 int ret;
   14369             : 
   14370          28 :                 memset(&hints, '\0', sizeof(hints));
   14371          28 :                 hints.ai_flags = AI_NUMERICHOST;
   14372          28 :                 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
   14373             :                                 NULL,
   14374             :                                 &hints,
   14375             :                                 &res);
   14376          28 :                 if (ret) {
   14377           0 :                         fprintf(stderr, "getaddrinfo failed on [%s]\n",
   14378             :                                 remove_duplicate_addrs2_test_strings_vector[i]);
   14379           0 :                         return false;
   14380             :                 }
   14381          56 :                 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
   14382          84 :                 memcpy(&test_vector[i].u.ss,
   14383          28 :                         res->ai_addr,
   14384          28 :                         res->ai_addrlen);
   14385          28 :                 freeaddrinfo(res);
   14386             :         }
   14387             : 
   14388           1 :         count = remove_duplicate_addrs2(test_vector, i);
   14389             : 
   14390           1 :         if (count != 14) {
   14391           0 :                 fprintf(stderr, "count wrong (%zu) should be 14\n",
   14392             :                         count);
   14393           0 :                 return false;
   14394             :         }
   14395             : 
   14396          14 :         for (i = 0; i < count; i++) {
   14397             :                 char addr[INET6_ADDRSTRLEN];
   14398             : 
   14399          14 :                 print_sockaddr(addr, sizeof(addr), &test_vector[i].u.ss);
   14400             : 
   14401          14 :                 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
   14402           0 :                         fprintf(stderr, "mismatch on [%zu] [%s] [%s]\n",
   14403             :                                 i,
   14404             :                                 addr,
   14405             :                                 remove_duplicate_addrs2_test_strings_result[i]);
   14406           0 :                         return false;
   14407             :                 }
   14408             :         }
   14409             : 
   14410           1 :         printf("run_local_remove_duplicate_addrs2: success\n");
   14411           1 :         return true;
   14412             : }
   14413             : 
   14414           0 : static bool run_local_tdb_opener(int dummy)
   14415             : {
   14416             :         TDB_CONTEXT *t;
   14417           0 :         unsigned v = 0;
   14418             : 
   14419             :         while (1) {
   14420           0 :                 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
   14421             :                              O_RDWR|O_CREAT, 0755);
   14422           0 :                 if (t == NULL) {
   14423           0 :                         perror("tdb_open failed");
   14424           0 :                         return false;
   14425             :                 }
   14426           0 :                 tdb_close(t);
   14427             : 
   14428           0 :                 v += 1;
   14429           0 :                 printf("\r%u", v);
   14430             :         }
   14431             :         return true;
   14432             : }
   14433             : 
   14434           0 : static bool run_local_tdb_writer(int dummy)
   14435             : {
   14436             :         TDB_CONTEXT *t;
   14437           0 :         unsigned v = 0;
   14438             :         TDB_DATA val;
   14439             : 
   14440           0 :         t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
   14441           0 :         if (t == 0) {
   14442           0 :                 perror("tdb_open failed");
   14443           0 :                 return 1;
   14444             :         }
   14445             : 
   14446           0 :         val.dptr = (uint8_t *)&v;
   14447           0 :         val.dsize = sizeof(v);
   14448             : 
   14449           0 :         while (1) {
   14450             :                 TDB_DATA data;
   14451             :                 int ret;
   14452             : 
   14453           0 :                 ret = tdb_store(t, val, val, 0);
   14454           0 :                 if (ret != 0) {
   14455           0 :                         printf("%s\n", tdb_errorstr(t));
   14456             :                 }
   14457           0 :                 v += 1;
   14458           0 :                 printf("\r%u", v);
   14459             : 
   14460           0 :                 data = tdb_fetch(t, val);
   14461           0 :                 if (data.dptr != NULL) {
   14462           0 :                         SAFE_FREE(data.dptr);
   14463             :                 }
   14464             :         }
   14465             :         return true;
   14466             : }
   14467             : 
   14468           1 : static bool run_local_canonicalize_path(int dummy)
   14469             : {
   14470           1 :         const char *src[] = {
   14471             :                         "/foo/..",
   14472             :                         "/..",
   14473             :                         "/foo/bar/../baz",
   14474             :                         "/foo/././",
   14475             :                         "/../foo",
   14476             :                         ".././././",
   14477             :                         ".././././../../../boo",
   14478             :                         "./..",
   14479             :                         "/",
   14480             :                         "/../../",
   14481             :                         "/foo/../",
   14482             :                         "/./././",
   14483             :                         "/./././.",
   14484             :                         "/.../././.",
   14485             :                         "/./././.foo",
   14486             :                         "/./././.foo.",
   14487             :                         "/./././foo.",
   14488             :                         "/foo/bar/..",
   14489             :                         "/foo/bar/../baz/",
   14490             :                         "////////////////",
   14491             :                         "/////////./././././.",
   14492             :                         "/./.././../.boo/../baz",
   14493             :                         "/a/component/path",
   14494             :                         "/a/component/path/",
   14495             :                         "/a/component/path/..",
   14496             :                         "/a/component/../path/",
   14497             :                         "///a/./././///component/../////path/",
   14498             :                         NULL
   14499             :                         };
   14500           1 :         const char *dst[] = {
   14501             :                         "/",
   14502             :                         "/",
   14503             :                         "/foo/baz",
   14504             :                         "/foo",
   14505             :                         "/foo",
   14506             :                         "/",
   14507             :                         "/boo",
   14508             :                         "/",
   14509             :                         "/",
   14510             :                         "/",
   14511             :                         "/",
   14512             :                         "/",
   14513             :                         "/",
   14514             :                         "/...",
   14515             :                         "/.foo",
   14516             :                         "/.foo.",
   14517             :                         "/foo.",
   14518             :                         "/foo",
   14519             :                         "/foo/baz",
   14520             :                         "/",
   14521             :                         "/",
   14522             :                         "/baz",
   14523             :                         "/a/component/path",
   14524             :                         "/a/component/path",
   14525             :                         "/a/component",
   14526             :                         "/a/path",
   14527             :                         "/a/path",
   14528             :                         NULL
   14529             :                         };
   14530             :         unsigned int i;
   14531             : 
   14532          28 :         for (i = 0; src[i] != NULL; i++) {
   14533          27 :                 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
   14534          27 :                 if (d == NULL) {
   14535           0 :                         perror("talloc fail\n");
   14536           0 :                         return false;
   14537             :                 }
   14538          27 :                 if (strcmp(d, dst[i]) != 0) {
   14539           0 :                         d_fprintf(stderr,
   14540             :                                 "canonicalize mismatch %s -> %s != %s",
   14541             :                                 src[i], d, dst[i]);
   14542           0 :                         return false;
   14543             :                 }
   14544          27 :                 talloc_free(d);
   14545             :         }
   14546           0 :         return true;
   14547             : }
   14548             : 
   14549           0 : static bool run_ign_bad_negprot(int dummy)
   14550             : {
   14551             :         struct tevent_context *ev;
   14552             :         struct tevent_req *req;
   14553             :         struct smbXcli_conn *conn;
   14554             :         struct sockaddr_storage ss;
   14555             :         NTSTATUS status;
   14556             :         int fd;
   14557             :         bool ok;
   14558             : 
   14559           0 :         printf("starting ignore bad negprot\n");
   14560             : 
   14561           0 :         ok = resolve_name(host, &ss, 0x20, true);
   14562           0 :         if (!ok) {
   14563           0 :                 d_fprintf(stderr, "Could not resolve name %s\n", host);
   14564           0 :                 return false;
   14565             :         }
   14566             : 
   14567           0 :         status = open_socket_out(&ss, 445, 10000, &fd);
   14568           0 :         if (!NT_STATUS_IS_OK(status)) {
   14569           0 :                 d_fprintf(stderr, "open_socket_out failed: %s\n",
   14570             :                           nt_errstr(status));
   14571           0 :                 return false;
   14572             :         }
   14573             : 
   14574           0 :         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
   14575             :                                    NULL, 0, NULL);
   14576           0 :         if (conn == NULL) {
   14577           0 :                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
   14578           0 :                 return false;
   14579             :         }
   14580             : 
   14581           0 :         status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
   14582           0 :         if (NT_STATUS_IS_OK(status)) {
   14583           0 :                 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
   14584           0 :                 return false;
   14585             :         }
   14586             : 
   14587           0 :         ev = samba_tevent_context_init(talloc_tos());
   14588           0 :         if (ev == NULL) {
   14589           0 :                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
   14590           0 :                 return false;
   14591             :         }
   14592             : 
   14593           0 :         req = smb1cli_session_setup_nt1_send(
   14594           0 :                 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
   14595             :                 data_blob_null, data_blob_null, 0x40,
   14596             :                 "Windows 2000 2195", "Windows 2000 5.0");
   14597           0 :         if (req == NULL) {
   14598           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
   14599           0 :                 return false;
   14600             :         }
   14601             : 
   14602           0 :         ok = tevent_req_poll_ntstatus(req, ev, &status);
   14603           0 :         if (!ok) {
   14604           0 :                 d_fprintf(stderr, "tevent_req_poll failed\n");
   14605           0 :                 return false;
   14606             :         }
   14607             : 
   14608           0 :         status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
   14609             :                                                 NULL, NULL);
   14610           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
   14611           0 :                 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
   14612             :                           "%s, expected NT_STATUS_CONNECTION_RESET\n",
   14613             :                           nt_errstr(status));
   14614           0 :                 return false;
   14615             :         }
   14616             : 
   14617           0 :         TALLOC_FREE(conn);
   14618             : 
   14619           0 :         printf("starting ignore bad negprot\n");
   14620             : 
   14621           0 :         return true;
   14622             : }
   14623             : 
   14624          16 : static double create_procs(bool (*fn)(int), bool *result)
   14625             : {
   14626             :         int i, status;
   14627             :         volatile pid_t *child_status;
   14628             :         volatile bool *child_status_out;
   14629             :         int synccount;
   14630          16 :         int tries = 8;
   14631             :         struct timeval start;
   14632             : 
   14633          16 :         synccount = 0;
   14634             : 
   14635          16 :         child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
   14636          16 :         if (!child_status) {
   14637           0 :                 printf("Failed to setup shared memory\n");
   14638           0 :                 return -1;
   14639             :         }
   14640             : 
   14641          16 :         child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
   14642          16 :         if (!child_status_out) {
   14643           0 :                 printf("Failed to setup result status shared memory\n");
   14644           0 :                 return -1;
   14645             :         }
   14646             : 
   14647          32 :         for (i = 0; i < torture_nprocs; i++) {
   14648          16 :                 child_status[i] = 0;
   14649          16 :                 child_status_out[i] = True;
   14650             :         }
   14651             : 
   14652          16 :         start = timeval_current();
   14653             : 
   14654          32 :         for (i=0;i<torture_nprocs;i++) {
   14655          16 :                 procnum = i;
   14656          16 :                 if (fork() == 0) {
   14657           0 :                         pid_t mypid = getpid();
   14658           0 :                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
   14659             : 
   14660           0 :                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
   14661             : 
   14662             :                         while (1) {
   14663           0 :                                 if (torture_open_connection(&current_cli, i)) break;
   14664           0 :                                 if (tries-- == 0) {
   14665           0 :                                         printf("pid %d failed to start\n", (int)getpid());
   14666           0 :                                         _exit(1);
   14667             :                                 }
   14668           0 :                                 smb_msleep(10); 
   14669             :                         }
   14670             : 
   14671           0 :                         child_status[i] = getpid();
   14672             : 
   14673           0 :                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
   14674             : 
   14675           0 :                         child_status_out[i] = fn(i);
   14676           0 :                         _exit(0);
   14677             :                 }
   14678             :         }
   14679             : 
   14680             :         do {
   14681         206 :                 synccount = 0;
   14682         412 :                 for (i=0;i<torture_nprocs;i++) {
   14683         206 :                         if (child_status[i]) synccount++;
   14684             :                 }
   14685         206 :                 if (synccount == torture_nprocs) break;
   14686         190 :                 smb_msleep(10);
   14687         190 :         } while (timeval_elapsed(&start) < 30);
   14688             : 
   14689          16 :         if (synccount != torture_nprocs) {
   14690           0 :                 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
   14691           0 :                 *result = False;
   14692           0 :                 return timeval_elapsed(&start);
   14693             :         }
   14694             : 
   14695             :         /* start the client load */
   14696          16 :         start = timeval_current();
   14697             : 
   14698          32 :         for (i=0;i<torture_nprocs;i++) {
   14699          16 :                 child_status[i] = 0;
   14700             :         }
   14701             : 
   14702          16 :         printf("%d clients started\n", torture_nprocs);
   14703             : 
   14704          32 :         for (i=0;i<torture_nprocs;i++) {
   14705          16 :                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
   14706             :         }
   14707             : 
   14708          16 :         printf("\n");
   14709             : 
   14710          32 :         for (i=0;i<torture_nprocs;i++) {
   14711          16 :                 if (!child_status_out[i]) {
   14712           2 :                         *result = False;
   14713             :                 }
   14714             :         }
   14715          16 :         return timeval_elapsed(&start);
   14716             : }
   14717             : 
   14718             : #define FLAG_MULTIPROC 1
   14719             : 
   14720             : static struct {
   14721             :         const char *name;
   14722             :         bool (*fn)(int);
   14723             :         unsigned flags;
   14724             : } torture_ops[] = {
   14725             :         {
   14726             :                 .name = "FDPASS",
   14727             :                 .fn   = run_fdpasstest,
   14728             :         },
   14729             :         {
   14730             :                 .name = "LOCK1",
   14731             :                 .fn   = run_locktest1,
   14732             :         },
   14733             :         {
   14734             :                 .name = "LOCK2",
   14735             :                 .fn   =  run_locktest2,
   14736             :         },
   14737             :         {
   14738             :                 .name = "LOCK3",
   14739             :                 .fn   =  run_locktest3,
   14740             :         },
   14741             :         {
   14742             :                 .name = "LOCK4",
   14743             :                 .fn   =  run_locktest4,
   14744             :         },
   14745             :         {
   14746             :                 .name = "LOCK5",
   14747             :                 .fn   =  run_locktest5,
   14748             :         },
   14749             :         {
   14750             :                 .name = "LOCK6",
   14751             :                 .fn   =  run_locktest6,
   14752             :         },
   14753             :         {
   14754             :                 .name = "LOCK7",
   14755             :                 .fn   =  run_locktest7,
   14756             :         },
   14757             :         {
   14758             :                 .name = "LOCK8",
   14759             :                 .fn   =  run_locktest8,
   14760             :         },
   14761             :         {
   14762             :                 .name = "LOCK9A",
   14763             :                 .fn   =  run_locktest9a,
   14764             :         },
   14765             :         {
   14766             :                 .name = "LOCK9B",
   14767             :                 .fn   =  run_locktest9b,
   14768             :         },
   14769             :         {
   14770             :                 .name = "LOCK10",
   14771             :                 .fn   =  run_locktest10,
   14772             :         },
   14773             :         {
   14774             :                 .name = "LOCK11",
   14775             :                 .fn   =  run_locktest11,
   14776             :         },
   14777             :         {
   14778             :                 .name = "LOCK12",
   14779             :                 .fn   =  run_locktest12,
   14780             :         },
   14781             :         {
   14782             :                 .name = "LOCK13",
   14783             :                 .fn   =  run_locktest13,
   14784             :         },
   14785             :         {
   14786             :                 .name = "UNLINK",
   14787             :                 .fn   = run_unlinktest,
   14788             :         },
   14789             :         {
   14790             :                 .name = "BROWSE",
   14791             :                 .fn   = run_browsetest,
   14792             :         },
   14793             :         {
   14794             :                 .name = "ATTR",
   14795             :                 .fn   =   run_attrtest,
   14796             :         },
   14797             :         {
   14798             :                 .name = "TRANS2",
   14799             :                 .fn   = run_trans2test,
   14800             :         },
   14801             :         {
   14802             :                 .name  = "MAXFID",
   14803             :                 .fn    = run_maxfidtest,
   14804             :                 .flags = FLAG_MULTIPROC,
   14805             :         },
   14806             :         {
   14807             :                 .name  = "TORTURE",
   14808             :                 .fn    = run_torture,
   14809             :                 .flags = FLAG_MULTIPROC,
   14810             :         },
   14811             :         {
   14812             :                 .name  = "RANDOMIPC",
   14813             :                 .fn    = run_randomipc,
   14814             :         },
   14815             :         {
   14816             :                 .name  = "NEGNOWAIT",
   14817             :                 .fn    = run_negprot_nowait,
   14818             :         },
   14819             :         {
   14820             :                 .name  = "NBENCH",
   14821             :                 .fn    =  run_nbench,
   14822             :         },
   14823             :         {
   14824             :                 .name  = "NBENCH2",
   14825             :                 .fn    = run_nbench2,
   14826             :         },
   14827             :         {
   14828             :                 .name  = "OPLOCK1",
   14829             :                 .fn    =  run_oplock1,
   14830             :         },
   14831             :         {
   14832             :                 .name  = "OPLOCK2",
   14833             :                 .fn    =  run_oplock2,
   14834             :         },
   14835             :         {
   14836             :                 .name  = "OPLOCK4",
   14837             :                 .fn    =  run_oplock4,
   14838             :         },
   14839             : #ifdef HAVE_KERNEL_OPLOCKS_LINUX
   14840             :         {
   14841             :                 .name  = "OPLOCK5",
   14842             :                 .fn    =  run_oplock5,
   14843             :         },
   14844             : #endif
   14845             :         {
   14846             :                 .name  = "DIR",
   14847             :                 .fn    =  run_dirtest,
   14848             :         },
   14849             :         {
   14850             :                 .name  = "DIR1",
   14851             :                 .fn    =  run_dirtest1,
   14852             :         },
   14853             :         {
   14854             :                 .name  = "DIR-CREATETIME",
   14855             :                 .fn    =  run_dir_createtime,
   14856             :         },
   14857             :         {
   14858             :                 .name  = "DENY1",
   14859             :                 .fn    =  torture_denytest1,
   14860             :         },
   14861             :         {
   14862             :                 .name  = "DENY2",
   14863             :                 .fn    =  torture_denytest2,
   14864             :         },
   14865             :         {
   14866             :                 .name  = "TCON",
   14867             :                 .fn    =  run_tcon_test,
   14868             :         },
   14869             :         {
   14870             :                 .name  = "TCONDEV",
   14871             :                 .fn    =  run_tcon_devtype_test,
   14872             :         },
   14873             :         {
   14874             :                 .name  = "RW1",
   14875             :                 .fn    =  run_readwritetest,
   14876             :         },
   14877             :         {
   14878             :                 .name  = "RW2",
   14879             :                 .fn    =  run_readwritemulti,
   14880             :                 .flags = FLAG_MULTIPROC
   14881             :         },
   14882             :         {
   14883             :                 .name  = "RW3",
   14884             :                 .fn    =  run_readwritelarge,
   14885             :         },
   14886             :         {
   14887             :                 .name  = "RW-SIGNING",
   14888             :                 .fn    =  run_readwritelarge_signtest,
   14889             :         },
   14890             :         {
   14891             :                 .name  = "OPEN",
   14892             :                 .fn    = run_opentest,
   14893             :         },
   14894             :         {
   14895             :                 .name  = "POSIX",
   14896             :                 .fn    = run_simple_posix_open_test,
   14897             :         },
   14898             :         {
   14899             :                 .name  = "POSIX-APPEND",
   14900             :                 .fn    = run_posix_append,
   14901             :         },
   14902             :         {
   14903             :                 .name  = "POSIX-SYMLINK-ACL",
   14904             :                 .fn    = run_acl_symlink_test,
   14905             :         },
   14906             :         {
   14907             :                 .name  = "POSIX-SYMLINK-EA",
   14908             :                 .fn    = run_ea_symlink_test,
   14909             :         },
   14910             :         {
   14911             :                 .name  = "POSIX-STREAM-DELETE",
   14912             :                 .fn    = run_posix_stream_delete,
   14913             :         },
   14914             :         {
   14915             :                 .name  = "POSIX-OFD-LOCK",
   14916             :                 .fn    = run_posix_ofd_lock_test,
   14917             :         },
   14918             :         {
   14919             :                 .name  = "POSIX-BLOCKING-LOCK",
   14920             :                 .fn    = run_posix_blocking_lock,
   14921             :         },
   14922             :         {
   14923             :                 .name  = "POSIX-MKDIR",
   14924             :                 .fn    = run_posix_mkdir_test,
   14925             :         },
   14926             :         {
   14927             :                 .name  = "POSIX-ACL-OPLOCK",
   14928             :                 .fn    = run_posix_acl_oplock_test,
   14929             :         },
   14930             :         {
   14931             :                 .name  = "POSIX-ACL-SHAREROOT",
   14932             :                 .fn    = run_posix_acl_shareroot_test,
   14933             :         },
   14934             :         {
   14935             :                 .name  = "POSIX-LS-WILDCARD",
   14936             :                 .fn    = run_posix_ls_wildcard_test,
   14937             :         },
   14938             :         {
   14939             :                 .name  = "POSIX-LS-SINGLE",
   14940             :                 .fn    = run_posix_ls_single_test,
   14941             :         },
   14942             :         {
   14943             :                 .name  = "POSIX-READLINK",
   14944             :                 .fn    = run_posix_readlink_test,
   14945             :         },
   14946             :         {
   14947             :                 .name  = "POSIX-STAT",
   14948             :                 .fn    = run_posix_stat_test,
   14949             :         },
   14950             :         {
   14951             :                 .name  = "POSIX-SYMLINK-PARENT",
   14952             :                 .fn    = run_posix_symlink_parent_test,
   14953             :         },
   14954             :         {
   14955             :                 .name  = "POSIX-SYMLINK-CHMOD",
   14956             :                 .fn    = run_posix_symlink_chmod_test,
   14957             :         },
   14958             :         {
   14959             :                 .name  = "POSIX-SYMLINK-RENAME",
   14960             :                 .fn    = run_posix_symlink_rename_test,
   14961             :         },
   14962             :         {
   14963             :                 .name  = "POSIX-DIR-DEFAULT-ACL",
   14964             :                 .fn    = run_posix_dir_default_acl_test,
   14965             :         },
   14966             :         {
   14967             :                 .name  = "POSIX-SYMLINK-GETPATHINFO",
   14968             :                 .fn    = run_posix_symlink_getpathinfo_test,
   14969             :         },
   14970             :         {
   14971             :                 .name  = "POSIX-SYMLINK-SETPATHINFO",
   14972             :                 .fn    = run_posix_symlink_setpathinfo_test,
   14973             :         },
   14974             :         {
   14975             :                 .name  = "WINDOWS-BAD-SYMLINK",
   14976             :                 .fn    = run_symlink_open_test,
   14977             :         },
   14978             :         {
   14979             :                 .name  = "SMB1-WILD-MANGLE-UNLINK",
   14980             :                 .fn    = run_smb1_wild_mangle_unlink_test,
   14981             :         },
   14982             :         {
   14983             :                 .name  = "SMB1-WILD-MANGLE-RENAME",
   14984             :                 .fn    = run_smb1_wild_mangle_rename_test,
   14985             :         },
   14986             :         {
   14987             :                 .name  = "CASE-INSENSITIVE-CREATE",
   14988             :                 .fn    = run_case_insensitive_create,
   14989             :         },
   14990             :         {
   14991             :                 .name  = "ASYNC-ECHO",
   14992             :                 .fn    = run_async_echo,
   14993             :         },
   14994             :         {
   14995             :                 .name  = "UID-REGRESSION-TEST",
   14996             :                 .fn    = run_uid_regression_test,
   14997             :         },
   14998             :         {
   14999             :                 .name  = "SHORTNAME-TEST",
   15000             :                 .fn    = run_shortname_test,
   15001             :         },
   15002             :         {
   15003             :                 .name  = "ADDRCHANGE",
   15004             :                 .fn    = run_addrchange,
   15005             :         },
   15006             : #if 1
   15007             :         {
   15008             :                 .name  = "OPENATTR",
   15009             :                 .fn    = run_openattrtest,
   15010             :         },
   15011             : #endif
   15012             :         {
   15013             :                 .name  = "XCOPY",
   15014             :                 .fn    = run_xcopy,
   15015             :         },
   15016             :         {
   15017             :                 .name  = "RENAME",
   15018             :                 .fn    = run_rename,
   15019             :         },
   15020             :         {
   15021             :                 .name  = "RENAME-ACCESS",
   15022             :                 .fn    = run_rename_access,
   15023             :         },
   15024             :         {
   15025             :                 .name  = "OWNER-RIGHTS",
   15026             :                 .fn    = run_owner_rights,
   15027             :         },
   15028             :         {
   15029             :                 .name  = "DELETE",
   15030             :                 .fn    = run_deletetest,
   15031             :         },
   15032             :         {
   15033             :                 .name  = "DELETE-STREAM",
   15034             :                 .fn    = run_delete_stream,
   15035             :         },
   15036             :         {
   15037             :                 .name  = "DELETE-PRINT",
   15038             :                 .fn    = run_delete_print_test,
   15039             :         },
   15040             :         {
   15041             :                 .name  = "WILDDELETE",
   15042             :                 .fn    = run_wild_deletetest,
   15043             :         },
   15044             :         {
   15045             :                 .name  = "DELETE-LN",
   15046             :                 .fn    = run_deletetest_ln,
   15047             :         },
   15048             :         {
   15049             :                 .name  = "PROPERTIES",
   15050             :                 .fn    = run_properties,
   15051             :         },
   15052             :         {
   15053             :                 .name  = "MANGLE",
   15054             :                 .fn    = torture_mangle,
   15055             :         },
   15056             :         {
   15057             :                 .name  = "MANGLE1",
   15058             :                 .fn    = run_mangle1,
   15059             :         },
   15060             :         {
   15061             :                 .name  = "MANGLE-ILLEGAL",
   15062             :                 .fn    = run_mangle_illegal,
   15063             :         },
   15064             :         {
   15065             :                 .name  = "W2K",
   15066             :                 .fn    = run_w2ktest,
   15067             :         },
   15068             :         {
   15069             :                 .name  = "TRANS2SCAN",
   15070             :                 .fn    = torture_trans2_scan,
   15071             :         },
   15072             :         {
   15073             :                 .name  = "NTTRANSSCAN",
   15074             :                 .fn    = torture_nttrans_scan,
   15075             :         },
   15076             :         {
   15077             :                 .name  = "UTABLE",
   15078             :                 .fn    = torture_utable,
   15079             :         },
   15080             :         {
   15081             :                 .name  = "CASETABLE",
   15082             :                 .fn    = torture_casetable,
   15083             :         },
   15084             :         {
   15085             :                 .name  = "ERRMAPEXTRACT",
   15086             :                 .fn    = run_error_map_extract,
   15087             :         },
   15088             :         {
   15089             :                 .name  = "PIPE_NUMBER",
   15090             :                 .fn    = run_pipe_number,
   15091             :         },
   15092             :         {
   15093             :                 .name  = "TCON2",
   15094             :                 .fn    =  run_tcon2_test,
   15095             :         },
   15096             :         {
   15097             :                 .name  = "IOCTL",
   15098             :                 .fn    =  torture_ioctl_test,
   15099             :         },
   15100             :         {
   15101             :                 .name  = "CHKPATH",
   15102             :                 .fn    =  torture_chkpath_test,
   15103             :         },
   15104             :         {
   15105             :                 .name  = "FDSESS",
   15106             :                 .fn    = run_fdsesstest,
   15107             :         },
   15108             :         {
   15109             :                 .name  = "EATEST",
   15110             :                 .fn    = run_eatest,
   15111             :         },
   15112             :         {
   15113             :                 .name  = "SESSSETUP_BENCH",
   15114             :                 .fn    = run_sesssetup_bench,
   15115             :         },
   15116             :         {
   15117             :                 .name  = "CHAIN1",
   15118             :                 .fn    = run_chain1,
   15119             :         },
   15120             :         {
   15121             :                 .name  = "CHAIN2",
   15122             :                 .fn    = run_chain2,
   15123             :         },
   15124             :         {
   15125             :                 .name  = "CHAIN3",
   15126             :                 .fn    = run_chain3,
   15127             :         },
   15128             :         {
   15129             :                 .name  = "WINDOWS-WRITE",
   15130             :                 .fn    = run_windows_write,
   15131             :         },
   15132             :         {
   15133             :                 .name  = "LARGE_READX",
   15134             :                 .fn    = run_large_readx,
   15135             :         },
   15136             :         {
   15137             :                 .name  = "MSDFS-ATTRIBUTE",
   15138             :                 .fn    = run_msdfs_attribute,
   15139             :         },
   15140             :         {
   15141             :                 .name  = "NTTRANS-CREATE",
   15142             :                 .fn    = run_nttrans_create,
   15143             :         },
   15144             :         {
   15145             :                 .name  = "NTTRANS-FSCTL",
   15146             :                 .fn    = run_nttrans_fsctl,
   15147             :         },
   15148             :         {
   15149             :                 .name  = "CLI_ECHO",
   15150             :                 .fn    = run_cli_echo,
   15151             :         },
   15152             :         {
   15153             :                 .name  = "CLI_SPLICE",
   15154             :                 .fn    = run_cli_splice,
   15155             :         },
   15156             :         {
   15157             :                 .name  = "TLDAP",
   15158             :                 .fn    = run_tldap,
   15159             :         },
   15160             :         {
   15161             :                 .name  = "STREAMERROR",
   15162             :                 .fn    = run_streamerror,
   15163             :         },
   15164             :         {
   15165             :                 .name  = "NOTIFY-BENCH",
   15166             :                 .fn    = run_notify_bench,
   15167             :         },
   15168             :         {
   15169             :                 .name  = "NOTIFY-BENCH2",
   15170             :                 .fn    = run_notify_bench2,
   15171             :         },
   15172             :         {
   15173             :                 .name  = "NOTIFY-BENCH3",
   15174             :                 .fn    = run_notify_bench3,
   15175             :         },
   15176             :         {
   15177             :                 .name  = "BAD-NBT-SESSION",
   15178             :                 .fn    = run_bad_nbt_session,
   15179             :         },
   15180             :         {
   15181             :                 .name  = "IGN-BAD-NEGPROT",
   15182             :                 .fn    = run_ign_bad_negprot,
   15183             :         },
   15184             :         {
   15185             :                 .name  = "SMB-ANY-CONNECT",
   15186             :                 .fn    = run_smb_any_connect,
   15187             :         },
   15188             :         {
   15189             :                 .name  = "NOTIFY-ONLINE",
   15190             :                 .fn    = run_notify_online,
   15191             :         },
   15192             :         {
   15193             :                 .name  = "SMB2-BASIC",
   15194             :                 .fn    = run_smb2_basic,
   15195             :         },
   15196             :         {
   15197             :                 .name  = "SMB2-NEGPROT",
   15198             :                 .fn    = run_smb2_negprot,
   15199             :         },
   15200             :         {
   15201             :                 .name  = "SMB2-ANONYMOUS",
   15202             :                 .fn    = run_smb2_anonymous,
   15203             :         },
   15204             :         {
   15205             :                 .name  = "SMB2-SESSION-RECONNECT",
   15206             :                 .fn    = run_smb2_session_reconnect,
   15207             :         },
   15208             :         {
   15209             :                 .name  = "SMB2-TCON-DEPENDENCE",
   15210             :                 .fn    = run_smb2_tcon_dependence,
   15211             :         },
   15212             :         {
   15213             :                 .name  = "SMB2-MULTI-CHANNEL",
   15214             :                 .fn    = run_smb2_multi_channel,
   15215             :         },
   15216             :         {
   15217             :                 .name  = "SMB2-SESSION-REAUTH",
   15218             :                 .fn    = run_smb2_session_reauth,
   15219             :         },
   15220             :         {
   15221             :                 .name  = "SMB2-FTRUNCATE",
   15222             :                 .fn    = run_smb2_ftruncate,
   15223             :         },
   15224             :         {
   15225             :                 .name  = "SMB2-DIR-FSYNC",
   15226             :                 .fn    = run_smb2_dir_fsync,
   15227             :         },
   15228             :         {
   15229             :                 .name  = "SMB2-PATH-SLASH",
   15230             :                 .fn    = run_smb2_path_slash,
   15231             :         },
   15232             :         {
   15233             :                 .name  = "SMB1-SYSTEM-SECURITY",
   15234             :                 .fn    = run_smb1_system_security,
   15235             :         },
   15236             :         {
   15237             :                 .name  = "SMB2-SACL",
   15238             :                 .fn    = run_smb2_sacl,
   15239             :         },
   15240             :         {
   15241             :                 .name  = "SMB2-QUOTA1",
   15242             :                 .fn    = run_smb2_quota1,
   15243             :         },
   15244             :         {
   15245             :                 .name  = "SMB2-STREAM-ACL",
   15246             :                 .fn    = run_smb2_stream_acl,
   15247             :         },
   15248             :         {
   15249             :                 .name  = "SMB2-LIST-DIR-ASYNC",
   15250             :                 .fn    = run_list_dir_async_test,
   15251             :         },
   15252             :         {
   15253             :                 .name  = "CLEANUP1",
   15254             :                 .fn    = run_cleanup1,
   15255             :         },
   15256             :         {
   15257             :                 .name  = "CLEANUP2",
   15258             :                 .fn    = run_cleanup2,
   15259             :         },
   15260             :         {
   15261             :                 .name  = "CLEANUP4",
   15262             :                 .fn    = run_cleanup4,
   15263             :         },
   15264             :         {
   15265             :                 .name  = "OPLOCK-CANCEL",
   15266             :                 .fn    = run_oplock_cancel,
   15267             :         },
   15268             :         {
   15269             :                 .name  = "PIDHIGH",
   15270             :                 .fn    = run_pidhigh,
   15271             :         },
   15272             :         {
   15273             :                 .name  = "LOCAL-SUBSTITUTE",
   15274             :                 .fn    = run_local_substitute,
   15275             :         },
   15276             :         {
   15277             :                 .name  = "LOCAL-GENCACHE",
   15278             :                 .fn    = run_local_gencache,
   15279             :         },
   15280             :         {
   15281             :                 .name  = "LOCAL-DBWRAP-WATCH1",
   15282             :                 .fn    = run_dbwrap_watch1,
   15283             :         },
   15284             :         {
   15285             :                 .name  = "LOCAL-DBWRAP-WATCH2",
   15286             :                 .fn    = run_dbwrap_watch2,
   15287             :         },
   15288             :         {
   15289             :                 .name  = "LOCAL-DBWRAP-WATCH3",
   15290             :                 .fn    = run_dbwrap_watch3,
   15291             :         },
   15292             :         {
   15293             :                 .name  = "LOCAL-DBWRAP-WATCH4",
   15294             :                 .fn    = run_dbwrap_watch4,
   15295             :         },
   15296             :         {
   15297             :                 .name  = "LOCAL-DBWRAP-DO-LOCKED1",
   15298             :                 .fn    = run_dbwrap_do_locked1,
   15299             :         },
   15300             :         {
   15301             :                 .name  = "LOCAL-MESSAGING-READ1",
   15302             :                 .fn    = run_messaging_read1,
   15303             :         },
   15304             :         {
   15305             :                 .name  = "LOCAL-MESSAGING-READ2",
   15306             :                 .fn    = run_messaging_read2,
   15307             :         },
   15308             :         {
   15309             :                 .name  = "LOCAL-MESSAGING-READ3",
   15310             :                 .fn    = run_messaging_read3,
   15311             :         },
   15312             :         {
   15313             :                 .name  = "LOCAL-MESSAGING-READ4",
   15314             :                 .fn    = run_messaging_read4,
   15315             :         },
   15316             :         {
   15317             :                 .name  = "LOCAL-MESSAGING-FDPASS1",
   15318             :                 .fn    = run_messaging_fdpass1,
   15319             :         },
   15320             :         {
   15321             :                 .name  = "LOCAL-MESSAGING-FDPASS2",
   15322             :                 .fn    = run_messaging_fdpass2,
   15323             :         },
   15324             :         {
   15325             :                 .name  = "LOCAL-MESSAGING-FDPASS2a",
   15326             :                 .fn    = run_messaging_fdpass2a,
   15327             :         },
   15328             :         {
   15329             :                 .name  = "LOCAL-MESSAGING-FDPASS2b",
   15330             :                 .fn    = run_messaging_fdpass2b,
   15331             :         },
   15332             :         {
   15333             :                 .name  = "LOCAL-MESSAGING-SEND-ALL",
   15334             :                 .fn    = run_messaging_send_all,
   15335             :         },
   15336             :         {
   15337             :                 .name  = "LOCAL-BASE64",
   15338             :                 .fn    = run_local_base64,
   15339             :         },
   15340             :         {
   15341             :                 .name  = "LOCAL-RBTREE",
   15342             :                 .fn    = run_local_rbtree,
   15343             :         },
   15344             :         {
   15345             :                 .name  = "LOCAL-MEMCACHE",
   15346             :                 .fn    = run_local_memcache,
   15347             :         },
   15348             :         {
   15349             :                 .name  = "LOCAL-STREAM-NAME",
   15350             :                 .fn    = run_local_stream_name,
   15351             :         },
   15352             :         {
   15353             :                 .name  = "LOCAL-STR-MATCH-MSWILD",
   15354             :                 .fn    = run_str_match_mswild,
   15355             :         },
   15356             :         {
   15357             :                 .name  = "LOCAL-STR-MATCH-REGEX-SUB1",
   15358             :                 .fn    = run_str_match_regex_sub1,
   15359             :         },
   15360             :         {
   15361             :                 .name  = "WBCLIENT-MULTI-PING",
   15362             :                 .fn    = run_wbclient_multi_ping,
   15363             :         },
   15364             :         {
   15365             :                 .name  = "LOCAL-string_to_sid",
   15366             :                 .fn    = run_local_string_to_sid,
   15367             :         },
   15368             :         {
   15369             :                 .name  = "LOCAL-sid_to_string",
   15370             :                 .fn    = run_local_sid_to_string,
   15371             :         },
   15372             :         {
   15373             :                 .name  = "LOCAL-binary_to_sid",
   15374             :                 .fn    = run_local_binary_to_sid,
   15375             :         },
   15376             :         {
   15377             :                 .name  = "LOCAL-DBTRANS",
   15378             :                 .fn    = run_local_dbtrans,
   15379             :         },
   15380             :         {
   15381             :                 .name  = "LOCAL-TEVENT-POLL",
   15382             :                 .fn    = run_local_tevent_poll,
   15383             :         },
   15384             :         {
   15385             :                 .name  = "LOCAL-CONVERT-STRING",
   15386             :                 .fn    = run_local_convert_string,
   15387             :         },
   15388             :         {
   15389             :                 .name  = "LOCAL-CONV-AUTH-INFO",
   15390             :                 .fn    = run_local_conv_auth_info,
   15391             :         },
   15392             :         {
   15393             :                 .name  = "LOCAL-hex_encode_buf",
   15394             :                 .fn    = run_local_hex_encode_buf,
   15395             :         },
   15396             :         {
   15397             :                 .name  = "LOCAL-IDMAP-TDB-COMMON",
   15398             :                 .fn    = run_idmap_tdb_common_test,
   15399             :         },
   15400             :         {
   15401             :                 .name  = "LOCAL-remove_duplicate_addrs2",
   15402             :                 .fn    = run_local_remove_duplicate_addrs2,
   15403             :         },
   15404             :         {
   15405             :                 .name  = "local-tdb-opener",
   15406             :                 .fn    = run_local_tdb_opener,
   15407             :         },
   15408             :         {
   15409             :                 .name  = "local-tdb-writer",
   15410             :                 .fn    = run_local_tdb_writer,
   15411             :         },
   15412             :         {
   15413             :                 .name  = "LOCAL-DBWRAP-CTDB1",
   15414             :                 .fn    = run_local_dbwrap_ctdb1,
   15415             :         },
   15416             :         {
   15417             :                 .name  = "LOCAL-BENCH-PTHREADPOOL",
   15418             :                 .fn    = run_bench_pthreadpool,
   15419             :         },
   15420             :         {
   15421             :                 .name  = "LOCAL-PTHREADPOOL-TEVENT",
   15422             :                 .fn    = run_pthreadpool_tevent,
   15423             :         },
   15424             :         {
   15425             :                 .name  = "LOCAL-G-LOCK1",
   15426             :                 .fn    = run_g_lock1,
   15427             :         },
   15428             :         {
   15429             :                 .name  = "LOCAL-G-LOCK2",
   15430             :                 .fn    = run_g_lock2,
   15431             :         },
   15432             :         {
   15433             :                 .name  = "LOCAL-G-LOCK3",
   15434             :                 .fn    = run_g_lock3,
   15435             :         },
   15436             :         {
   15437             :                 .name  = "LOCAL-G-LOCK4",
   15438             :                 .fn    = run_g_lock4,
   15439             :         },
   15440             :         {
   15441             :                 .name  = "LOCAL-G-LOCK4A",
   15442             :                 .fn    = run_g_lock4a,
   15443             :         },
   15444             :         {
   15445             :                 .name  = "LOCAL-G-LOCK5",
   15446             :                 .fn    = run_g_lock5,
   15447             :         },
   15448             :         {
   15449             :                 .name  = "LOCAL-G-LOCK6",
   15450             :                 .fn    = run_g_lock6,
   15451             :         },
   15452             :         {
   15453             :                 .name  = "LOCAL-G-LOCK7",
   15454             :                 .fn    = run_g_lock7,
   15455             :         },
   15456             :         {
   15457             :                 .name  = "LOCAL-G-LOCK8",
   15458             :                 .fn    = run_g_lock8,
   15459             :         },
   15460             :         {
   15461             :                 .name  = "LOCAL-G-LOCK-PING-PONG",
   15462             :                 .fn    = run_g_lock_ping_pong,
   15463             :         },
   15464             :         {
   15465             :                 .name  = "LOCAL-CANONICALIZE-PATH",
   15466             :                 .fn    = run_local_canonicalize_path,
   15467             :         },
   15468             :         {
   15469             :                 .name  = "LOCAL-NAMEMAP-CACHE1",
   15470             :                 .fn    = run_local_namemap_cache1,
   15471             :         },
   15472             :         {
   15473             :                 .name  = "LOCAL-IDMAP-CACHE1",
   15474             :                 .fn    = run_local_idmap_cache1,
   15475             :         },
   15476             :         {
   15477             :                 .name  = "qpathinfo-bufsize",
   15478             :                 .fn    = run_qpathinfo_bufsize,
   15479             :         },
   15480             :         {
   15481             :                 .name  = "hide-new-files-timeout",
   15482             :                 .fn    = run_hidenewfiles,
   15483             :         },
   15484             : #ifdef CLUSTER_SUPPORT
   15485             :         {
   15486             :                 .name  = "ctdbd-conn1",
   15487             :                 .fn    = run_ctdbd_conn1,
   15488             :         },
   15489             : #endif
   15490             :         {
   15491             :                 .name  = "readdir-timestamp",
   15492             :                 .fn    = run_readdir_timestamp,
   15493             :         },
   15494             :         {
   15495             :                 .name = NULL,
   15496             :         },
   15497             : };
   15498             : 
   15499             : /****************************************************************************
   15500             : run a specified test or "ALL"
   15501             : ****************************************************************************/
   15502         520 : static bool run_test(const char *name)
   15503             : {
   15504         520 :         bool ret = True;
   15505         520 :         bool result = True;
   15506         520 :         bool found = False;
   15507             :         int i;
   15508             :         double t;
   15509         520 :         if (strequal(name,"ALL")) {
   15510           0 :                 for (i=0;torture_ops[i].name;i++) {
   15511           0 :                         run_test(torture_ops[i].name);
   15512             :                 }
   15513           0 :                 found = True;
   15514             :         }
   15515             : 
   15516       98923 :         for (i=0;torture_ops[i].name;i++) {
   15517       98443 :                 fstr_sprintf(randomfname, "\\XX%x", 
   15518       98443 :                          (unsigned)random());
   15519             : 
   15520       98443 :                 if (strequal(name, torture_ops[i].name)) {
   15521         520 :                         found = True;
   15522         520 :                         printf("Running %s\n", name);
   15523         520 :                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
   15524          16 :                                 t = create_procs(torture_ops[i].fn, &result);
   15525          16 :                                 if (!result) { 
   15526           2 :                                         ret = False;
   15527           2 :                                         printf("TEST %s FAILED!\n", name);
   15528             :                                 }
   15529             :                         } else {
   15530             :                                 struct timeval start;
   15531         504 :                                 start = timeval_current();
   15532         504 :                                 if (!torture_ops[i].fn(0)) {
   15533          10 :                                         ret = False;
   15534          10 :                                         printf("TEST %s FAILED!\n", name);
   15535             :                                 }
   15536         508 :                                 t = timeval_elapsed(&start);
   15537             :                         }
   15538         476 :                         printf("%s took %g secs\n\n", name, t);
   15539             :                 }
   15540             :         }
   15541             : 
   15542         524 :         if (!found) {
   15543           0 :                 printf("Did not find a test named %s\n", name);
   15544           0 :                 ret = False;
   15545             :         }
   15546             : 
   15547         524 :         return ret;
   15548             : }
   15549             : 
   15550             : 
   15551           0 : static void usage(void)
   15552             : {
   15553             :         int i;
   15554             : 
   15555           0 :         printf("WARNING samba4 test suite is much more complete nowadays.\n");
   15556           0 :         printf("Please use samba4 torture.\n\n");
   15557             : 
   15558           0 :         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
   15559             : 
   15560           0 :         printf("\t-d debuglevel\n");
   15561           0 :         printf("\t-U user%%pass\n");
   15562           0 :         printf("\t-k                    use kerberos\n");
   15563           0 :         printf("\t-N numprocs\n");
   15564           0 :         printf("\t-n my_netbios_name\n");
   15565           0 :         printf("\t-W workgroup\n");
   15566           0 :         printf("\t-o num_operations\n");
   15567           0 :         printf("\t-O socket_options\n");
   15568           0 :         printf("\t-m maximum protocol\n");
   15569           0 :         printf("\t-L use oplocks\n");
   15570           0 :         printf("\t-c CLIENT.TXT         specify client load file for NBENCH\n");
   15571           0 :         printf("\t-A showall\n");
   15572           0 :         printf("\t-p port\n");
   15573           0 :         printf("\t-s seed\n");
   15574           0 :         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
   15575           0 :         printf("\t-f filename           filename to test\n");
   15576           0 :         printf("\t-e                    encrypt\n");
   15577           0 :         printf("\n\n");
   15578             : 
   15579           0 :         printf("tests are:");
   15580           0 :         for (i=0;torture_ops[i].name;i++) {
   15581           0 :                 printf(" %s", torture_ops[i].name);
   15582             :         }
   15583           0 :         printf("\n");
   15584             : 
   15585           0 :         printf("default test is ALL\n");
   15586             : 
   15587           0 :         exit(1);
   15588             : }
   15589             : 
   15590             : /****************************************************************************
   15591             :   main program
   15592             : ****************************************************************************/
   15593         520 :  int main(int argc,char *argv[])
   15594             : {
   15595             :         int opt, i;
   15596             :         char *p;
   15597         520 :         int gotuser = 0;
   15598         520 :         int gotpass = 0;
   15599         520 :         bool correct = True;
   15600         520 :         TALLOC_CTX *frame = talloc_stackframe();
   15601         520 :         int seed = time(NULL);
   15602             : 
   15603             : #ifdef HAVE_SETBUFFER
   15604         520 :         setbuffer(stdout, NULL, 0);
   15605             : #endif
   15606             : 
   15607         520 :         setup_logging("smbtorture", DEBUG_STDOUT);
   15608             : 
   15609         520 :         smb_init_locale();
   15610         520 :         fault_setup();
   15611             : 
   15612         520 :         if (is_default_dyn_CONFIGFILE()) {
   15613         520 :                 if(getenv("SMB_CONF_PATH")) {
   15614         520 :                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
   15615             :                 }
   15616             :         }
   15617         520 :         lp_load_global(get_dyn_CONFIGFILE());
   15618         520 :         load_interfaces();
   15619             : 
   15620         520 :         if (argc < 2) {
   15621           0 :                 usage();
   15622             :         }
   15623             : 
   15624       10373 :         for(p = argv[1]; *p; p++)
   15625        9853 :           if(*p == '\\')
   15626           0 :             *p = '/';
   15627             : 
   15628         520 :         if (strncmp(argv[1], "//", 2)) {
   15629           0 :                 usage();
   15630             :         }
   15631             : 
   15632         520 :         fstrcpy(host, &argv[1][2]);
   15633         520 :         p = strchr_m(&host[2],'/');
   15634         520 :         if (!p) {
   15635           0 :                 usage();
   15636             :         }
   15637         520 :         *p = 0;
   15638         520 :         fstrcpy(share, p+1);
   15639             : 
   15640         520 :         fstrcpy(myname, get_myname(talloc_tos()));
   15641         520 :         if (!*myname) {
   15642           0 :                 fprintf(stderr, "Failed to get my hostname.\n");
   15643           0 :                 return 1;
   15644             :         }
   15645             : 
   15646         520 :         if (*username == 0 && getenv("LOGNAME")) {
   15647           0 :           fstrcpy(username,getenv("LOGNAME"));
   15648             :         }
   15649             : 
   15650         520 :         argc--;
   15651         520 :         argv++;
   15652             : 
   15653         520 :         fstrcpy(workgroup, lp_workgroup());
   15654             : 
   15655        2215 :         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
   15656           9 :                != EOF) {
   15657        1179 :                 switch (opt) {
   15658           0 :                 case 'p':
   15659           0 :                         port_to_use = atoi(optarg);
   15660           0 :                         break;
   15661           0 :                 case 's':
   15662           0 :                         seed = atoi(optarg);
   15663           0 :                         break;
   15664           0 :                 case 'W':
   15665           0 :                         fstrcpy(workgroup,optarg);
   15666           0 :                         break;
   15667           9 :                 case 'm':
   15668           9 :                         lp_set_cmdline("client max protocol", optarg);
   15669           9 :                         break;
   15670           0 :                 case 'N':
   15671           0 :                         torture_nprocs = atoi(optarg);
   15672           0 :                         break;
   15673           0 :                 case 'o':
   15674           0 :                         torture_numops = atoi(optarg);
   15675           0 :                         break;
   15676           0 :                 case 'd':
   15677           0 :                         lp_set_cmdline("log level", optarg);
   15678           0 :                         break;
   15679           0 :                 case 'O':
   15680           0 :                         sockops = optarg;
   15681           0 :                         break;
   15682           0 :                 case 'L':
   15683           0 :                         use_oplocks = True;
   15684           0 :                         break;
   15685         462 :                 case 'l':
   15686         462 :                         local_path = optarg;
   15687         462 :                         break;
   15688           0 :                 case 'A':
   15689           0 :                         torture_showall = True;
   15690           0 :                         break;
   15691           0 :                 case 'n':
   15692           0 :                         fstrcpy(myname, optarg);
   15693           0 :                         break;
   15694           0 :                 case 'c':
   15695           0 :                         client_txt = optarg;
   15696           0 :                         break;
   15697         184 :                 case 'e':
   15698         184 :                         do_encrypt = true;
   15699         184 :                         break;
   15700           0 :                 case 'k':
   15701             : #ifdef HAVE_KRB5
   15702           0 :                         use_kerberos = True;
   15703             : #else
   15704             :                         d_printf("No kerberos support compiled in\n");
   15705             :                         exit(1);
   15706             : #endif
   15707           0 :                         break;
   15708         520 :                 case 'U':
   15709         520 :                         gotuser = 1;
   15710         520 :                         fstrcpy(username,optarg);
   15711         520 :                         p = strchr_m(username,'%');
   15712         520 :                         if (p) {
   15713         520 :                                 *p = 0;
   15714         520 :                                 fstrcpy(password, p+1);
   15715         520 :                                 gotpass = 1;
   15716             :                         }
   15717         476 :                         break;
   15718           0 :                 case 'b':
   15719           0 :                         fstrcpy(multishare_conn_fname, optarg);
   15720           0 :                         use_multishare_conn = True;
   15721           0 :                         break;
   15722           0 :                 case 'B':
   15723           0 :                         torture_blocksize = atoi(optarg);
   15724           0 :                         break;
   15725           4 :                 case 'f':
   15726           4 :                         test_filename = SMB_STRDUP(optarg);
   15727           4 :                         break;
   15728           0 :                 default:
   15729           0 :                         printf("Unknown option %c (%d)\n", (char)opt, opt);
   15730           0 :                         usage();
   15731             :                 }
   15732             :         }
   15733             : 
   15734         520 :         d_printf("using seed %d\n", seed);
   15735             : 
   15736         520 :         srandom(seed);
   15737             : 
   15738         520 :         if(use_kerberos && !gotuser) gotpass = True;
   15739             : 
   15740         992 :         while (!gotpass) {
   15741           0 :                 char pwd[256] = {0};
   15742             :                 int rc;
   15743             : 
   15744           0 :                 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
   15745           0 :                 if (rc == 0) {
   15746           0 :                         fstrcpy(password, pwd);
   15747           0 :                         gotpass = 1;
   15748             :                 }
   15749             :         }
   15750             : 
   15751         520 :         printf("host=%s share=%s user=%s myname=%s\n", 
   15752             :                host, share, username, myname);
   15753             : 
   15754         520 :         torture_creds = cli_session_creds_init(frame,
   15755             :                                                username,
   15756             :                                                workgroup,
   15757             :                                                NULL, /* realm */
   15758             :                                                password,
   15759             :                                                use_kerberos,
   15760             :                                                false, /* fallback_after_kerberos */
   15761             :                                                false, /* use_ccache */
   15762             :                                                false); /* password_is_nt_hash */
   15763         520 :         if (torture_creds == NULL) {
   15764           0 :                 d_printf("cli_session_creds_init() failed.\n");
   15765           0 :                 exit(1);
   15766             :         }
   15767             : 
   15768         520 :         if (argc == optind) {
   15769           0 :                 correct = run_test("ALL");
   15770             :         } else {
   15771        1000 :                 for (i=optind;i<argc;i++) {
   15772         520 :                         if (!run_test(argv[i])) {
   15773          12 :                                 correct = False;
   15774             :                         }
   15775             :                 }
   15776             :         }
   15777             : 
   15778         524 :         TALLOC_FREE(frame);
   15779             : 
   15780         524 :         if (correct) {
   15781         464 :                 return(0);
   15782             :         } else {
   15783          12 :                 return(1);
   15784             :         }
   15785             : }

Generated by: LCOV version 1.13