Unix SMB/CIFS implementation.
SMB torture tester
Copyright (C) Andrew Tridgell 1997-1998
+ Copyright (C) Jeremy Allison 2009
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
#include "includes.h"
#include "nsswitch/libwbclient/wbc_async.h"
+#include "torture/proto.h"
+#include "libcli/security/dom_sid.h"
+#include "tldap.h"
+#include "tldap_util.h"
extern char *optarg;
extern int optind;
static fstring multishare_conn_fname;
static bool use_multishare_conn = False;
static bool do_encrypt;
+static const char *local_path = NULL;
bool torture_showall = False;
static double create_procs(bool (*fn)(int), bool *result);
-static struct timeval tp1,tp2;
-
-
-void start_timer(void)
-{
- GetTimeOfDay(&tp1);
-}
-
-double end_timer(void)
-{
- GetTimeOfDay(&tp2);
- return((tp2.tv_sec - tp1.tv_sec) +
- (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
-}
-
-
/* return a pointer to a anonymous shared memory segment of size "size"
which will persist across fork() but will disappear when all processes
exit
return false;
}
- if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
+ status = cli_unix_extensions_version(c, &major, &minor, &caplow,
+ &caphigh);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("Encryption required and "
"can't get UNIX CIFS extensions "
- "version from server.\n");
+ "version from server: %s\n", nt_errstr(status));
return false;
}
bool torture_close_connection(struct cli_state *c)
{
bool ret = True;
- if (!cli_tdis(c)) {
- printf("tdis failed (%s)\n", cli_errstr(c));
+ NTSTATUS status;
+
+ status = cli_tdis(c);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("tdis failed (%s)\n", nt_errstr(status));
ret = False;
}
cli->cnum = cnum2;
- if (!cli_tdis(cli)) {
- printf("secondary tdis failed (%s)\n", cli_errstr(cli));
+ status = cli_tdis(cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("secondary tdis failed (%s)\n", nt_errstr(status));
return False;
}
return correct;
}
+/*
+ * This test is designed to be run in conjunction with
+ * external NFS or POSIX locks taken in the filesystem.
+ * It checks that the smbd server will block until the
+ * lock is released and then acquire it. JRA.
+ */
+
+static bool got_alarm;
+static int alarm_fd;
+
+static void alarm_handler(int dummy)
+{
+ got_alarm = True;
+}
+
+static void alarm_handler_parent(int dummy)
+{
+ close(alarm_fd);
+}
+
+static void do_local_lock(int read_fd, int write_fd)
+{
+ int fd;
+ char c = '\0';
+ struct flock lock;
+ const char *local_pathname = NULL;
+ int ret;
+
+ local_pathname = talloc_asprintf(talloc_tos(),
+ "%s/lockt9.lck", local_path);
+ if (!local_pathname) {
+ printf("child: alloc fail\n");
+ exit(1);
+ }
+
+ unlink(local_pathname);
+ fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
+ if (fd == -1) {
+ printf("child: open of %s failed %s.\n",
+ local_pathname, strerror(errno));
+ exit(1);
+ }
+
+ /* Now take a fcntl lock. */
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 4;
+ lock.l_pid = getpid();
+
+ ret = fcntl(fd,F_SETLK,&lock);
+ if (ret == -1) {
+ printf("child: failed to get lock 0:4 on file %s. Error %s\n",
+ local_pathname, strerror(errno));
+ exit(1);
+ } else {
+ printf("child: got lock 0:4 on file %s.\n",
+ local_pathname );
+ fflush(stdout);
+ }
+
+ CatchSignal(SIGALRM, alarm_handler);
+ alarm(5);
+ /* Signal the parent. */
+ if (write(write_fd, &c, 1) != 1) {
+ printf("child: start signal fail %s.\n",
+ strerror(errno));
+ exit(1);
+ }
+ alarm(0);
+
+ alarm(10);
+ /* Wait for the parent to be ready. */
+ if (read(read_fd, &c, 1) != 1) {
+ printf("child: reply signal fail %s.\n",
+ strerror(errno));
+ exit(1);
+ }
+ alarm(0);
+
+ sleep(5);
+ close(fd);
+ printf("child: released lock 0:4 on file %s.\n",
+ local_pathname );
+ fflush(stdout);
+ exit(0);
+}
+
+static bool run_locktest9(int dummy)
+{
+ struct cli_state *cli1;
+ const char *fname = "\\lockt9.lck";
+ uint16_t fnum;
+ bool correct = False;
+ int pipe_in[2], pipe_out[2];
+ pid_t child_pid;
+ char c = '\0';
+ int ret;
+ struct timeval start;
+ double seconds;
+ NTSTATUS status;
+
+ printf("starting locktest9\n");
+
+ if (local_path == NULL) {
+ d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
+ return false;
+ }
+
+ if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
+ return false;
+ }
+
+ child_pid = fork();
+ if (child_pid == -1) {
+ return false;
+ }
+
+ if (child_pid == 0) {
+ /* Child. */
+ do_local_lock(pipe_out[0], pipe_in[1]);
+ exit(0);
+ }
+
+ close(pipe_out[0]);
+ close(pipe_in[1]);
+ pipe_out[0] = -1;
+ pipe_in[1] = -1;
+
+ /* Parent. */
+ ret = read(pipe_in[0], &c, 1);
+ if (ret != 1) {
+ d_fprintf(stderr, "failed to read start signal from child. %s\n",
+ strerror(errno));
+ return false;
+ }
+
+ if (!torture_open_connection(&cli1, 0)) {
+ return false;
+ }
+
+ cli_sockopt(cli1, sockops);
+
+ status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
+ &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
+ return false;
+ }
+
+ /* Ensure the child has the lock. */
+ if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
+ d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
+ goto fail;
+ } else {
+ d_printf("Child has the lock.\n");
+ }
+
+ /* Tell the child to wait 5 seconds then exit. */
+ ret = write(pipe_out[1], &c, 1);
+ if (ret != 1) {
+ d_fprintf(stderr, "failed to send exit signal to child. %s\n",
+ strerror(errno));
+ goto fail;
+ }
+
+ /* Wait 20 seconds for the lock. */
+ alarm_fd = cli1->fd;
+ CatchSignal(SIGALRM, alarm_handler_parent);
+ alarm(20);
+
+ start = timeval_current();
+
+ if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
+ d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
+ "%s\n", cli_errstr(cli1));
+ goto fail_nofd;
+ }
+ alarm(0);
+
+ seconds = timeval_elapsed(&start);
+
+ printf("Parent got the lock after %.2f seconds.\n",
+ seconds);
+
+ status = cli_close(cli1, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
+ goto fail;
+ }
+
+ correct = true;
+
+fail:
+ cli_close(cli1, fnum);
+ torture_close_connection(cli1);
+
+fail_nofd:
+
+ printf("finished locktest9\n");
+ return correct;
+}
+
/*
test whether fnums and tids open on one VC are available on another (a major
security hole)
const char *fname2 = "\\trans2\\trans2.tst";
char pname[1024];
bool correct = True;
+ NTSTATUS status;
+ uint32_t fs_attr;
printf("starting trans2 test\n");
return False;
}
+ status = cli_get_fs_attr_info(cli, &fs_attr);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ERROR: cli_get_fs_attr_info returned %s\n",
+ nt_errstr(status));
+ correct = false;
+ }
+
cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
cli_open(cli, fname,
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
}
cli_close(cli, fnum);
- if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
- printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
+ status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
+ NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
correct = False;
} else {
if (c_time != m_time) {
cli_open(cli, fname,
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
cli_close(cli, fnum);
- if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
- &m_time_ts, &size, NULL, NULL)) {
- printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
+ status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
+ &m_time_ts, &size, NULL, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
correct = False;
} else {
if (w_time_ts.tv_sec < 60*60*24*2) {
correct = False;
}
sleep(3);
- if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
- &m_time_ts, &size, NULL, NULL)) {
- printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
+ status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
+ &w_time_ts, &m_time_ts, &size, NULL, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
correct = False;
}
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
cli_close(cli, fnum);
- if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
- &m_time2_ts, &size, NULL, NULL)) {
- printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
+ status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
+ &w_time_ts, &m_time2_ts, &size, NULL, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
correct = False;
} else {
if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
const char *fname1 = "\\test1.txt";
bool correct = True;
uint16_t fnum1;
+ uint16_t attr;
NTSTATUS status;
printf("starting rename test\n");
} */
/*--*/
-
-
if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
printf("close - 5 failed (%s)\n", cli_errstr(cli1));
return False;
}
+ /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
+ if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
+ printf("getatr on file %s failed - %s ! \n",
+ fname1,
+ cli_errstr(cli1));
+ correct = False;
+ } else {
+ if (attr != FILE_ATTRIBUTE_ARCHIVE) {
+ printf("Renamed file %s has wrong attr 0x%x "
+ "(should be 0x%x)\n",
+ fname1,
+ attr,
+ (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
+ correct = False;
+ } else {
+ printf("Renamed file %s has archive bit set\n", fname1);
+ }
+ }
+
cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
return correct;
}
+NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
+{
+ uint16 major, minor;
+ uint32 caplow, caphigh;
+ NTSTATUS status;
+
+ if (!SERVER_HAS_UNIX_CIFS(cli)) {
+ printf("Server doesn't support UNIX CIFS extensions.\n");
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
+ &caphigh);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Server didn't return UNIX CIFS extensions: %s\n",
+ nt_errstr(status));
+ return status;
+ }
+
+ status = cli_set_unix_extensions_capabilities(cli, major, minor,
+ caplow, caphigh);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Server doesn't support setting UNIX CIFS extensions: "
+ "%s.\n", nt_errstr(status));
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
/*
Test POSIX open /mkdir calls.
*/
const char *dname = "posix:dir";
char buf[10];
char namebuf[11];
- uint16 major, minor;
- uint32 caplow, caphigh;
uint16_t fnum1 = (uint16_t)-1;
SMB_STRUCT_STAT sbuf;
bool correct = false;
+ NTSTATUS status;
printf("Starting simple POSIX open test\n");
cli_sockopt(cli1, sockops);
- if (!SERVER_HAS_UNIX_CIFS(cli1)) {
- printf("Server doesn't support UNIX CIFS extensions.\n");
- return false;
- }
-
- if (!cli_unix_extensions_version(cli1, &major,
- &minor, &caplow, &caphigh)) {
- printf("Server didn't return UNIX CIFS extensions.\n");
+ status = torture_setup_unix_extensions(cli1);
+ if (!NT_STATUS_IS_OK(status)) {
return false;
}
- if (!cli_set_unix_extensions_capabilities(cli1,
- major, minor, caplow, caphigh)) {
- printf("Server doesn't support setting UNIX CIFS extensions.\n");
- return false;
- }
-
cli_setatr(cli1, fname, 0, 0);
cli_posix_unlink(cli1, fname);
cli_setatr(cli1, dname, 0, 0);
return correct;
}
-static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
+static void list_fn(const char *mnt, struct file_info *finfo,
+ const char *name, void *state)
{
}
int i;
static struct cli_state *cli;
uint16_t fnum;
- double t1;
+ struct timeval core_start;
bool correct = True;
printf("starting directory test\n");
cli_close(cli, fnum);
}
- t1 = end_timer();
+ core_start = timeval_current();
printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
- printf("dirtest core %g seconds\n", end_timer() - t1);
+ printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
srandom(0);
for (i=0;i<torture_numops;i++) {
return correct;
}
-static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
+static void del_fn(const char *mnt, struct file_info *finfo, const char *mask,
+ void *state)
{
struct cli_state *pcli = (struct cli_state *)state;
fstring fname;
}
status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
- printf("ioctl device info: %s\n", cli_errstr(cli));
+ printf("ioctl device info: %s\n", nt_errstr(status));
status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
- printf("ioctl job info: %s\n", cli_errstr(cli));
+ printf("ioctl job info: %s\n", nt_errstr(status));
for (device=0;device<0x100;device++) {
printf("testing device=0x%x\n", device);
size_t num_eas;
struct ea_struct *ea_list = NULL;
TALLOC_CTX *mem_ctx = talloc_init("eatest");
+ NTSTATUS status;
printf("starting eatest\n");
}
}
- if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
- printf("ea_get list failed - %s\n", cli_errstr(cli));
+ status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ea_get list failed - %s\n", nt_errstr(status));
correct = False;
}
}
#endif
- if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
- printf("ea_get list failed - %s\n", cli_errstr(cli));
+ status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ea_get list failed - %s\n", nt_errstr(status));
correct = False;
}
d_printf("\r%d ", (int)c->vuid);
- if (!cli_ulogoff(c)) {
+ status = cli_ulogoff(c);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("(%s) cli_ulogoff failed: %s\n",
- __location__, cli_errstr(c));
+ __location__, nt_errstr(status));
return false;
}
c->vuid = 0;
struct tevent_context *ev;
NTSTATUS status;
uint16_t dnum;
- struct tevent_req *req1, *req2;
+ struct tevent_req *req1;
+ struct tevent_req *req2 = NULL;
int i, num_unc_names;
int num_finished = 0;
}
cli_close(cli, fnum);
- if (!cli_qpathinfo(cli, alt_name, &change_time, &access_time,
- &write_time, &size, &mode)) {
- d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
- cli_errstr(cli));
+ status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
+ &write_time, &size, &mode);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
+ nt_errstr(status));
return false;
}
int i;
bool ret = false;
const char *fname = "\\writetest.txt";
+ struct timeval start_time;
double seconds;
double kbytes;
cli_sockopt(cli1, sockops);
- start_timer();
+ start_time = timeval_current();
for (i=0; i<torture_numops; i++) {
char c = 0;
}
}
- seconds = end_timer();
+ seconds = timeval_elapsed(&start_time);
kbytes = (double)torture_blocksize * torture_numops;
kbytes /= 1024;
int16_t old_vuid;
int16_t old_cnum;
bool correct = True;
+ NTSTATUS status;
printf("starting uid regression test\n");
/* Ok - now save then logoff our current user. */
old_vuid = cli->vuid;
- if (!cli_ulogoff(cli)) {
+ status = cli_ulogoff(cli);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf("(%s) cli_ulogoff failed: %s\n",
- __location__, cli_errstr(cli));
+ __location__, nt_errstr(status));
correct = false;
goto out;
}
cli->vuid = 0;
/* This should succeed. */
- if (cli_tdis(cli)) {
+ status = cli_tdis(cli);
+
+ if (NT_STATUS_IS_OK(status)) {
printf("First tdis with invalid vuid should succeed.\n");
} else {
- printf("First tdis failed (%s)\n", cli_errstr(cli));
+ printf("First tdis failed (%s)\n", nt_errstr(status));
}
cli->vuid = old_vuid;
cli->cnum = old_cnum;
/* This should fail. */
- if (cli_tdis(cli)) {
+ status = cli_tdis(cli);
+ if (NT_STATUS_IS_OK(status)) {
printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
} else {
/* Should be bad tid. */
static const char *illegal_chars = "*\\/?<>|\":";
static char force_shortname_chars[] = " +,.[];=\177";
-static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
+static void shortname_del_fn(const char *mnt, struct file_info *finfo,
+ const char *mask, void *state)
{
struct cli_state *pcli = (struct cli_state *)state;
fstring fname;
bool val;
};
-static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
+static void shortname_list_fn(const char *mnt, struct file_info *finfo,
+ const char *name, void *state)
{
struct sn_state *s = (struct sn_state *)state;
int i = s->i;
struct tevent_context *ev;
struct tevent_req *req;
char *basedn;
+ const char *filter;
if (!resolve_name(host, &addr, 0, false)) {
d_printf("could not find host %s\n", host);
TALLOC_FREE(req);
+ /* test search filters against rootDSE */
+ filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
+ "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
+
+ rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
+ NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
+ talloc_tos(), NULL, NULL);
+ if (rc != TLDAP_SUCCESS) {
+ d_printf("tldap_search with complex filter failed: %s\n",
+ tldap_errstr(talloc_tos(), ld, rc));
+ return false;
+ }
+
TALLOC_FREE(ld);
return true;
}
+/* Torture test to ensure no regression of :
+https://bugzilla.samba.org/show_bug.cgi?id=7084
+*/
+
+static bool run_dir_createtime(int dummy)
+{
+ struct cli_state *cli;
+ const char *dname = "\\testdir";
+ const char *fname = "\\testdir\\testfile";
+ NTSTATUS status;
+ struct timespec create_time;
+ struct timespec create_time1;
+ uint16_t fnum;
+ bool ret = false;
+
+ if (!torture_open_connection(&cli, 0)) {
+ return false;
+ }
+
+ cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
+ cli_rmdir(cli, dname);
+
+ status = cli_mkdir(cli, dname);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("mkdir failed: %s\n", nt_errstr(status));
+ goto out;
+ }
+
+ status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_qpathinfo2 returned %s\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Sleep 3 seconds, then create a file. */
+ sleep(3);
+
+ status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
+ DENY_NONE, &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_open failed: %s\n", nt_errstr(status));
+ goto out;
+ }
+
+ status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_qpathinfo2 (2) returned %s\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ if (timespec_compare(&create_time1, &create_time)) {
+ printf("run_dir_createtime: create time was updated (error)\n");
+ } else {
+ printf("run_dir_createtime: create time was not updated (correct)\n");
+ ret = true;
+ }
+
+ out:
+
+ cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
+ cli_rmdir(cli, dname);
+ if (!torture_close_connection(cli)) {
+ ret = false;
+ }
+ return ret;
+}
+
+
static bool run_streamerror(int dummy)
{
struct cli_state *cli;
return false;
}
+ cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
cli_rmdir(cli, dname);
status = cli_mkdir(cli, dname);
return false;
}
- cli_qpathinfo(cli, streamname, &change_time, &access_time, &write_time,
+ cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
&size, &mode);
status = cli_nt_error(cli);
return False;
}
+ if (!gencache_get("foo", NULL, NULL)) {
+ d_printf("%s: gencache_get() failed\n", __location__);
+ return False;
+ }
+
if (!gencache_get("foo", &val, &tm)) {
d_printf("%s: gencache_get() failed\n", __location__);
return False;
return true;
}
+static bool run_local_string_to_sid(int dummy) {
+ struct dom_sid sid;
+
+ if (string_to_sid(&sid, "S--1-5-32-545")) {
+ printf("allowing S--1-5-32-545\n");
+ return false;
+ }
+ if (string_to_sid(&sid, "S-1-5-32-+545")) {
+ printf("allowing S-1-5-32-+545\n");
+ return false;
+ }
+ 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")) {
+ printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
+ return false;
+ }
+ if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
+ printf("allowing S-1-5-32-545-abc\n");
+ return false;
+ }
+ if (!string_to_sid(&sid, "S-1-5-32-545")) {
+ printf("could not parse S-1-5-32-545\n");
+ return false;
+ }
+ if (!sid_equal(&sid, &global_sid_Builtin_Users)) {
+ printf("mis-parsed S-1-5-32-545 as %s\n",
+ sid_string_tos(&sid));
+ return false;
+ }
+ return true;
+}
+
/* Split a path name into filename and stream name components. Canonicalise
* such that an implicit $DATA token is always explicit.
*
return result;
}
+static bool dbtrans_inc(struct db_context *db)
+{
+ struct db_record *rec;
+ uint32_t *val;
+ bool ret = false;
+ NTSTATUS status;
+
+ rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
+ if (rec == NULL) {
+ printf(__location__ "fetch_lock failed\n");
+ return false;
+ }
+
+ if (rec->value.dsize != sizeof(uint32_t)) {
+ printf(__location__ "value.dsize = %d\n",
+ (int)rec->value.dsize);
+ goto fail;
+ }
+
+ val = (uint32_t *)rec->value.dptr;
+ *val += 1;
+
+ status = rec->store(rec, make_tdb_data((uint8_t *)val,
+ sizeof(uint32_t)),
+ 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf(__location__ "store failed: %s\n",
+ nt_errstr(status));
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ TALLOC_FREE(rec);
+ return ret;
+}
+
+static bool run_local_dbtrans(int dummy)
+{
+ struct db_context *db;
+ struct db_record *rec;
+ NTSTATUS status;
+ uint32_t initial;
+ int res;
+
+ db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
+ O_RDWR|O_CREAT, 0600);
+ if (db == NULL) {
+ printf("Could not open transtest.db\n");
+ return false;
+ }
+
+ res = db->transaction_start(db);
+ if (res == -1) {
+ printf(__location__ "transaction_start failed\n");
+ return false;
+ }
+
+ rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
+ if (rec == NULL) {
+ printf(__location__ "fetch_lock failed\n");
+ return false;
+ }
+
+ if (rec->value.dptr == NULL) {
+ initial = 0;
+ status = rec->store(
+ rec, make_tdb_data((uint8_t *)&initial,
+ sizeof(initial)),
+ 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf(__location__ "store returned %s\n",
+ nt_errstr(status));
+ return false;
+ }
+ }
+
+ TALLOC_FREE(rec);
+
+ res = db->transaction_commit(db);
+ if (res == -1) {
+ printf(__location__ "transaction_commit failed\n");
+ return false;
+ }
+
+ while (true) {
+ uint32_t val, val2;
+ int i;
+
+ res = db->transaction_start(db);
+ if (res == -1) {
+ printf(__location__ "transaction_start failed\n");
+ break;
+ }
+
+ if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
+ printf(__location__ "dbwrap_fetch_uint32 failed\n");
+ break;
+ }
+
+ for (i=0; i<10; i++) {
+ if (!dbtrans_inc(db)) {
+ return false;
+ }
+ }
+
+ if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
+ printf(__location__ "dbwrap_fetch_uint32 failed\n");
+ break;
+ }
+
+ if (val2 != val + 10) {
+ printf(__location__ "val=%d, val2=%d\n",
+ (int)val, (int)val2);
+ break;
+ }
+
+ printf("val2=%d\r", val2);
+
+ res = db->transaction_commit(db);
+ if (res == -1) {
+ printf(__location__ "transaction_commit failed\n");
+ break;
+ }
+ }
+
+ TALLOC_FREE(db);
+ return true;
+}
+
+/*
+ * Just a dummy test to be run under a debugger. There's no real way
+ * to inspect the tevent_select specific function from outside of
+ * tevent_select.c.
+ */
+
+static bool run_local_tevent_select(int dummy)
+{
+ struct tevent_context *ev;
+ struct tevent_fd *fd1, *fd2;
+ bool result = false;
+
+ ev = tevent_context_init_byname(NULL, "select");
+ if (ev == NULL) {
+ d_fprintf(stderr, "tevent_context_init_byname failed\n");
+ goto fail;
+ }
+
+ fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
+ if (fd1 == NULL) {
+ d_fprintf(stderr, "tevent_add_fd failed\n");
+ goto fail;
+ }
+ fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
+ if (fd2 == NULL) {
+ d_fprintf(stderr, "tevent_add_fd failed\n");
+ goto fail;
+ }
+ TALLOC_FREE(fd2);
+
+ fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
+ if (fd2 == NULL) {
+ d_fprintf(stderr, "tevent_add_fd failed\n");
+ goto fail;
+ }
+
+ result = true;
+fail:
+ TALLOC_FREE(ev);
+ return result;
+}
static double create_procs(bool (*fn)(int), bool *result)
{
volatile bool *child_status_out;
int synccount;
int tries = 8;
+ struct timeval start;
synccount = 0;
child_status_out[i] = True;
}
- start_timer();
+ start = timeval_current();
for (i=0;i<nprocs;i++) {
procnum = i;
child_status[i] = getpid();
- while (child_status[i] && end_timer() < 5) smb_msleep(2);
+ while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
child_status_out[i] = fn(i);
_exit(0);
}
if (synccount == nprocs) break;
smb_msleep(10);
- } while (end_timer() < 30);
+ } while (timeval_elapsed(&start) < 30);
if (synccount != nprocs) {
printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
*result = False;
- return end_timer();
+ return timeval_elapsed(&start);
}
/* start the client load */
- start_timer();
+ start = timeval_current();
for (i=0;i<nprocs;i++) {
child_status[i] = 0;
*result = False;
}
}
- return end_timer();
+ return timeval_elapsed(&start);
}
#define FLAG_MULTIPROC 1
{"LOCK6", run_locktest6, 0},
{"LOCK7", run_locktest7, 0},
{"LOCK8", run_locktest8, 0},
+ {"LOCK9", run_locktest9, 0},
{"UNLINK", run_unlinktest, 0},
{"BROWSE", run_browsetest, 0},
{"ATTR", run_attrtest, 0},
{"RANDOMIPC", run_randomipc, 0},
{"NEGNOWAIT", run_negprot_nowait, 0},
{"NBENCH", run_nbench, 0},
+ {"NBENCH2", run_nbench2, 0},
{"OPLOCK1", run_oplock1, 0},
{"OPLOCK2", run_oplock2, 0},
{"OPLOCK3", run_oplock3, 0},
{"DIR", run_dirtest, 0},
{"DIR1", run_dirtest1, 0},
+ {"DIR-CREATETIME", run_dir_createtime, 0},
{"DENY1", torture_denytest1, 0},
{"DENY2", torture_denytest2, 0},
{"TCON", run_tcon_test, 0},
{"RW3", run_readwritelarge, 0},
{"OPEN", run_opentest, 0},
{"POSIX", run_simple_posix_open_test, 0},
+ {"POSIX-APPEND", run_posix_append, 0},
{ "UID-REGRESSION-TEST", run_uid_regression_test, 0},
{ "SHORTNAME-TEST", run_shortname_test, 0},
#if 1
{ "LOCAL-MEMCACHE", run_local_memcache, 0},
{ "LOCAL-STREAM-NAME", run_local_stream_name, 0},
{ "LOCAL-WBCLIENT", run_local_wbclient, 0},
+ { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
+ { "LOCAL-DBTRANS", run_local_dbtrans, 0},
+ { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
{NULL, NULL, 0}};
printf("TEST %s FAILED!\n", name);
}
} else {
- start_timer();
+ struct timeval start;
+ start = timeval_current();
if (!torture_ops[i].fn(0)) {
ret = False;
printf("TEST %s FAILED!\n", name);
}
- t = end_timer();
+ t = timeval_elapsed(&start);
}
printf("%s took %g secs\n\n", name, t);
}
load_case_tables();
+ setup_logging("smbtorture", true);
+
if (is_default_dyn_CONFIGFILE()) {
if(getenv("SMB_CONF_PATH")) {
set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
fstrcpy(workgroup, lp_workgroup());
- while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
+ while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
switch (opt) {
case 'p':
port_to_use = atoi(optarg);
case 'L':
use_oplocks = True;
break;
+ case 'l':
+ local_path = optarg;
+ break;
case 'A':
torture_showall = True;
break;