*/
#include "includes.h"
-#include "wbc_async.h"
+#include "nsswitch/libwbclient/wbc_async.h"
extern char *optarg;
extern int optind;
correct = False;
}
- if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
+ if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
printf("unlock failed (%s)\n", cli_errstr(c));
correct = False;
}
static bool run_readwritetest(int dummy)
{
- static struct cli_state *cli1, *cli2;
+ struct cli_state *cli1, *cli2;
bool test1, test2 = False;
if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
printf("lock at 100 failed (%s)\n", cli_errstr(cli));
}
cli_setpid(cli, 2);
- if (cli_unlock(cli, fnum1, 100, 4)) {
+ if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
printf("unlock at 100 succeeded! This is a locking bug\n");
correct = False;
}
- if (cli_unlock(cli, fnum1, 0, 4)) {
+ if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
printf("unlock1 succeeded! This is a locking bug\n");
correct = False;
} else {
NT_STATUS_RANGE_NOT_LOCKED)) return False;
}
- if (cli_unlock(cli, fnum1, 0, 8)) {
+ if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
printf("unlock2 succeeded! This is a locking bug\n");
correct = False;
} else {
for (offset=i=0;i<torture_numops;i++) {
NEXT_OFFSET;
- if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
+ if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
printf("unlock1 %d failed (%s)\n",
i,
cli_errstr(cli1));
return False;
}
- if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
+ if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
printf("unlock2 %d failed (%s)\n",
i,
cli_errstr(cli1));
ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 110, 6);
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
EXPECTED(ret, False);
printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 140, 4) &&
- cli_unlock(cli1, fnum1, 140, 4);
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
EXPECTED(ret, True);
printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 150, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
(cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
!(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
- cli_unlock(cli1, fnum1, 150, 4);
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
EXPECTED(ret, True);
printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 160, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
(cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
(cli_read(cli2, fnum2, buf, 160, 4) == 4);
EXPECTED(ret, True);
printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
- cli_unlock(cli1, fnum1, 170, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
(cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
(cli_read(cli2, fnum2, buf, 170, 4) == 4);
EXPECTED(ret, True);
ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 190, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
!(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
(cli_read(cli2, fnum2, buf, 190, 4) == 4);
EXPECTED(ret, True);
/* Unlock the first process lock, then check this was the WRITE lock that was
removed. */
- ret = cli_unlock(cli1, fnum1, 0, 4) &&
+ ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
EXPECTED(ret, True);
/* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
- ret = cli_unlock(cli1, fnum1, 1, 1) &&
- cli_unlock(cli1, fnum1, 0, 4) &&
- cli_unlock(cli1, fnum1, 0, 4);
+ ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
EXPECTED(ret, True);
printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
/* Ensure the next unlock fails. */
- ret = cli_unlock(cli1, fnum1, 0, 4);
+ ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
EXPECTED(ret, False);
printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
return correct;
}
+/*
+ * This demonstrates a problem with our use of GPFS share modes: A file
+ * descriptor sitting in the pending close queue holding a GPFS share mode
+ * blocks opening a file another time. Happens with Word 2007 temp files.
+ * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
+ * open is denied with NT_STATUS_SHARING_VIOLATION.
+ */
+
+static bool run_locktest8(int dummy)
+{
+ struct cli_state *cli1;
+ const char *fname = "\\lockt8.lck";
+ uint16_t fnum1, fnum2;
+ char buf[200];
+ bool correct = False;
+ NTSTATUS status;
+
+ if (!torture_open_connection(&cli1, 0)) {
+ return False;
+ }
+
+ cli_sockopt(cli1, sockops);
+
+ printf("starting locktest8\n");
+
+ cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
+
+ status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
+ &fnum1);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
+ return false;
+ }
+
+ memset(buf, 0, sizeof(buf));
+
+ status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "cli_open second time returned %s\n",
+ cli_errstr(cli1));
+ goto fail;
+ }
+
+ if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
+ printf("Unable to apply read lock on range 1:1, error was "
+ "%s\n", cli_errstr(cli1));
+ goto fail;
+ }
+
+ status = cli_close(cli1, fnum1);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
+ goto fail;
+ }
+
+ status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "cli_open third time returned %s\n",
+ cli_errstr(cli1));
+ goto fail;
+ }
+
+ correct = true;
+
+fail:
+ cli_close(cli1, fnum1);
+ cli_close(cli1, fnum2);
+ cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
+ torture_close_connection(cli1);
+
+ printf("finished locktest8\n");
+ return correct;
+}
+
/*
test whether fnums and tids open on one VC are available on another (a major
security hole)
cli_open(cli, fname,
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
cli_close(cli, fnum);
- if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
+ if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
printf("getatr failed (%s)\n", cli_errstr(cli));
correct = False;
}
t2 = t-60*60*24; /* 1 day ago */
- if (!cli_setatr(cli, fname, 0, t2)) {
+ if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
printf("setatr failed (%s)\n", cli_errstr(cli));
correct = True;
}
- if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
+ if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
printf("getatr failed (%s)\n", cli_errstr(cli));
correct = True;
}
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
correct = False;
goto fail;
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
correct = False;
goto fail;
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
correct = False;
goto fail;
/* This should fail - only allowed on NT opens with DELETE access. */
- if (cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
correct = False;
goto fail;
/* This should fail - only allowed on NT opens with DELETE access. */
- if (cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
correct = False;
goto fail;
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[7] setting delete_on_close on file failed !\n");
correct = False;
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
printf("[7] unsetting delete_on_close on file failed !\n");
correct = False;
goto fail;
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[8] setting delete_on_close on file failed !\n");
correct = False;
goto fail;
printf("Fourth open failed - %s\n", cli_errstr(cli1));
return False;
}
- if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
printf("[8] setting delete_on_close on file failed !\n");
return False;
}
return False;
}
- if (!cli_setatr(cli1, fname, aRONLY, 0)) {
+ if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
return False;
}
}
/* Ensure size == 20. */
- if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
+ if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
return False;
}
}
/* Ensure size == 0. */
- if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
+ if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
return False;
}
printf("testing ctemp\n");
- fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
- if (fnum1 == (uint16_t)-1) {
+ if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
printf("ctemp failed (%s)\n", cli_errstr(cli1));
return False;
}
static bool run_simple_posix_open_test(int dummy)
{
static struct cli_state *cli1;
- const char *fname = "\\posix:file";
- const char *dname = "\\posix:dir";
+ const char *fname = "posix:file";
+ const char *hname = "posix:hlink";
+ const char *sname = "posix:symlink";
+ const char *dname = "posix:dir";
+ char buf[10];
+ char namebuf[11];
uint16 major, minor;
uint32 caplow, caphigh;
- int fnum1 = -1;
+ uint16_t fnum1 = (uint16_t)-1;
+ SMB_STRUCT_STAT sbuf;
bool correct = false;
printf("Starting simple POSIX open test\n");
cli_posix_unlink(cli1, fname);
cli_setatr(cli1, dname, 0, 0);
cli_posix_rmdir(cli1, dname);
+ cli_setatr(cli1, hname, 0, 0);
+ cli_posix_unlink(cli1, hname);
+ cli_setatr(cli1, sname, 0, 0);
+ cli_posix_unlink(cli1, sname);
/* Create a directory. */
- if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
+ if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
goto out;
}
- fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
- if (fnum1 == -1) {
+ if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
goto out;
}
+ /* Test ftruncate - set file size. */
+ if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
+ printf("ftruncate failed (%s)\n", cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Ensure st_size == 1000 */
+ if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
+ printf("stat failed (%s)\n", cli_errstr(cli1));
+ goto out;
+ }
+
+ if (sbuf.st_ex_size != 1000) {
+ printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
+ goto out;
+ }
+
+ /* Test ftruncate - set file size back to zero. */
+ if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
+ printf("ftruncate failed (%s)\n", cli_errstr(cli1));
+ goto out;
+ }
+
if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
printf("close failed (%s)\n", cli_errstr(cli1));
goto out;
}
/* Now open the file again for read only. */
- fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
- if (fnum1 == -1) {
+ if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
goto out;
}
}
/* Ensure the file has gone. */
- fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
- if (fnum1 != -1) {
+ if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
goto out;
}
+ /* What happens when we try and POSIX open a directory ? */
+ if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
+ printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
+ goto out;
+ } else {
+ if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
+ NT_STATUS_FILE_IS_A_DIRECTORY)) {
+ goto out;
+ }
+ }
+
+ /* Create the file. */
+ if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
+ printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Write some data into it. */
+ if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
+ printf("cli_write failed: %s\n", cli_errstr(cli1));
+ goto out;
+ }
+
+ cli_close(cli1, fnum1);
+
+ /* Now create a hardlink. */
+ if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
+ printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Now create a symlink. */
+ if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
+ printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Open the hardlink for read. */
+ if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
+ printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
+ goto out;
+ }
+
+ if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
+ printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
+ goto out;
+ }
+
+ if (memcmp(buf, "TEST DATA\n", 10)) {
+ printf("invalid data read from hardlink\n");
+ goto out;
+ }
+
+ /* Do a POSIX lock/unlock. */
+ if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
+ printf("POSIX lock failed %s\n", cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Punch a hole in the locked area. */
+ if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
+ printf("POSIX unlock failed %s\n", cli_errstr(cli1));
+ goto out;
+ }
+
+ cli_close(cli1, fnum1);
+
+ /* Open the symlink for read - this should fail. A POSIX
+ client should not be doing opens on a symlink. */
+ if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
+ printf("POSIX open of %s succeeded (should have failed)\n", sname);
+ goto out;
+ } else {
+ if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
+ NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
+ printf("POSIX open of %s should have failed "
+ "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
+ "failed with %s instead.\n",
+ sname, cli_errstr(cli1));
+ goto out;
+ }
+ }
+
+ if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
+ printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
+ goto out;
+ }
+
+ if (strcmp(namebuf, fname) != 0) {
+ printf("POSIX readlink on %s failed to match name %s (read %s)\n",
+ sname, fname, namebuf);
+ goto out;
+ }
+
if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
goto out;
out:
- if (fnum1 != -1) {
+ if (fnum1 != (uint16_t)-1) {
cli_close(cli1, fnum1);
- fnum1 = -1;
+ fnum1 = (uint16_t)-1;
}
+ cli_setatr(cli1, sname, 0, 0);
+ cli_posix_unlink(cli1, sname);
+ cli_setatr(cli1, hname, 0, 0);
+ cli_posix_unlink(cli1, hname);
cli_setatr(cli1, fname, 0, 0);
cli_posix_unlink(cli1, fname);
cli_setatr(cli1, dname, 0, 0);
return False;
}
- if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
+ if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
return False;
}
struct tevent_req *reqs[3], *smbreqs[3];
bool done = false;
const char *str = "foobar";
+ NTSTATUS status;
printf("starting chain1 test\n");
if (!torture_open_connection(&cli1, 0)) {
if (reqs[2] == NULL) return false;
tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
- if (!cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs))) {
+ status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ while (!done) {
+ event_loop_once(evt);
+ }
+
+ torture_close_connection(cli1);
+ return True;
+}
+
+static void chain2_sesssetup_completion(struct tevent_req *req)
+{
+ NTSTATUS status;
+ status = cli_session_setup_guest_recv(req);
+ d_printf("sesssetup returned %s\n", nt_errstr(status));
+}
+
+static void chain2_tcon_completion(struct tevent_req *req)
+{
+ bool *done = (bool *)tevent_req_callback_data_void(req);
+ NTSTATUS status;
+ status = cli_tcon_andx_recv(req);
+ d_printf("tcon_and_x returned %s\n", nt_errstr(status));
+ *done = true;
+}
+
+static bool run_chain2(int dummy)
+{
+ struct cli_state *cli1;
+ struct event_context *evt = event_context_init(NULL);
+ struct tevent_req *reqs[2], *smbreqs[2];
+ bool done = false;
+ NTSTATUS status;
+
+ printf("starting chain2 test\n");
+ status = cli_start_connection(&cli1, global_myname(), host, NULL,
+ port_to_use, Undefined, 0, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
+
+ cli_sockopt(cli1, sockops);
+
+ reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
+ &smbreqs[0]);
+ if (reqs[0] == NULL) return false;
+ tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
+
+ reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
+ "?????", NULL, 0, &smbreqs[1]);
+ if (reqs[1] == NULL) return false;
+ tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
+
+ status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
+ if (!NT_STATUS_IS_OK(status)) {
return false;
}
SMB_OFF_T size;
uint16_t mode;
- printf("starting chain1 test\n");
+ printf("starting mangle1 test\n");
if (!torture_open_connection(&cli, 0)) {
return False;
}
cli_sockopt(cli, sockops);
- if (NT_STATUS_IS_OK(cli_ntcreate(
+ if (!NT_STATUS_IS_OK(cli_ntcreate(
cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
return correct;
}
+
+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)
+{
+ struct cli_state *pcli = (struct cli_state *)state;
+ fstring fname;
+ slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
+
+ if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
+ return;
+
+ if (finfo->mode & aDIR) {
+ if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
+ printf("del_fn: failed to rmdir %s\n,", fname );
+ } else {
+ if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
+ printf("del_fn: failed to unlink %s\n,", fname );
+ }
+}
+
+struct sn_state {
+ int i;
+ bool val;
+};
+
+static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
+{
+ struct sn_state *s = (struct sn_state *)state;
+ int i = s->i;
+
+#if 0
+ printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
+ i, finfo->name, finfo->short_name);
+#endif
+
+ if (strchr(force_shortname_chars, i)) {
+ if (!finfo->short_name[0]) {
+ /* Shortname not created when it should be. */
+ d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
+ __location__, finfo->name, i);
+ s->val = true;
+ }
+ } else if (finfo->short_name[0]){
+ /* Shortname created when it should not be. */
+ d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
+ __location__, finfo->short_name, finfo->name);
+ s->val = true;
+ }
+}
+
+static bool run_shortname_test(int dummy)
+{
+ static struct cli_state *cli;
+ bool correct = True;
+ int i;
+ struct sn_state s;
+ char fname[20];
+
+ printf("starting shortname test\n");
+
+ if (!torture_open_connection(&cli, 0)) {
+ return False;
+ }
+
+ cli_sockopt(cli, sockops);
+
+ cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
+ cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
+ cli_rmdir(cli, "\\shortname");
+
+ if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
+ d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
+ __location__, cli_errstr(cli));
+ correct = false;
+ goto out;
+ }
+
+ strlcpy(fname, "\\shortname\\", sizeof(fname));
+ strlcat(fname, "test .txt", sizeof(fname));
+
+ s.val = false;
+
+ for (i = 32; i < 128; i++) {
+ NTSTATUS status;
+ uint16_t fnum = (uint16_t)-1;
+
+ s.i = i;
+
+ if (strchr(illegal_chars, i)) {
+ continue;
+ }
+ fname[15] = i;
+
+ status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("(%s) cli_nt_create of %s failed: %s\n",
+ __location__, fname, cli_errstr(cli));
+ correct = false;
+ goto out;
+ }
+ cli_close(cli, fnum);
+ if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
+ d_printf("(%s) failed to list %s: %s\n",
+ __location__, fname, cli_errstr(cli));
+ correct = false;
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
+ d_printf("(%s) failed to delete %s: %s\n",
+ __location__, fname, cli_errstr(cli));
+ correct = false;
+ goto out;
+ }
+
+ if (s.val) {
+ correct = false;
+ goto out;
+ }
+ }
+
+ out:
+
+ cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
+ cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
+ cli_rmdir(cli, "\\shortname");
+ torture_close_connection(cli);
+ return correct;
+}
+
+static void pagedsearch_cb(struct tevent_req *req)
+{
+ int rc;
+ struct tldap_message *msg;
+ char *dn;
+
+ rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
+ if (rc != TLDAP_SUCCESS) {
+ d_printf("tldap_search_paged_recv failed: %s\n",
+ tldap_err2string(rc));
+ return;
+ }
+ if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
+ TALLOC_FREE(msg);
+ return;
+ }
+ if (!tldap_entry_dn(msg, &dn)) {
+ d_printf("tldap_entry_dn failed\n");
+ return;
+ }
+ d_printf("%s\n", dn);
+ TALLOC_FREE(msg);
+}
+
+static bool run_tldap(int dummy)
+{
+ struct tldap_context *ld;
+ int fd, rc;
+ NTSTATUS status;
+ struct sockaddr_storage addr;
+ struct tevent_context *ev;
+ struct tevent_req *req;
+ char *basedn;
+
+ if (!resolve_name(host, &addr, 0, false)) {
+ d_printf("could not find host %s\n", host);
+ return false;
+ }
+ status = open_socket_out(&addr, 389, 9999, &fd);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("open_socket_out failed: %s\n", nt_errstr(status));
+ return false;
+ }
+
+ ld = tldap_context_create(talloc_tos(), fd);
+ if (ld == NULL) {
+ close(fd);
+ d_printf("tldap_context_create failed\n");
+ return false;
+ }
+
+ rc = tldap_fetch_rootdse(ld);
+ if (rc != TLDAP_SUCCESS) {
+ d_printf("tldap_fetch_rootdse failed: %s\n",
+ tldap_errstr(talloc_tos(), ld, rc));
+ return false;
+ }
+
+ basedn = tldap_talloc_single_attribute(
+ tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
+ if (basedn == NULL) {
+ d_printf("no defaultNamingContext\n");
+ return false;
+ }
+ d_printf("defaultNamingContext: %s\n", basedn);
+
+ ev = tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ d_printf("tevent_context_init failed\n");
+ return false;
+ }
+
+ req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
+ TLDAP_SCOPE_SUB, "(objectclass=*)",
+ NULL, 0, 0,
+ NULL, 0, NULL, 0, 0, 0, 0, 5);
+ if (req == NULL) {
+ d_printf("tldap_search_paged_send failed\n");
+ return false;
+ }
+ tevent_req_set_callback(req, pagedsearch_cb, NULL);
+
+ tevent_req_poll(req, ev);
+
+ TALLOC_FREE(req);
+
+ TALLOC_FREE(ld);
+ return true;
+}
+
+static bool run_streamerror(int dummy)
+{
+ struct cli_state *cli;
+ const char *dname = "\\testdir";
+ const char *streamname =
+ "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
+ NTSTATUS status;
+ time_t change_time, access_time, write_time;
+ SMB_OFF_T size;
+ uint16_t mode, fnum;
+ bool ret = true;
+
+ if (!torture_open_connection(&cli, 0)) {
+ return false;
+ }
+
+ cli_rmdir(cli, dname);
+
+ status = cli_mkdir(cli, dname);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("mkdir failed: %s\n", nt_errstr(status));
+ return false;
+ }
+
+ cli_qpathinfo(cli, streamname, &change_time, &access_time, &write_time,
+ &size, &mode);
+ status = cli_nt_error(cli);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ printf("pathinfo returned %s, expected "
+ "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
+ nt_errstr(status));
+ ret = false;
+ }
+
+ status = cli_ntcreate(cli, streamname, 0x16,
+ FILE_READ_DATA|FILE_READ_EA|
+ FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
+ FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
+ FILE_OPEN, 0, 0, &fnum);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ printf("ntcreate returned %s, expected "
+ "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
+ nt_errstr(status));
+ ret = false;
+ }
+
+
+ cli_rmdir(cli, dname);
+ return ret;
+}
+
static bool run_local_substitute(int dummy)
{
bool ok = true;
return ok;
}
+static bool run_local_base64(int dummy)
+{
+ int i;
+ bool ret = true;
+
+ for (i=1; i<2000; i++) {
+ DATA_BLOB blob1, blob2;
+ char *b64;
+
+ blob1.data = talloc_array(talloc_tos(), uint8_t, i);
+ blob1.length = i;
+ generate_random_buffer(blob1.data, blob1.length);
+
+ b64 = base64_encode_data_blob(talloc_tos(), blob1);
+ if (b64 == NULL) {
+ d_fprintf(stderr, "base64_encode_data_blob failed "
+ "for %d bytes\n", i);
+ ret = false;
+ }
+ blob2 = base64_decode_data_blob(b64);
+ TALLOC_FREE(b64);
+
+ if (data_blob_cmp(&blob1, &blob2)) {
+ d_fprintf(stderr, "data_blob_cmp failed for %d "
+ "bytes\n", i);
+ ret = false;
+ }
+ TALLOC_FREE(blob1.data);
+ data_blob_free(&blob2);
+ }
+ return ret;
+}
+
static bool run_local_gencache(int dummy)
{
char *val;
time_t tm;
DATA_BLOB blob;
- if (!gencache_init()) {
- d_printf("%s: gencache_init() failed\n", __location__);
- return False;
- }
-
if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
d_printf("%s: gencache_set() failed\n", __location__);
return False;
}
blob = data_blob_string_const_null("bar");
- tm = time(NULL);
+ tm = time(NULL) + 60;
if (!gencache_set_data_blob("foo", &blob, tm)) {
d_printf("%s: gencache_set_data_blob() failed\n", __location__);
return False;
}
- data_blob_free(&blob);
-
if (!gencache_get_data_blob("foo", &blob, NULL)) {
d_printf("%s: gencache_get_data_blob() failed\n", __location__);
return False;
return False;
}
- if (!gencache_shutdown()) {
- d_printf("%s: gencache_shutdown() failed\n", __location__);
- return False;
- }
-
- if (gencache_shutdown()) {
- d_printf("%s: second gencache_shutdown() succeeded\n",
- __location__);
- return False;
- }
-
return True;
}
return ret;
}
+/* Split a path name into filename and stream name components. Canonicalise
+ * such that an implicit $DATA token is always explicit.
+ *
+ * The "specification" of this function can be found in the
+ * run_local_stream_name() function in torture.c, I've tried those
+ * combinations against a W2k3 server.
+ */
+
+static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
+ char **pbase, char **pstream)
+{
+ char *base = NULL;
+ char *stream = NULL;
+ char *sname; /* stream name */
+ const char *stype; /* stream type */
+
+ DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
+
+ sname = strchr_m(fname, ':');
+
+ if (lp_posix_pathnames() || (sname == NULL)) {
+ if (pbase != NULL) {
+ base = talloc_strdup(mem_ctx, fname);
+ NT_STATUS_HAVE_NO_MEMORY(base);
+ }
+ goto done;
+ }
+
+ if (pbase != NULL) {
+ base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
+ NT_STATUS_HAVE_NO_MEMORY(base);
+ }
+
+ sname += 1;
+
+ stype = strchr_m(sname, ':');
+
+ if (stype == NULL) {
+ sname = talloc_strdup(mem_ctx, sname);
+ stype = "$DATA";
+ }
+ else {
+ if (StrCaseCmp(stype, ":$DATA") != 0) {
+ /*
+ * If there is an explicit stream type, so far we only
+ * allow $DATA. Is there anything else allowed? -- vl
+ */
+ DEBUG(10, ("[%s] is an invalid stream type\n", stype));
+ TALLOC_FREE(base);
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
+ stype += 1;
+ }
+
+ if (sname == NULL) {
+ TALLOC_FREE(base);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (sname[0] == '\0') {
+ /*
+ * no stream name, so no stream
+ */
+ goto done;
+ }
+
+ if (pstream != NULL) {
+ stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
+ if (stream == NULL) {
+ TALLOC_FREE(sname);
+ TALLOC_FREE(base);
+ return NT_STATUS_NO_MEMORY;
+ }
+ /*
+ * upper-case the type field
+ */
+ strupper_m(strchr_m(stream, ':')+1);
+ }
+
+ done:
+ if (pbase != NULL) {
+ *pbase = base;
+ }
+ if (pstream != NULL) {
+ *pstream = stream;
+ }
+ return NT_STATUS_OK;
+}
+
static bool test_stream_name(const char *fname, const char *expected_base,
const char *expected_stream,
NTSTATUS expected_status)
BlockSignals(True, SIGPIPE);
- ev = event_context_init(talloc_tos());
+ ev = tevent_context_init_byname(talloc_tos(), "epoll");
if (ev == NULL) {
goto fail;
}
- wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
+ wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
if (wb_ctx == NULL) {
goto fail;
}
ZERO_STRUCT(wb_req);
wb_req.cmd = WINBINDD_PING;
- for (i=0; i<torture_numops; i++) {
- wb_ctx[i] = wb_context_init(ev);
+ d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
+
+ for (i=0; i<nprocs; i++) {
+ wb_ctx[i] = wb_context_init(ev, NULL);
if (wb_ctx[i] == NULL) {
goto fail;
}
- for (j=0; j<5; j++) {
+ for (j=0; j<torture_numops; j++) {
struct tevent_req *req;
req = wb_trans_send(ev, ev, wb_ctx[i],
(j % 2) == 0, &wb_req);
i = 0;
- while (i < 5 * torture_numops) {
+ while (i < nprocs * torture_numops) {
event_loop_once(ev);
}
{"LOCK5", run_locktest5, 0},
{"LOCK6", run_locktest6, 0},
{"LOCK7", run_locktest7, 0},
+ {"LOCK8", run_locktest8, 0},
{"UNLINK", run_unlinktest, 0},
{"BROWSE", run_browsetest, 0},
{"ATTR", run_attrtest, 0},
{"OPEN", run_opentest, 0},
{"POSIX", run_simple_posix_open_test, 0},
{ "UID-REGRESSION-TEST", run_uid_regression_test, 0},
+ { "SHORTNAME-TEST", run_shortname_test, 0},
#if 1
{"OPENATTR", run_openattrtest, 0},
#endif
{ "EATEST", run_eatest, 0},
{ "SESSSETUP_BENCH", run_sesssetup_bench, 0},
{ "CHAIN1", run_chain1, 0},
+ { "CHAIN2", run_chain2, 0},
{ "WINDOWS-WRITE", run_windows_write, 0},
{ "CLI_ECHO", run_cli_echo, 0},
{ "GETADDRINFO", run_getaddrinfo_send, 0},
+ { "TLDAP", run_tldap },
+ { "STREAMERROR", run_streamerror },
{ "LOCAL-SUBSTITUTE", run_local_substitute, 0},
{ "LOCAL-GENCACHE", run_local_gencache, 0},
+ { "LOCAL-BASE64", run_local_base64, 0},
{ "LOCAL-RBTREE", run_local_rbtree, 0},
{ "LOCAL-MEMCACHE", run_local_memcache, 0},
{ "LOCAL-STREAM-NAME", run_local_stream_name, 0},