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 2 of the License, or
+ 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,
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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "system/filesys.h"
-#include "dynconfig.h"
#include "system/time.h"
+#include "pstring.h"
+#include "auth/credentials/credentials.h"
+#include "auth/gensec/gensec.h"
+#include "libcli/libcli.h"
+#include "param/param.h"
+#include "dynconfig.h"
static int numops = 1000;
static BOOL showall;
#define NFILES 2
#define LOCK_TIMEOUT 0
-#define NASTY_POSIX_LOCK_HACK 0
-
-static struct cli_credentials servers[NSERVERS];
+static struct cli_credentials *servers[NSERVERS];
enum lock_op {OP_LOCK, OP_UNLOCK, OP_REOPEN};
char conn, f;
uint64_t start, len;
char needed;
+ uint16_t pid;
};
#define PRESETS 0
/*****************************************************
return a connection to a server
*******************************************************/
-static struct smbcli_state *connect_one(char *share, int snum)
+static struct smbcli_state *connect_one(char *share, int snum, int conn)
{
struct smbcli_state *c;
fstring server, myname;
NTSTATUS status;
int retries = 10;
+ printf("connect_one(%s, %d, %d)\n", share, snum, conn);
+
fstrcpy(server,share+2);
share = strchr_m(server,'\\');
if (!share) return NULL;
*share = 0;
share++;
+ if (snum == 0) {
+ char **unc_list = NULL;
+ int num_unc_names;
+ const char *p;
+ p = lp_parm_string(global_loadparm, NULL, "torture", "unclist");
+ if (p) {
+ char *h, *s;
+ unc_list = file_lines_load(p, &num_unc_names, NULL);
+ if (!unc_list || num_unc_names <= 0) {
+ printf("Failed to load unc names list from '%s'\n", p);
+ exit(1);
+ }
+
+ if (!smbcli_parse_unc(unc_list[conn % num_unc_names],
+ NULL, &h, &s)) {
+ printf("Failed to parse UNC name %s\n",
+ unc_list[conn % num_unc_names]);
+ exit(1);
+ }
+ fstrcpy(server, h);
+ fstrcpy(share, s);
+ }
+ }
+
+
slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), snum);
+ cli_credentials_set_workstation(servers[snum], myname, CRED_SPECIFIED);
do {
- status = smbcli_full_connection(NULL, &c, myname,
+ printf("\\\\%s\\%s\n", server, share);
+ status = smbcli_full_connection(NULL, &c,
server,
share, NULL,
- &servers[snum]);
+ servers[snum], NULL);
if (!NT_STATUS_IS_OK(status)) {
sleep(2);
}
fnum[server][conn][f] = -1;
}
}
- smbcli_shutdown(cli[server][conn]);
+ talloc_free(cli[server][conn]);
}
- cli[server][conn] = connect_one(share[server], server);
+ cli[server][conn] = connect_one(share[server], server, conn);
if (!cli[server][conn]) {
DEBUG(0,("Failed to connect to %s\n", share[server]));
exit(1);
-static BOOL test_one(struct smbcli_state *cli[NSERVERS][NCONNECTIONS],
+static bool test_one(struct smbcli_state *cli[NSERVERS][NCONNECTIONS],
int fnum[NSERVERS][NCONNECTIONS][NFILES],
struct record *rec)
{
case OP_LOCK:
/* set a lock */
for (server=0;server<NSERVERS;server++) {
- ret[server] = NT_STATUS_IS_OK(smbcli_lock64(cli[server][conn]->tree,
- fnum[server][conn][f],
- start, len, LOCK_TIMEOUT, op));
+ NTSTATUS res;
+ struct smbcli_tree *tree=cli[server][conn]->tree;
+ int fn=fnum[server][conn][f];
+
+ if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
+ res=smbcli_lock(tree, fn, start, len, LOCK_TIMEOUT, rec->lock_op);
+ } else {
+ union smb_lock parms;
+ int ltype;
+ struct smb_lock_entry lock[1];
+
+ parms.lockx.level = RAW_LOCK_LOCKX;
+ parms.lockx.in.file.fnum = fn;
+
+ ltype = (rec->lock_op == READ_LOCK? 1 : 0);
+ ltype |= LOCKING_ANDX_LARGE_FILES;
+ parms.lockx.in.mode = ltype;
+ parms.lockx.in.timeout = LOCK_TIMEOUT;
+ parms.lockx.in.ulock_cnt = 0;
+ parms.lockx.in.lock_cnt = 1;
+ lock[0].pid = rec->pid;
+ lock[0].offset = start;
+ lock[0].count = len;
+ parms.lockx.in.locks = &lock[0];
+
+ res = smb_raw_lock(tree, &parms);
+ }
+
+ ret[server] = NT_STATUS_IS_OK(res);
status[server] = smbcli_nt_error(cli[server][conn]->tree);
if (!exact_error_codes &&
NT_STATUS_EQUAL(status[server],
case OP_UNLOCK:
/* unset a lock */
for (server=0;server<NSERVERS;server++) {
- ret[server] = NT_STATUS_IS_OK(smbcli_unlock64(cli[server][conn]->tree,
- fnum[server][conn][f],
- start, len));
+ NTSTATUS res;
+ struct smbcli_tree *tree=cli[server][conn]->tree;
+ int fn=fnum[server][conn][f];
+
+
+ if (!(tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
+ res=smbcli_unlock(tree, fn, start, len);
+ } else {
+ union smb_lock parms;
+ struct smb_lock_entry lock[1];
+
+ parms.lockx.level = RAW_LOCK_LOCKX;
+ parms.lockx.in.file.fnum = fn;
+ parms.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
+ parms.lockx.in.timeout = 0;
+ parms.lockx.in.ulock_cnt = 1;
+ parms.lockx.in.lock_cnt = 0;
+ lock[0].pid = rec->pid;
+ lock[0].count = len;
+ lock[0].offset = start;
+ parms.lockx.in.locks = &lock[0];
+
+ res = smb_raw_lock(tree, &parms);
+ }
+
+ ret[server] = NT_STATUS_IS_OK(res);
status[server] = smbcli_nt_error(cli[server][conn]->tree);
}
if (showall ||
random() % (lock_range-(recorded[n].start-lock_base));
recorded[n].start *= RANGE_MULTIPLE;
recorded[n].len *= RANGE_MULTIPLE;
+ recorded[n].pid = random()%3;
+ if (recorded[n].pid == 2) {
+ recorded[n].pid = 0xFFFF; /* see if its magic */
+ }
r1 = random() % 100;
r2 = random() % 100;
if (r1 < READ_PCT) {
-R range set lock range\n\
-B base set lock base\n\
-M min set min lock length\n\
+ -l filename unclist file\n\
");
}
{
char *share[NSERVERS];
int opt;
- int seed, server, i;
+ int seed, server;
+ int username_count=0;
setlinebuf(stdout);
argc -= NSERVERS;
argv += NSERVERS;
- lp_load(dyn_CONFIGFILE,True,False,False);
- load_interfaces();
+ lp_load(dyn_CONFIGFILE);
+
+ servers[0] = cli_credentials_init(talloc_autofree_context());
+ servers[1] = cli_credentials_init(talloc_autofree_context());
+ cli_credentials_guess(servers[0]);
+ cli_credentials_guess(servers[1]);
seed = time(NULL);
- while ((opt = getopt(argc, argv, "U:s:ho:aAW:OR:B:M:EZW:")) != EOF) {
+ while ((opt = getopt(argc, argv, "U:s:ho:aAW:OR:B:M:EZW:l:")) != EOF) {
switch (opt) {
case 'U':
- i = servers[0].username?1:0;
- cli_credentials_parse_string(&servers[0], optarg, CRED_SPECIFIED);
-
+ if (username_count == 2) {
+ usage();
+ exit(1);
+ }
+ cli_credentials_parse_string(servers[username_count],
+ optarg, CRED_SPECIFIED);
+ username_count++;
break;
case 'R':
lock_range = strtol(optarg, NULL, 0);
case 'E':
exact_error_codes = True;
break;
+ case 'l':
+ lp_set_cmdline(global_loadparm, "torture:unclist", optarg);
+ break;
case 'W':
- lp_set_cmdline("workgroup", optarg);
+ lp_set_cmdline(global_loadparm, "workgroup", optarg);
break;
case 'h':
usage();
}
}
- if (!servers[0].username) {
+ if (username_count == 0) {
usage();
return -1;
}
- if (!servers[1].username) {
- servers[1].username = servers[0].username;
- servers[1].password = servers[0].password;
+ if (username_count == 1) {
+ servers[1] = servers[0];
}
- locktest_init_subsystems;
+ gensec_init();
argc -= optind;
argv += optind;
return(0);
}
+