From 8daa83a594a2e98f39d764422bfbdbc62c9efd44 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 19:20:00 +0200 Subject: Adding upstream version 2:4.20.0+dfsg. Signed-off-by: Daniel Baumann --- source3/torture/locktest2.c | 610 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 610 insertions(+) create mode 100644 source3/torture/locktest2.c (limited to 'source3/torture/locktest2.c') diff --git a/source3/torture/locktest2.c b/source3/torture/locktest2.c new file mode 100644 index 0000000..851d77b --- /dev/null +++ b/source3/torture/locktest2.c @@ -0,0 +1,610 @@ +/* + Unix SMB/CIFS implementation. + byte range lock tester - with local filesystem support + Copyright (C) Andrew Tridgell 1999 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmb/libsmb.h" +#include "system/filesys.h" +#include "locking/share_mode_lock.h" +#include "locking/proto.h" +#include "lib/util/string_wrappers.h" + +static fstring password; +static fstring username; +static int got_pass; +static int numops = 1000; +static bool showall; +static bool analyze; +static bool hide_unlock_fails; +static bool use_oplocks; + +extern char *optarg; +extern int optind; + +#define FILENAME "\\locktest.dat" +#define LOCKRANGE 100 +#define LOCKBASE 0 + +/* +#define LOCKBASE (0x40000000 - 50) +*/ + +#define READ_PCT 50 +#define LOCK_PCT 25 +#define UNLOCK_PCT 65 +#define RANGE_MULTIPLE 1 + +#define NSERVERS 2 +#define NCONNECTIONS 2 +#define NUMFSTYPES 2 +#define NFILES 2 +#define LOCK_TIMEOUT 0 + +#define FSTYPE_SMB 0 +#define FSTYPE_NFS 1 + +struct record { + char r1, r2; + char conn, f, fstype; + unsigned start, len; + char needed; +}; + +static struct record *recorded; + +static int try_open(struct cli_state *c, char *nfs, int fstype, const char *fname, int flags) +{ + char *path; + + switch (fstype) { + case FSTYPE_SMB: + { + uint16_t fd; + if (!NT_STATUS_IS_OK(cli_openx(c, fname, flags, DENY_NONE, &fd))) { + return -1; + } + return fd; + } + + case FSTYPE_NFS: + if (asprintf(&path, "%s%s", nfs, fname) > 0) { + int ret; + string_replace(path,'\\', '/'); + ret = open(path, flags, 0666); + SAFE_FREE(path); + return ret; + } + break; + } + + return -1; +} + +static bool try_close(struct cli_state *c, int fstype, int fd) +{ + switch (fstype) { + case FSTYPE_SMB: + return NT_STATUS_IS_OK(cli_close(c, fd)); + + case FSTYPE_NFS: + return close(fd) == 0; + } + + return False; +} + +static bool try_lock(struct cli_state *c, int fstype, + int fd, unsigned start, unsigned len, + enum brl_type op) +{ + struct flock lock; + + switch (fstype) { + case FSTYPE_SMB: + return NT_STATUS_IS_OK(cli_lock32(c, fd, start, len, + LOCK_TIMEOUT, op)); + + case FSTYPE_NFS: + lock.l_type = (op==READ_LOCK) ? F_RDLCK:F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = start; + lock.l_len = len; + lock.l_pid = getpid(); + return fcntl(fd,F_SETLK,&lock) == 0; + } + + return False; +} + +static bool try_unlock(struct cli_state *c, int fstype, + int fd, unsigned start, unsigned len) +{ + struct flock lock; + + switch (fstype) { + case FSTYPE_SMB: + return NT_STATUS_IS_OK(cli_unlock(c, fd, start, len)); + + case FSTYPE_NFS: + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = start; + lock.l_len = len; + lock.l_pid = getpid(); + return fcntl(fd,F_SETLK,&lock) == 0; + } + + return False; +} + +static void print_brl(struct file_id id, struct server_id pid, + enum brl_type lock_type, + enum brl_flavour lock_flav, + br_off start, br_off size, + void *private_data) +{ + struct file_id_buf idbuf; + + printf("%6d %s %s %.0f:%.0f(%.0f)\n", + (int)procid_to_pid(&pid), + file_id_str_buf(id, &idbuf), + lock_type==READ_LOCK?"R":"W", + (double)start, (double)start+size-1,(double)size); + +} + +/***************************************************** +return a connection to a server +*******************************************************/ +static struct cli_state *connect_one(char *share) +{ + struct cli_state *c; + char *server_n; + fstring server; + fstring myname; + static int count; + NTSTATUS nt_status; + bool use_kerberos = false; + bool fallback_after_kerberos = false; + bool use_ccache = false; + bool pw_nt_hash = false; + struct cli_credentials *creds = NULL; + + fstrcpy(server,share+2); + share = strchr_m(server,'\\'); + if (!share) return NULL; + *share = 0; + share++; + + server_n = server; + + if (!got_pass) { + char pwd[256] = {0}; + int rc; + + rc = samba_getpass("Password: ", pwd, sizeof(pwd), false, false); + if (rc == 0) { + fstrcpy(password, pwd); + } + } + + creds = cli_session_creds_init(NULL, + username, + lp_workgroup(), + NULL, /* realm (use default) */ + password, + use_kerberos, + fallback_after_kerberos, + use_ccache, + pw_nt_hash); + if (creds == NULL) { + DEBUG(0, ("cli_session_creds_init failed\n")); + return NULL; + } + + slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++); + + nt_status = cli_full_connection_creds(&c, + myname, + server_n, + NULL, + 0, + share, + "?????", + creds, + 0); + TALLOC_FREE(creds); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("cli_full_connection failed with error %s\n", nt_errstr(nt_status))); + return NULL; + } + + c->use_oplocks = use_oplocks; + + return c; +} + + +static void reconnect(struct cli_state *cli[NSERVERS][NCONNECTIONS], + char *nfs[NSERVERS], + int fnum[NSERVERS][NUMFSTYPES][NCONNECTIONS][NFILES], + char *share1, char *share2) +{ + int server, conn, f, fstype; + char *share[2]; + share[0] = share1; + share[1] = share2; + + fstype = FSTYPE_SMB; + + for (server=0;serverconn; + unsigned f = rec->f; + unsigned fstype = rec->fstype; + unsigned start = rec->start; + unsigned len = rec->len; + unsigned r1 = rec->r1; + unsigned r2 = rec->r2; + enum brl_type op; + int server; + bool ret[NSERVERS]; + + if (r1 < READ_PCT) { + op = READ_LOCK; + } else { + op = WRITE_LOCK; + } + + if (fstype >= NUMFSTYPES) { + return false; + } + + if (r2 < LOCK_PCT) { + /* set a lock */ + for (server=0;server %u:%u\n", + conn, fstype, f, + start, start+len-1, len, + op==READ_LOCK?"READ_LOCK":"WRITE_LOCK", + ret[0], ret[1]); + } + if (showall) brl_forall(print_brl, NULL); + if (ret[0] != ret[1]) return False; + } else if (r2 < LOCK_PCT+UNLOCK_PCT) { + /* unset a lock */ + for (server=0;server %u:%u\n", + conn, fstype, f, + start, start+len-1, len, + ret[0], ret[1]); + } + if (showall) brl_forall(print_brl, NULL); + if (!hide_unlock_fails && ret[0] != ret[1]) return False; + } else { + /* reopen the file */ + for (server=0;server