X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Ftorture%2Ftorture.c;h=7a209859b3f86c52e2f719566b9f17fa7dd5c82d;hb=e18610a197aab80a32cae8c1e09b96496679bbad;hp=ea0fc01d69208247bf1e0785eebccddd8cf5a04c;hpb=1863e6da0aeb9218394cabccf9c7a0e4507edaec;p=samba.git diff --git a/source3/torture/torture.c b/source3/torture/torture.c index ea0fc01d692..7a209859b3f 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -20,6 +20,7 @@ #include "includes.h" #include "system/shmem.h" +#include "libsmb/namequery.h" #include "wbc_async.h" #include "torture/proto.h" #include "libcli/security/security.h" @@ -31,7 +32,6 @@ #include "dbwrap/dbwrap.h" #include "dbwrap/dbwrap_open.h" #include "dbwrap/dbwrap_rbt.h" -#include "talloc_dict.h" #include "async_smb.h" #include "libsmb/libsmb.h" #include "libsmb/clirap.h" @@ -43,11 +43,15 @@ #include "../libcli/smb/smbXcli_base.h" #include "lib/util/sys_rw_data.h" #include "lib/util/base64.h" +#include "lib/util/time.h" +#include "lib/crypto/md5.h" +#include "lib/gencache.h" extern char *optarg; extern int optind; fstring host, workgroup, share, password, username, myname; +struct cli_credentials *torture_creds; static const char *sockops="TCP_NODELAY"; int torture_nprocs=1; static int port_to_use=0; @@ -107,15 +111,7 @@ static bool force_cli_encryption(struct cli_state *c, return false; } - if (c->use_kerberos) { - status = cli_gss_smb_encryption_start(c); - } else { - status = cli_raw_ntlm_smb_encryption_start(c, - username, - password, - workgroup); - } - + status = cli_smb1_setup_encryption(c, torture_creds); if (!NT_STATUS_IS_OK(status)) { d_printf("Encryption required and " "setup failed with error %s.\n", @@ -333,23 +329,21 @@ bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, static bool torture_open_connection_share(struct cli_state **c, const char *hostname, - const char *sharename) + const char *sharename, + int flags) { - int flags = 0; NTSTATUS status; - if (use_kerberos) - flags |= CLI_FULL_CONNECTION_USE_KERBEROS; - if (use_oplocks) - flags |= CLI_FULL_CONNECTION_OPLOCKS; - if (use_level_II_oplocks) - flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS; - - status = cli_full_connection(c, myname, - hostname, NULL, port_to_use, - sharename, "?????", - username, workgroup, - password, flags, signing_state); + status = cli_full_connection_creds(c, + myname, + hostname, + NULL, /* dest_ss */ + port_to_use, + sharename, + "?????", + torture_creds, + flags, + signing_state); if (!NT_STATUS_IS_OK(status)) { printf("failed to open share connection: //%s/%s port:%d - %s\n", hostname, sharename, port_to_use, nt_errstr(status)); @@ -365,7 +359,7 @@ static bool torture_open_connection_share(struct cli_state **c, return True; } -bool torture_open_connection(struct cli_state **c, int conn_index) +bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags) { char **unc_list = NULL; int num_unc_names = 0; @@ -387,14 +381,28 @@ bool torture_open_connection(struct cli_state **c, int conn_index) exit(1); } - result = torture_open_connection_share(c, h, s); + result = torture_open_connection_share(c, h, s, flags); /* h, s were copied earlier */ TALLOC_FREE(unc_list); return result; } - return torture_open_connection_share(c, host, share); + return torture_open_connection_share(c, host, share, flags); +} + +bool torture_open_connection(struct cli_state **c, int conn_index) +{ + int flags = CLI_FULL_CONNECTION_FORCE_SMB1; + + if (use_oplocks) { + flags |= CLI_FULL_CONNECTION_OPLOCKS; + } + if (use_level_II_oplocks) { + flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS; + } + + return torture_open_connection_flags(c, conn_index, flags); } bool torture_init_connection(struct cli_state **pcli) @@ -413,15 +421,11 @@ bool torture_init_connection(struct cli_state **pcli) bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid) { uint16_t old_vuid = cli_state_get_uid(cli); - size_t passlen = strlen(password); NTSTATUS status; bool ret; cli_state_set_uid(cli, 0); - status = cli_session_setup(cli, username, - password, passlen, - password, passlen, - workgroup); + status = cli_session_setup_creds(cli, torture_creds); ret = NT_STATUS_IS_OK(status); *new_vuid = cli_state_get_uid(cli); cli_state_set_uid(cli, old_vuid); @@ -1309,7 +1313,8 @@ static bool run_tcon_test(int dummy) static struct cli_state *cli; const char *fname = "\\tcontest.tmp"; uint16_t fnum1; - uint16_t cnum1, cnum2, cnum3; + uint32_t cnum1, cnum2, cnum3; + struct smbXcli_tcon *orig_tcon = NULL; uint16_t vuid1, vuid2; char buf[4]; bool ret = True; @@ -1341,8 +1346,12 @@ static bool run_tcon_test(int dummy) return False; } - status = cli_tree_connect(cli, share, "?????", - password, strlen(password)+1); + orig_tcon = cli_state_save_tcon(cli); + if (orig_tcon == NULL) { + return false; + } + + status = cli_tree_connect_creds(cli, share, "?????", torture_creds); if (!NT_STATUS_IS_OK(status)) { printf("%s refused 2nd tree connect (%s)\n", host, nt_errstr(status)); @@ -1409,6 +1418,8 @@ static bool run_tcon_test(int dummy) return False; } + cli_state_restore_tcon(cli, orig_tcon); + cli_state_set_tid(cli, cnum1); if (!torture_close_connection(cli)) { @@ -1467,12 +1478,12 @@ static bool tcon_devtest(struct cli_state *cli, NTSTATUS status; bool ret; - status = cli_tree_connect(cli, myshare, devtype, - password, strlen(password)+1); + status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds); if (NT_STATUS_IS_OK(expected_error)) { if (NT_STATUS_IS_OK(status)) { - if (strcmp(cli->dev, return_devtype) == 0) { + if (return_devtype != NULL && + strequal(cli->dev, return_devtype)) { ret = True; } else { printf("tconX to share %s with type %s " @@ -1512,15 +1523,20 @@ static bool tcon_devtest(struct cli_state *cli, static bool run_tcon_devtype_test(int dummy) { static struct cli_state *cli1 = NULL; - int flags = 0; + int flags = CLI_FULL_CONNECTION_FORCE_SMB1; NTSTATUS status; bool ret = True; - status = cli_full_connection(&cli1, myname, - host, NULL, port_to_use, - NULL, NULL, - username, workgroup, - password, flags, signing_state); + status = cli_full_connection_creds(&cli1, + myname, + host, + NULL, /* dest_ss */ + port_to_use, + NULL, /* service */ + NULL, /* service_type */ + torture_creds, + flags, + signing_state); if (!NT_STATUS_IS_OK(status)) { printf("could not open connection\n"); @@ -2145,7 +2161,7 @@ static bool run_locktest5(int dummy) ret = NT_STATUS_IS_OK(status); EXPECTED(ret, False); - printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot"); + printf("a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot"); /* Unlock the process 2 lock. */ cli_unlock(cli2, fnum2, 0, 4); @@ -2154,7 +2170,7 @@ static bool run_locktest5(int dummy) ret = NT_STATUS_IS_OK(status); EXPECTED(ret, False); - printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot"); + printf("the same process on a different fnum %s get a read lock\n", ret?"can":"cannot"); /* Unlock the process 1 fnum3 lock. */ cli_unlock(cli1, fnum3, 0, 4); @@ -2197,7 +2213,7 @@ static bool run_locktest5(int dummy) ret = NT_STATUS_IS_OK(status); EXPECTED(ret, True); - printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot"); + printf("a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot"); fail: @@ -2769,8 +2785,8 @@ static bool run_fdsesstest(int dummy) struct cli_state *cli; uint16_t new_vuid; uint16_t saved_vuid; - uint16_t new_cnum; - uint16_t saved_cnum; + uint32_t new_cnum; + uint32_t saved_cnum; const char *fname = "\\fdsess.tst"; const char *fname1 = "\\fdsess1.tst"; uint16_t fnum1; @@ -2787,7 +2803,7 @@ static bool run_fdsesstest(int dummy) return False; saved_cnum = cli_state_get_tid(cli); - if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", "", 1))) + if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL))) return False; new_cnum = cli_state_get_tid(cli); cli_state_set_tid(cli, saved_cnum); @@ -2995,7 +3011,7 @@ static bool run_negprot_nowait(int dummy) struct tevent_req *req; req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout, - PROTOCOL_CORE, PROTOCOL_NT1); + PROTOCOL_CORE, PROTOCOL_NT1, 0); if (req == NULL) { TALLOC_FREE(ev); return false; @@ -3150,6 +3166,29 @@ static bool run_browsetest(int dummy) } +static bool check_attributes(struct cli_state *cli, + const char *fname, + uint16_t expected_attrs) +{ + uint16_t attrs = 0; + NTSTATUS status = cli_getatr(cli, + fname, + &attrs, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_getatr failed with %s\n", + nt_errstr(status)); + return false; + } + if (attrs != expected_attrs) { + printf("Attributes incorrect 0x%x, should be 0x%x\n", + (unsigned int)attrs, + (unsigned int)expected_attrs); + return false; + } + return true; +} /* This checks how the getatr calls works @@ -3180,7 +3219,7 @@ static bool run_attrtest(int dummy) correct = False; } - if (abs(t - time(NULL)) > 60*60*24*10) { + if (labs(t - time(NULL)) > 60*60*24*10) { printf("ERROR: SMBgetatr bug. time is %s", ctime(&t)); t = time(NULL); @@ -3210,6 +3249,120 @@ static bool run_attrtest(int dummy) cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + /* Check cli_setpathinfo_basic() */ + /* Re-create the file. */ + status = cli_openx(cli, fname, + O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("Failed to recreate %s (%s)\n", + fname, nt_errstr(status)); + correct = false; + } + cli_close(cli, fnum); + + status = cli_setpathinfo_basic(cli, + fname, + 0, /* create */ + 0, /* access */ + 0, /* write */ + 0, /* change */ + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_setpathinfo_basic failed with %s\n", + nt_errstr(status)); + correct = false; + } + + /* Check attributes are correct. */ + correct = check_attributes(cli, + fname, + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY); + if (correct == false) { + goto out; + } + + /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */ + status = cli_setpathinfo_basic(cli, + fname, + 0, /* create */ + 0, /* access */ + 0, /* write */ + 0, /* change */ + FILE_ATTRIBUTE_NORMAL); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_setpathinfo_basic failed with %s\n", + nt_errstr(status)); + correct = false; + } + + /* Check attributes are correct. */ + correct = check_attributes(cli, + fname, + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY); + if (correct == false) { + goto out; + } + + /* Setting to (uint16_t)-1 should also be ignored. */ + status = cli_setpathinfo_basic(cli, + fname, + 0, /* create */ + 0, /* access */ + 0, /* write */ + 0, /* change */ + (uint16_t)-1); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_setpathinfo_basic failed with %s\n", + nt_errstr(status)); + correct = false; + } + + /* Check attributes are correct. */ + correct = check_attributes(cli, + fname, + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY); + if (correct == false) { + goto out; + } + + /* Setting to 0 should clear them all. */ + status = cli_setpathinfo_basic(cli, + fname, + 0, /* create */ + 0, /* access */ + 0, /* write */ + 0, /* change */ + 0); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_setpathinfo_basic failed with %s\n", + nt_errstr(status)); + correct = false; + } + + /* Check attributes are correct. */ + correct = check_attributes(cli, + fname, + FILE_ATTRIBUTE_NORMAL); + if (correct == false) { + goto out; + } + + out: + + cli_unlink(cli, + fname, + FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN| + FILE_ATTRIBUTE_READONLY); + if (!torture_close_connection(cli)) { correct = False; } @@ -3297,13 +3450,13 @@ static bool run_trans2test(int dummy) printf("modify time=%s", ctime(&m_time)); printf("This system appears to have sticky create times\n"); } - if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) { + if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) { printf("access time=%s", ctime(&a_time)); printf("This system appears to set a midnight access time\n"); correct = False; } - if (abs(m_time - t) > 60*60*24*7) { + if (labs(m_time - t) > 60*60*24*7) { printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time)); correct = False; } @@ -4410,6 +4563,78 @@ static bool run_deletetest(int dummy) return correct; } +/* + Exercise delete on close semantics - use on the PRINT1 share in torture + testing. + */ +static bool run_delete_print_test(int dummy) +{ + struct cli_state *cli1 = NULL; + const char *fname = "print_delete.file"; + uint16_t fnum1 = (uint16_t)-1; + bool correct = false; + const char *buf = "print file data\n"; + NTSTATUS status; + + printf("starting print delete test\n"); + + if (!torture_open_connection(&cli1, 0)) { + return false; + } + + smbXcli_conn_set_sockopt(cli1->conn, sockops); + + status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, + FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, + 0, 0, &fnum1, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("open of %s failed (%s)\n", + fname, + nt_errstr(status)); + goto fail; + } + + status = cli_writeall(cli1, + fnum1, + 0, + (const uint8_t *)buf, + 0, /* offset */ + strlen(buf), /* size */ + NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("writing print file data failed (%s)\n", + nt_errstr(status)); + goto fail; + } + + status = cli_nt_delete_on_close(cli1, fnum1, true); + if (!NT_STATUS_IS_OK(status)) { + printf("setting delete_on_close failed (%s)\n", + nt_errstr(status)); + goto fail; + } + + status = cli_close(cli1, fnum1); + if (!NT_STATUS_IS_OK(status)) { + printf("close failed (%s)\n", nt_errstr(status)); + goto fail; + } + + printf("finished print delete test\n"); + + correct = true; + + fail: + + if (fnum1 != (uint16_t)-1) { + cli_close(cli1, fnum1); + } + + if (cli1 && !torture_close_connection(cli1)) { + correct = false; + } + return correct; +} /* Test wildcard delete. @@ -4708,7 +4933,7 @@ static bool run_rename(int dummy) return False; } - status = cli_rename(cli1, fname, fname1); + status = cli_rename(cli1, fname, fname1, false); if (!NT_STATUS_IS_OK(status)) { printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status)); } else { @@ -4736,7 +4961,7 @@ static bool run_rename(int dummy) return False; } - status = cli_rename(cli1, fname, fname1); + status = cli_rename(cli1, fname, fname1, false); if (!NT_STATUS_IS_OK(status)) { printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status)); correct = False; @@ -4783,7 +5008,7 @@ static bool run_rename(int dummy) } #endif - status = cli_rename(cli1, fname, fname1); + status = cli_rename(cli1, fname, fname1, false); if (!NT_STATUS_IS_OK(status)) { printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status)); correct = False; @@ -4811,7 +5036,7 @@ static bool run_rename(int dummy) return False; } - status = cli_rename(cli1, fname, fname1); + status = cli_rename(cli1, fname, fname1, false); if (!NT_STATUS_IS_OK(status)) { printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status)); } else { @@ -4839,7 +5064,7 @@ static bool run_rename(int dummy) return False; } - status = cli_rename(cli1, fname, fname1); + status = cli_rename(cli1, fname, fname1, false); if (!NT_STATUS_IS_OK(status)) { printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status)); correct = False; @@ -4898,97 +5123,673 @@ static bool run_rename(int dummy) return correct; } -static bool run_pipe_number(int dummy) -{ - struct cli_state *cli1; - const char *pipe_name = "\\SPOOLSS"; - uint16_t fnum; - int num_pipes = 0; +/* + Test rename into a directory with an ACL denying it. + */ +static bool run_rename_access(int dummy) +{ + static struct cli_state *cli = NULL; + static struct cli_state *posix_cli = NULL; + const char *src = "test.txt"; + const char *dname = "dir"; + const char *dst = "dir\\test.txt"; + const char *dsrc = "test.dir"; + const char *ddst = "dir\\test.dir"; + uint16_t fnum = (uint16_t)-1; + struct security_descriptor *sd = NULL; + struct security_descriptor *newsd = NULL; NTSTATUS status; + TALLOC_CTX *frame = NULL; - printf("starting pipenumber test\n"); - if (!torture_open_connection(&cli1, 0)) { - return False; - } + frame = talloc_stackframe(); + printf("starting rename access test\n"); - smbXcli_conn_set_sockopt(cli1->conn, sockops); - while(1) { - status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, - FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_OPEN_IF, 0, 0, &fnum, NULL); - if (!NT_STATUS_IS_OK(status)) { - printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status)); - break; - } - num_pipes++; - printf("\r%6d", num_pipes); + /* Windows connection. */ + if (!torture_open_connection(&cli, 0)) { + goto fail; } - printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name ); - torture_close_connection(cli1); - return True; -} + smbXcli_conn_set_sockopt(cli->conn, sockops); -/* - Test open mode returns on read-only files. - */ -static bool run_opentest(int dummy) -{ - static struct cli_state *cli1; - static struct cli_state *cli2; - const char *fname = "\\readonly.file"; - uint16_t fnum1, fnum2; - char buf[20]; - off_t fsize; - bool correct = True; - char *tmp_path; - NTSTATUS status; + /* Posix connection. */ + if (!torture_open_connection(&posix_cli, 0)) { + goto fail; + } - printf("starting open test\n"); + smbXcli_conn_set_sockopt(posix_cli->conn, sockops); - if (!torture_open_connection(&cli1, 0)) { - return False; + status = torture_setup_unix_extensions(posix_cli); + if (!NT_STATUS_IS_OK(status)) { + goto fail; } - cli_setatr(cli1, fname, 0, 0); - cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); - - smbXcli_conn_set_sockopt(cli1->conn, sockops); + /* Start with a clean slate. */ + cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_rmdir(cli, dsrc); + cli_rmdir(cli, ddst); + cli_rmdir(cli, dname); - status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1); + /* + * Setup the destination directory with a DENY ACE to + * prevent new files within it. + */ + status = cli_ntcreate(cli, + dname, + 0, + FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS| + WRITE_DAC_ACCESS|FILE_READ_DATA| + WRITE_OWNER_ACCESS, + FILE_ATTRIBUTE_DIRECTORY, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, + FILE_DIRECTORY_FILE, + 0, + &fnum, + NULL); if (!NT_STATUS_IS_OK(status)) { - printf("open of %s failed (%s)\n", fname, nt_errstr(status)); - return False; + printf("Create of %s - %s\n", dname, nt_errstr(status)); + goto fail; } - status = cli_close(cli1, fnum1); + status = cli_query_secdesc(cli, + fnum, + frame, + &sd); if (!NT_STATUS_IS_OK(status)) { - printf("close2 failed (%s)\n", nt_errstr(status)); - return False; + printf("cli_query_secdesc failed for %s (%s)\n", + dname, nt_errstr(status)); + goto fail; } - status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0); + newsd = security_descriptor_dacl_create(frame, + 0, + NULL, + NULL, + SID_WORLD, + SEC_ACE_TYPE_ACCESS_DENIED, + SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR, + 0, + NULL); + if (newsd == NULL) { + goto fail; + } + sd->dacl = security_acl_concatenate(frame, + newsd->dacl, + sd->dacl); + if (sd->dacl == NULL) { + goto fail; + } + status = cli_set_secdesc(cli, fnum, sd); if (!NT_STATUS_IS_OK(status)) { - printf("cli_setatr failed (%s)\n", nt_errstr(status)); - return False; + printf("cli_set_secdesc failed for %s (%s)\n", + dname, nt_errstr(status)); + goto fail; } - - status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1); + status = cli_close(cli, fnum); if (!NT_STATUS_IS_OK(status)) { - printf("open of %s failed (%s)\n", fname, nt_errstr(status)); - return False; + printf("close failed for %s (%s)\n", + dname, nt_errstr(status)); + goto fail; + } + /* Now go around the back and chmod to 777 via POSIX. */ + status = cli_posix_chmod(posix_cli, dname, 0777); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_chmod failed for %s (%s)\n", + dname, nt_errstr(status)); + goto fail; } - /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */ - status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2); - - if (check_error(__LINE__, status, ERRDOS, ERRnoaccess, - NT_STATUS_ACCESS_DENIED)) { - printf("correct error code ERRDOS/ERRnoaccess returned\n"); + /* Check we can't create a file within dname via Windows. */ + status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum); + if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + cli_close(posix_cli, fnum); + printf("Create of %s should be ACCESS denied, was %s\n", + dst, nt_errstr(status)); + goto fail; } - printf("finished open test 1\n"); + /* Make the sample file/directory. */ + status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("open of %s failed (%s)\n", src, nt_errstr(status)); + goto fail; + } + status = cli_close(cli, fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_close failed (%s)\n", nt_errstr(status)); + goto fail; + } + + status = cli_mkdir(cli, dsrc); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_mkdir of %s failed (%s)\n", + dsrc, nt_errstr(status)); + goto fail; + } + + /* + * OK - renames of the new file and directory into the + * dst directory should fail. + */ + + status = cli_rename(cli, src, dst, false); + if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + printf("rename of %s -> %s should be ACCESS denied, was %s\n", + src, dst, nt_errstr(status)); + goto fail; + } + status = cli_rename(cli, dsrc, ddst, false); + if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + printf("rename of %s -> %s should be ACCESS denied, was %s\n", + src, dst, nt_errstr(status)); + goto fail; + } + + TALLOC_FREE(frame); + return true; + + fail: + + if (posix_cli) { + torture_close_connection(posix_cli); + } + + if (cli) { + if (fnum != (uint16_t)-1) { + cli_close(cli, fnum); + } + cli_unlink(cli, src, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_unlink(cli, dst, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_rmdir(cli, dsrc); + cli_rmdir(cli, ddst); + cli_rmdir(cli, dname); + + torture_close_connection(cli); + } + + TALLOC_FREE(frame); + return false; +} + +/* + Test owner rights ACE. + */ +static bool run_owner_rights(int dummy) +{ + static struct cli_state *cli = NULL; + const char *fname = "owner_rights.txt"; + uint16_t fnum = (uint16_t)-1; + struct security_descriptor *sd = NULL; + struct security_descriptor *newsd = NULL; + NTSTATUS status; + TALLOC_CTX *frame = NULL; + + frame = talloc_stackframe(); + printf("starting owner rights test\n"); + + /* Windows connection. */ + if (!torture_open_connection(&cli, 0)) { + goto fail; + } + + smbXcli_conn_set_sockopt(cli->conn, sockops); + + /* Start with a clean slate. */ + cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + /* Create the test file. */ + /* Now try and open for read and write-dac. */ + status = cli_ntcreate(cli, + fname, + 0, + GENERIC_ALL_ACCESS, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE| + FILE_SHARE_DELETE, + FILE_CREATE, + 0, + 0, + &fnum, + NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("Create of %s - %s\n", fname, nt_errstr(status)); + goto fail; + } + + /* Get the original SD. */ + status = cli_query_secdesc(cli, + fnum, + frame, + &sd); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_query_secdesc failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + + /* + * Add an "owner-rights" ACE denying WRITE_DATA, + * and an "owner-rights" ACE allowing READ_DATA. + */ + + newsd = security_descriptor_dacl_create(frame, + 0, + NULL, + NULL, + SID_OWNER_RIGHTS, + SEC_ACE_TYPE_ACCESS_DENIED, + FILE_WRITE_DATA, + 0, + SID_OWNER_RIGHTS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + FILE_READ_DATA, + 0, + NULL); + if (newsd == NULL) { + goto fail; + } + sd->dacl = security_acl_concatenate(frame, + newsd->dacl, + sd->dacl); + if (sd->dacl == NULL) { + goto fail; + } + status = cli_set_secdesc(cli, fnum, sd); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_set_secdesc failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + status = cli_close(cli, fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("close failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + fnum = (uint16_t)-1; + + /* Try and open for FILE_WRITE_DATA */ + status = cli_ntcreate(cli, + fname, + 0, + FILE_WRITE_DATA, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE| + FILE_SHARE_DELETE, + FILE_OPEN, + 0, + 0, + &fnum, + NULL); + if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + printf("Open of %s - %s\n", fname, nt_errstr(status)); + goto fail; + } + + /* Now try and open for FILE_READ_DATA */ + status = cli_ntcreate(cli, + fname, + 0, + FILE_READ_DATA, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE| + FILE_SHARE_DELETE, + FILE_OPEN, + 0, + 0, + &fnum, + NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("Open of %s - %s\n", fname, nt_errstr(status)); + goto fail; + } + + status = cli_close(cli, fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("close failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + + /* Restore clean slate. */ + TALLOC_FREE(sd); + cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + /* Create the test file. */ + status = cli_ntcreate(cli, + fname, + 0, + GENERIC_ALL_ACCESS, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE| + FILE_SHARE_DELETE, + FILE_CREATE, + 0, + 0, + &fnum, + NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("Create of %s - %s\n", fname, nt_errstr(status)); + goto fail; + } + + /* Get the original SD. */ + status = cli_query_secdesc(cli, + fnum, + frame, + &sd); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_query_secdesc failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + + /* + * Add an "owner-rights ACE denying WRITE_DATA, + * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA. + */ + + newsd = security_descriptor_dacl_create(frame, + 0, + NULL, + NULL, + SID_OWNER_RIGHTS, + SEC_ACE_TYPE_ACCESS_DENIED, + FILE_WRITE_DATA, + 0, + SID_OWNER_RIGHTS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + FILE_READ_DATA|FILE_WRITE_DATA, + 0, + NULL); + if (newsd == NULL) { + goto fail; + } + sd->dacl = security_acl_concatenate(frame, + newsd->dacl, + sd->dacl); + if (sd->dacl == NULL) { + goto fail; + } + status = cli_set_secdesc(cli, fnum, sd); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_set_secdesc failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + status = cli_close(cli, fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("close failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + fnum = (uint16_t)-1; + + /* Try and open for FILE_WRITE_DATA */ + status = cli_ntcreate(cli, + fname, + 0, + FILE_WRITE_DATA, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE| + FILE_SHARE_DELETE, + FILE_OPEN, + 0, + 0, + &fnum, + NULL); + if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + printf("Open of %s - %s\n", fname, nt_errstr(status)); + goto fail; + } + + /* Now try and open for FILE_READ_DATA */ + status = cli_ntcreate(cli, + fname, + 0, + FILE_READ_DATA, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE| + FILE_SHARE_DELETE, + FILE_OPEN, + 0, + 0, + &fnum, + NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("Open of %s - %s\n", fname, nt_errstr(status)); + goto fail; + } + + status = cli_close(cli, fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("close failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + + /* Restore clean slate. */ + TALLOC_FREE(sd); + cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + + /* Create the test file. */ + status = cli_ntcreate(cli, + fname, + 0, + GENERIC_ALL_ACCESS, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE| + FILE_SHARE_DELETE, + FILE_CREATE, + 0, + 0, + &fnum, + NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("Create of %s - %s\n", fname, nt_errstr(status)); + goto fail; + } + + /* Get the original SD. */ + status = cli_query_secdesc(cli, + fnum, + frame, + &sd); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_query_secdesc failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + + /* + * Add an "authenticated users" ACE allowing READ_DATA, + * add an "owner-rights" denying READ_DATA, + * and an "authenticated users" ACE allowing WRITE_DATA. + */ + + newsd = security_descriptor_dacl_create(frame, + 0, + NULL, + NULL, + SID_NT_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + FILE_READ_DATA, + 0, + SID_OWNER_RIGHTS, + SEC_ACE_TYPE_ACCESS_DENIED, + FILE_READ_DATA, + 0, + SID_NT_AUTHENTICATED_USERS, + SEC_ACE_TYPE_ACCESS_ALLOWED, + FILE_WRITE_DATA, + 0, + NULL); + if (newsd == NULL) { + printf("newsd == NULL\n"); + goto fail; + } + sd->dacl = security_acl_concatenate(frame, + newsd->dacl, + sd->dacl); + if (sd->dacl == NULL) { + printf("sd->dacl == NULL\n"); + goto fail; + } + status = cli_set_secdesc(cli, fnum, sd); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_set_secdesc failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + status = cli_close(cli, fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("close failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + fnum = (uint16_t)-1; + + /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */ + status = cli_ntcreate(cli, + fname, + 0, + FILE_READ_DATA|FILE_WRITE_DATA, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE| + FILE_SHARE_DELETE, + FILE_OPEN, + 0, + 0, + &fnum, + NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("Open of %s - %s\n", fname, nt_errstr(status)); + goto fail; + } + + status = cli_close(cli, fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("close failed for %s (%s)\n", + fname, nt_errstr(status)); + goto fail; + } + + cli_unlink(cli, fname, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + TALLOC_FREE(frame); + return true; + + fail: + + if (cli) { + if (fnum != (uint16_t)-1) { + cli_close(cli, fnum); + } + cli_unlink(cli, fname, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + torture_close_connection(cli); + } + + TALLOC_FREE(frame); + return false; +} + +static bool run_pipe_number(int dummy) +{ + struct cli_state *cli1; + const char *pipe_name = "\\SPOOLSS"; + uint16_t fnum; + int num_pipes = 0; + NTSTATUS status; + + printf("starting pipenumber test\n"); + if (!torture_open_connection(&cli1, 0)) { + return False; + } + + smbXcli_conn_set_sockopt(cli1->conn, sockops); + while(1) { + status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN_IF, 0, 0, &fnum, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status)); + break; + } + num_pipes++; + printf("\r%6d", num_pipes); + } + + printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name ); + torture_close_connection(cli1); + return True; +} + +/* + Test open mode returns on read-only files. + */ +static bool run_opentest(int dummy) +{ + static struct cli_state *cli1; + static struct cli_state *cli2; + const char *fname = "\\readonly.file"; + uint16_t fnum1, fnum2; + char buf[20]; + off_t fsize; + bool correct = True; + char *tmp_path; + NTSTATUS status; + + printf("starting open test\n"); + + if (!torture_open_connection(&cli1, 0)) { + return False; + } + + cli_setatr(cli1, fname, 0, 0); + cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + smbXcli_conn_set_sockopt(cli1->conn, sockops); + + status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1); + if (!NT_STATUS_IS_OK(status)) { + printf("open of %s failed (%s)\n", fname, nt_errstr(status)); + return False; + } + + status = cli_close(cli1, fnum1); + if (!NT_STATUS_IS_OK(status)) { + printf("close2 failed (%s)\n", nt_errstr(status)); + return False; + } + + status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_setatr failed (%s)\n", nt_errstr(status)); + return False; + } + + status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1); + if (!NT_STATUS_IS_OK(status)) { + printf("open of %s failed (%s)\n", fname, nt_errstr(status)); + return False; + } + + /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */ + status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2); + + if (check_error(__LINE__, status, ERRDOS, ERRnoaccess, + NT_STATUS_ACCESS_DENIED)) { + printf("correct error code ERRDOS/ERRnoaccess returned\n"); + } + + printf("finished open test 1\n"); cli_close(cli1, fnum1); @@ -6013,6 +6814,151 @@ static bool run_acl_symlink_test(int dummy) return correct; } +/* + Test POSIX can delete a file containing streams. + */ +static bool run_posix_stream_delete(int dummy) +{ + struct cli_state *cli1 = NULL; + struct cli_state *cli2 = NULL; + const char *fname = "streamfile"; + const char *stream_fname = "streamfile:Zone.Identifier:$DATA"; + uint16_t fnum1 = (uint16_t)-1; + bool correct = false; + NTSTATUS status; + TALLOC_CTX *frame = NULL; + + frame = talloc_stackframe(); + + printf("Starting POSIX stream delete test\n"); + + if (!torture_open_connection(&cli1, 0) || + !torture_open_connection(&cli2, 1)) { + TALLOC_FREE(frame); + return false; + } + + smbXcli_conn_set_sockopt(cli1->conn, sockops); + smbXcli_conn_set_sockopt(cli2->conn, sockops); + + status = torture_setup_unix_extensions(cli2); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + cli_setatr(cli1, fname, 0, 0); + cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + /* Create the file. */ + status = cli_ntcreate(cli1, + fname, + 0, + READ_CONTROL_ACCESS, + 0, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_CREATE, + 0x0, + 0x0, + &fnum1, + NULL); + + if (!NT_STATUS_IS_OK(status)) { + printf("cli_ntcreate of %s failed (%s)\n", + fname, + nt_errstr(status)); + goto out; + } + + status = cli_close(cli1, fnum1); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_close of %s failed (%s)\n", + fname, + nt_errstr(status)); + goto out; + } + fnum1 = (uint16_t)-1; + + /* Now create the stream. */ + status = cli_ntcreate(cli1, + stream_fname, + 0, + FILE_WRITE_DATA, + 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, + 0x0, + 0x0, + &fnum1, + NULL); + + if (!NT_STATUS_IS_OK(status)) { + printf("cli_ntcreate of %s failed (%s)\n", + stream_fname, + nt_errstr(status)); + goto out; + } + + /* Leave the stream handle open... */ + + /* POSIX unlink should fail. */ + status = cli_posix_unlink(cli2, fname); + if (NT_STATUS_IS_OK(status)) { + printf("cli_posix_unlink of %s succeeded, should have failed\n", + fname); + goto out; + } + + if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { + printf("cli_posix_unlink of %s failed with (%s) " + "should have been NT_STATUS_SHARING_VIOLATION\n", + fname, + nt_errstr(status)); + goto out; + } + + /* Close the stream handle. */ + status = cli_close(cli1, fnum1); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_close of %s failed (%s)\n", + stream_fname, + nt_errstr(status)); + goto out; + } + fnum1 = (uint16_t)-1; + + /* POSIX unlink after stream handle closed should succeed. */ + status = cli_posix_unlink(cli2, fname); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_unlink of %s failed (%s)\n", + fname, + nt_errstr(status)); + goto out; + } + + printf("POSIX stream delete test passed\n"); + correct = true; + + out: + + if (fnum1 != (uint16_t)-1) { + cli_close(cli1, fnum1); + fnum1 = (uint16_t)-1; + } + + cli_setatr(cli1, fname, 0, 0); + cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + if (!torture_close_connection(cli1)) { + correct = false; + } + if (!torture_close_connection(cli2)) { + correct = false; + } + + TALLOC_FREE(frame); + return correct; +} + /* Test setting EA's are rejected on symlinks. */ @@ -6238,69 +7184,269 @@ static bool run_posix_ofd_lock_test(int dummy) goto out; } - /* Set a 0-50 lock on fnum1. */ - status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK); + /* Set a 0-50 lock on fnum1. */ + status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK); + if (!NT_STATUS_IS_OK(status)) { + printf("POSIX lock (1) failed %s\n", nt_errstr(status)); + goto out; + } + + /* Set a 60-100 lock on fnum2. */ + status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK); + if (!NT_STATUS_IS_OK(status)) { + printf("POSIX lock (2) failed %s\n", nt_errstr(status)); + goto out; + } + + /* close fnum1 - 0-50 lock should go away. */ + status = cli_close(cli, fnum1); + if (!NT_STATUS_IS_OK(status)) { + printf("close failed (%s)\n", + nt_errstr(status)); + goto out; + } + fnum1 = (uint16_t)-1; + + /* Change the lock context. */ + cli_setpid(cli, cli_getpid(cli) + 1); + + /* Re-open fnum1. */ + status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1); + if (!NT_STATUS_IS_OK(status)) { + printf("Third POSIX open of %s failed\n", fname); + goto out; + } + + /* 60-100 lock should still be there. */ + status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK); + if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { + printf("POSIX lock 60-100 not there %s\n", nt_errstr(status)); + goto out; + } + + /* 0-50 lock should be gone. */ + status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK); + if (!NT_STATUS_IS_OK(status)) { + printf("POSIX lock 0-50 failed %s\n", nt_errstr(status)); + goto out; + } + + printf("POSIX OFD lock test passed\n"); + correct = true; + + out: + + if (fnum1 != (uint16_t)-1) { + cli_close(cli, fnum1); + fnum1 = (uint16_t)-1; + } + if (fnum2 != (uint16_t)-1) { + cli_close(cli, fnum2); + fnum2 = (uint16_t)-1; + } + + cli_setatr(cli, fname, 0, 0); + cli_posix_unlink(cli, fname); + + if (!torture_close_connection(cli)) { + correct = false; + } + + TALLOC_FREE(frame); + return correct; +} + +/* + Test POSIX mkdir is case-sensitive. + */ +static bool run_posix_mkdir_test(int dummy) +{ + static struct cli_state *cli; + const char *fname_foo = "POSIX_foo"; + const char *fname_foo_Foo = "POSIX_foo/Foo"; + const char *fname_foo_foo = "POSIX_foo/foo"; + const char *fname_Foo = "POSIX_Foo"; + const char *fname_Foo_Foo = "POSIX_Foo/Foo"; + const char *fname_Foo_foo = "POSIX_Foo/foo"; + bool correct = false; + NTSTATUS status; + TALLOC_CTX *frame = NULL; + uint16_t fnum = (uint16_t)-1; + + frame = talloc_stackframe(); + + printf("Starting POSIX mkdir test\n"); + + if (!torture_open_connection(&cli, 0)) { + TALLOC_FREE(frame); + return false; + } + + smbXcli_conn_set_sockopt(cli->conn, sockops); + + status = torture_setup_unix_extensions(cli); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return false; + } + + cli_posix_rmdir(cli, fname_foo_foo); + cli_posix_rmdir(cli, fname_foo_Foo); + cli_posix_rmdir(cli, fname_foo); + + cli_posix_rmdir(cli, fname_Foo_foo); + cli_posix_rmdir(cli, fname_Foo_Foo); + cli_posix_rmdir(cli, fname_Foo); + + /* + * Create a file POSIX_foo then try + * and use it in a directory path by + * doing mkdir POSIX_foo/bar. + * The mkdir should fail with + * NT_STATUS_OBJECT_PATH_NOT_FOUND + */ + + status = cli_posix_open(cli, + fname_foo, + O_RDWR|O_CREAT, + 0666, + &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_open of %s failed error %s\n", + fname_foo, + nt_errstr(status)); + goto out; + } + + status = cli_posix_mkdir(cli, fname_foo_foo, 0777); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) { + printf("cli_posix_mkdir of %s should fail with " + "NT_STATUS_OBJECT_PATH_NOT_FOUND got " + "%s instead\n", + fname_foo_foo, + nt_errstr(status)); + goto out; + } + + status = cli_close(cli, fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_close failed %s\n", nt_errstr(status)); + goto out; + } + fnum = (uint16_t)-1; + + status = cli_posix_unlink(cli, fname_foo); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_unlink of %s failed error %s\n", + fname_foo, + nt_errstr(status)); + goto out; + } + + /* + * Now we've deleted everything, posix_mkdir, posix_rmdir, + * posix_open, posix_unlink, on + * POSIX_foo/foo should return NT_STATUS_OBJECT_PATH_NOT_FOUND + * not silently create POSIX_foo/foo. + */ + + status = cli_posix_mkdir(cli, fname_foo_foo, 0777); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) { + printf("cli_posix_mkdir of %s should fail with " + "NT_STATUS_OBJECT_PATH_NOT_FOUND got " + "%s instead\n", + fname_foo_foo, + nt_errstr(status)); + goto out; + } + + status = cli_posix_rmdir(cli, fname_foo_foo); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) { + printf("cli_posix_rmdir of %s should fail with " + "NT_STATUS_OBJECT_PATH_NOT_FOUND got " + "%s instead\n", + fname_foo_foo, + nt_errstr(status)); + goto out; + } + + status = cli_posix_open(cli, + fname_foo_foo, + O_RDWR|O_CREAT, + 0666, + &fnum); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) { + printf("cli_posix_open of %s should fail with " + "NT_STATUS_OBJECT_PATH_NOT_FOUND got " + "%s instead\n", + fname_foo_foo, + nt_errstr(status)); + goto out; + } + + status = cli_posix_unlink(cli, fname_foo_foo); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) { + printf("cli_posix_unlink of %s should fail with " + "NT_STATUS_OBJECT_PATH_NOT_FOUND got " + "%s instead\n", + fname_foo_foo, + nt_errstr(status)); + goto out; + } + + status = cli_posix_mkdir(cli, fname_foo, 0777); if (!NT_STATUS_IS_OK(status)) { - printf("POSIX lock (1) failed %s\n", nt_errstr(status)); + printf("cli_posix_mkdir of %s failed\n", fname_foo); goto out; } - /* Set a 60-100 lock on fnum2. */ - status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK); + status = cli_posix_mkdir(cli, fname_Foo, 0777); if (!NT_STATUS_IS_OK(status)) { - printf("POSIX lock (2) failed %s\n", nt_errstr(status)); + printf("cli_posix_mkdir of %s failed\n", fname_Foo); goto out; } - /* close fnum1 - 0-50 lock should go away. */ - status = cli_close(cli, fnum1); + status = cli_posix_mkdir(cli, fname_foo_foo, 0777); if (!NT_STATUS_IS_OK(status)) { - printf("close failed (%s)\n", - nt_errstr(status)); + printf("cli_posix_mkdir of %s failed\n", fname_foo_foo); goto out; } - fnum1 = (uint16_t)-1; - - /* Change the lock context. */ - cli_setpid(cli, cli_getpid(cli) + 1); - /* Re-open fnum1. */ - status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1); + status = cli_posix_mkdir(cli, fname_foo_Foo, 0777); if (!NT_STATUS_IS_OK(status)) { - printf("Third POSIX open of %s failed\n", fname); + printf("cli_posix_mkdir of %s failed\n", fname_foo_Foo); goto out; } - /* 60-100 lock should still be there. */ - status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK); - if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { - printf("POSIX lock 60-100 not there %s\n", nt_errstr(status)); + status = cli_posix_mkdir(cli, fname_Foo_foo, 0777); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_mkdir of %s failed\n", fname_Foo_foo); goto out; } - /* 0-50 lock should be gone. */ - status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK); + status = cli_posix_mkdir(cli, fname_Foo_Foo, 0777); if (!NT_STATUS_IS_OK(status)) { - printf("POSIX lock 0-50 failed %s\n", nt_errstr(status)); + printf("cli_posix_mkdir of %s failed\n", fname_Foo_Foo); goto out; } - printf("POSIX OFD lock test passed\n"); + printf("POSIX mkdir test passed\n"); correct = true; out: - if (fnum1 != (uint16_t)-1) { - cli_close(cli, fnum1); - fnum1 = (uint16_t)-1; - } - if (fnum2 != (uint16_t)-1) { - cli_close(cli, fnum2); - fnum2 = (uint16_t)-1; + if (fnum != (uint16_t)-1) { + cli_close(cli, fnum); + fnum = (uint16_t)-1; } - cli_setatr(cli, fname, 0, 0); - cli_posix_unlink(cli, fname); + cli_posix_rmdir(cli, fname_foo_foo); + cli_posix_rmdir(cli, fname_foo_Foo); + cli_posix_rmdir(cli, fname_foo); + + cli_posix_rmdir(cli, fname_Foo_foo); + cli_posix_rmdir(cli, fname_Foo_Foo); + cli_posix_rmdir(cli, fname_Foo); if (!torture_close_connection(cli)) { correct = false; @@ -6310,6 +7456,7 @@ static bool run_posix_ofd_lock_test(int dummy) return correct; } + static uint32_t open_attrs_table[] = { FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, @@ -6970,7 +8117,7 @@ static bool run_error_map_extract(int dummy) { return False; } - status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup); + status = cli_session_setup_anon(c_nt); if (!NT_STATUS_IS_OK(status)) { printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status)); return False; @@ -6997,7 +8144,7 @@ static bool run_error_map_extract(int dummy) { return False; } - status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup); + status = cli_session_setup_anon(c_dos); if (!NT_STATUS_IS_OK(status)) { printf("%s rejected the DOS-error initial session setup (%s)\n", host, nt_errstr(status)); @@ -7008,12 +8155,25 @@ static bool run_error_map_extract(int dummy) { c_dos->map_dos_errors = false; for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) { + struct cli_credentials *user_creds = NULL; + fstr_sprintf(user, "%X", error); - status = cli_session_setup(c_nt, user, - password, strlen(password), - password, strlen(password), - workgroup); + user_creds = cli_session_creds_init(talloc_tos(), + user, + workgroup, + NULL, /* realm */ + password, + false, /* use_kerberos */ + false, /* fallback_after_kerberos */ + false, /* use_ccache */ + false); /* password_is_nt_hash */ + if (user_creds == NULL) { + printf("cli_session_creds_init(%s) failed\n", user); + return false; + } + + status = cli_session_setup_creds(c_nt, user_creds); if (NT_STATUS_IS_OK(status)) { printf("/** Session setup succeeded. This shouldn't happen...*/\n"); } @@ -7027,10 +8187,7 @@ static bool run_error_map_extract(int dummy) { nt_status = NT_STATUS(0xc0000000); } - status = cli_session_setup(c_dos, user, - password, strlen(password), - password, strlen(password), - workgroup); + status = cli_session_setup_creds(c_dos, user_creds); if (NT_STATUS_IS_OK(status)) { printf("/** Session setup succeeded. This shouldn't happen...*/\n"); } @@ -7055,6 +8212,8 @@ static bool run_error_map_extract(int dummy) { smb_dos_err_class(errclass), smb_dos_err_name(errclass, errnum), get_nt_error_c_code(talloc_tos(), NT_STATUS(error))); + + TALLOC_FREE(user_creds); } return True; } @@ -7080,13 +8239,9 @@ static bool run_sesssetup_bench(int dummy) } for (i=0; iconn, sockops); - reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test", + cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, fname, O_CREAT|O_RDWR, 0, &smbreqs[0]); if (reqs[0] == NULL) return false; tevent_req_set_callback(reqs[0], chain1_open_completion, NULL); @@ -7188,7 +8346,7 @@ static bool run_chain1(int dummy) if (reqs[1] == NULL) return false; tevent_req_set_callback(reqs[1], chain1_write_completion, NULL); - reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]); + reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]); if (reqs[2] == NULL) return false; tevent_req_set_callback(reqs[2], chain1_close_completion, &done); @@ -7228,10 +8386,11 @@ static bool run_chain2(int dummy) struct tevent_req *reqs[2], *smbreqs[2]; bool done = false; NTSTATUS status; + int flags = CLI_FULL_CONNECTION_FORCE_SMB1; printf("starting chain2 test\n"); status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL, - port_to_use, SMB_SIGNING_DEFAULT, 0); + port_to_use, SMB_SIGNING_DEFAULT, flags); if (!NT_STATUS_IS_OK(status)) { return False; } @@ -7291,7 +8450,8 @@ static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, - FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0); + FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, + SMB2_IMPERSONATION_IMPERSONATION, 0); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); @@ -7716,6 +8876,152 @@ static bool run_mangle1(int dummy) return true; } +static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint, + struct file_info *f, + const char *mask, + void *state) +{ + if (f->short_name == NULL) { + return NT_STATUS_OK; + } + + if (strlen(f->short_name) == 0) { + return NT_STATUS_OK; + } + + printf("unexpected shortname: %s\n", f->short_name); + + return NT_STATUS_OBJECT_NAME_INVALID; +} + +static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint, + struct file_info *f, + const char *mask, + void *state) +{ + char *name = state; + + printf("name: %s\n", f->name); + fstrcpy(name, f->name); + return NT_STATUS_OK; +} + +static bool run_mangle_illegal(int dummy) +{ + struct cli_state *cli = NULL; + struct cli_state *cli_posix = NULL; + const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt"; + const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar"; + char *mangled_path = NULL; + uint16_t fnum; + fstring name; + fstring alt_name; + NTSTATUS status; + + printf("starting mangle-illegal test\n"); + + if (!torture_open_connection(&cli, 0)) { + return False; + } + + smbXcli_conn_set_sockopt(cli->conn, sockops); + + if (!torture_open_connection(&cli_posix, 0)) { + return false; + } + + smbXcli_conn_set_sockopt(cli_posix->conn, sockops); + + status = torture_setup_unix_extensions(cli_posix); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + + cli_rmdir(cli, "\\MANGLE_ILLEGAL"); + status = cli_mkdir(cli, "\\MANGLE_ILLEGAL"); + if (!NT_STATUS_IS_OK(status)) { + printf("mkdir1 failed : %s\n", nt_errstr(status)); + return False; + } + + /* + * Create a file with illegal NTFS characters and test that we + * get a usable mangled name + */ + + cli_setatr(cli_posix, illegal_fname, 0, 0); + cli_posix_unlink(cli_posix, illegal_fname); + + status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL, + 0600, &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("POSIX create of %s failed (%s)\n", + illegal_fname, nt_errstr(status)); + return false; + } + + status = cli_close(cli_posix, fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("close failed (%s)\n", nt_errstr(status)); + return false; + } + + status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name); + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_list failed: %s\n", nt_errstr(status)); + return false; + } + + mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name); + if (mangled_path == NULL) { + return false; + } + + status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum); + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status)); + TALLOC_FREE(mangled_path); + return false; + } + TALLOC_FREE(mangled_path); + cli_close(cli, fnum); + + cli_setatr(cli_posix, illegal_fname, 0, 0); + cli_posix_unlink(cli_posix, illegal_fname); + + /* + * Create a file with a long name and check that we got *no* short name. + */ + + status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, + FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, + 0, 0, &fnum, NULL); + if (!NT_STATUS_IS_OK(status)) { + d_printf("open %s failed: %s\n", fname, nt_errstr(status)); + return false; + } + cli_close(cli, fnum); + + status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name); + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_list failed\n"); + return false; + } + + cli_unlink(cli, fname, 0); + cli_rmdir(cli, "\\MANGLE_ILLEGAL"); + + if (!torture_close_connection(cli_posix)) { + return false; + } + + if (!torture_close_connection(cli)) { + return false; + } + + return true; +} + static size_t null_source(uint8_t *buf, size_t n, void *priv) { size_t *to_pull = (size_t *)priv; @@ -8020,13 +9326,7 @@ static bool run_large_readx(int dummy) goto out; } - status = cli_session_setup(cli2, - username, - password, - strlen(password)+1, - password, - strlen(password)+1, - workgroup); + status = cli_session_setup_creds(cli2, torture_creds); if (!NT_STATUS_IS_OK(status)) { goto out; } @@ -8034,8 +9334,7 @@ static bool run_large_readx(int dummy) status = cli_tree_connect(cli2, share, "?????", - password, - strlen(password)+1); + password); if (!NT_STATUS_IS_OK(status)) { goto out; } @@ -8105,55 +9404,207 @@ static bool run_large_readx(int dummy) if (cli1) { if (fnum1 != UINT16_MAX) { - status = cli_close(cli1, fnum1); - if (!NT_STATUS_IS_OK(status)) { - d_printf("cli_close failed: %s\n", nt_errstr(status)); - } - fnum1 = UINT16_MAX; + status = cli_close(cli1, fnum1); + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_close failed: %s\n", nt_errstr(status)); + } + fnum1 = UINT16_MAX; + } + + status = cli_unlink(cli1, fname, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + if (!NT_STATUS_IS_OK(status)) { + printf("unlink failed (%s)\n", nt_errstr(status)); + } + + if (!torture_close_connection(cli1)) { + correct = false; + } + } + + TALLOC_FREE(frame); + + printf("finished large_readx test\n"); + return correct; +} + +static bool run_cli_echo(int dummy) +{ + struct cli_state *cli; + NTSTATUS status; + + printf("starting cli_echo test\n"); + if (!torture_open_connection(&cli, 0)) { + return false; + } + smbXcli_conn_set_sockopt(cli->conn, sockops); + + status = cli_echo(cli, 5, data_blob_const("hello", 5)); + + d_printf("cli_echo returned %s\n", nt_errstr(status)); + + torture_close_connection(cli); + return NT_STATUS_IS_OK(status); +} + +static int splice_status(off_t written, void *priv) +{ + return true; +} + +static bool run_cli_splice(int dummy) +{ + uint8_t *buf = NULL; + struct cli_state *cli1 = NULL; + bool correct = false; + const char *fname_src = "\\splice_src.dat"; + const char *fname_dst = "\\splice_dst.dat"; + NTSTATUS status; + uint16_t fnum1 = UINT16_MAX; + uint16_t fnum2 = UINT16_MAX; + size_t file_size = 2*1024*1024; + size_t splice_size = 1*1024*1024 + 713; + MD5_CTX md5_ctx; + uint8_t digest1[16], digest2[16]; + off_t written = 0; + size_t nread = 0; + TALLOC_CTX *frame = talloc_stackframe(); + + printf("starting cli_splice test\n"); + + if (!torture_open_connection(&cli1, 0)) { + goto out; + } + + cli_unlink(cli1, fname_src, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_unlink(cli1, fname_dst, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + /* Create a file */ + status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS, + FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, + 0, 0, &fnum1, NULL); + + if (!NT_STATUS_IS_OK(status)) { + d_printf("open %s failed: %s\n", fname_src, nt_errstr(status)); + goto out; + } + + /* Write file_size bytes - must be bigger than splice_size. */ + buf = talloc_zero_array(frame, uint8_t, file_size); + if (buf == NULL) { + d_printf("talloc_fail\n"); + goto out; + } + + /* Fill it with random numbers. */ + generate_random_buffer(buf, file_size); + + /* MD5 the first 1MB + 713 bytes. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, buf, splice_size); + MD5Final(digest1, &md5_ctx); + + status = cli_writeall(cli1, + fnum1, + 0, + buf, + 0, + file_size, + NULL); + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_writeall failed: %s\n", nt_errstr(status)); + goto out; + } + + status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS, + FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, + 0, 0, &fnum2, NULL); + + if (!NT_STATUS_IS_OK(status)) { + d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status)); + goto out; + } + + /* Now splice 1MB + 713 bytes. */ + status = cli_splice(cli1, + cli1, + fnum1, + fnum2, + splice_size, + 0, + 0, + &written, + splice_status, + NULL); + + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_splice failed: %s\n", nt_errstr(status)); + goto out; + } + + /* Clear the old buffer. */ + memset(buf, '\0', file_size); + + /* Read the new file. */ + status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread); + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_read failed: %s\n", nt_errstr(status)); + goto out; + } + if (nread != splice_size) { + d_printf("bad read of 0x%x, should be 0x%x\n", + (unsigned int)nread, + (unsigned int)splice_size); + goto out; + } + + /* MD5 the first 1MB + 713 bytes. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, buf, splice_size); + MD5Final(digest2, &md5_ctx); + + /* Must be the same. */ + if (memcmp(digest1, digest2, 16) != 0) { + d_printf("bad MD5 compare\n"); + goto out; + } + + correct = true; + printf("Success on cli_splice test\n"); + + out: + + if (cli1) { + if (fnum1 != UINT16_MAX) { + cli_close(cli1, fnum1); } - - status = cli_unlink(cli1, fname, - FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); - if (!NT_STATUS_IS_OK(status)) { - printf("unlink failed (%s)\n", nt_errstr(status)); + if (fnum2 != UINT16_MAX) { + cli_close(cli1, fnum2); } + cli_unlink(cli1, fname_src, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_unlink(cli1, fname_dst, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + if (!torture_close_connection(cli1)) { correct = false; } } TALLOC_FREE(frame); - - printf("finished large_readx test\n"); return correct; } -static bool run_cli_echo(int dummy) -{ - struct cli_state *cli; - NTSTATUS status; - - printf("starting cli_echo test\n"); - if (!torture_open_connection(&cli, 0)) { - return false; - } - smbXcli_conn_set_sockopt(cli->conn, sockops); - - status = cli_echo(cli, 5, data_blob_const("hello", 5)); - - d_printf("cli_echo returned %s\n", nt_errstr(status)); - - torture_close_connection(cli); - return NT_STATUS_IS_OK(status); -} - static bool run_uid_regression_test(int dummy) { static struct cli_state *cli; int16_t old_vuid; - int16_t old_cnum; + int32_t old_cnum; bool correct = True; + struct smbXcli_tcon *orig_tcon = NULL; NTSTATUS status; printf("starting uid regression test\n"); @@ -8194,6 +9645,11 @@ static bool run_uid_regression_test(int dummy) } old_cnum = cli_state_get_tid(cli); + orig_tcon = cli_state_save_tcon(cli); + if (orig_tcon == NULL) { + correct = false; + goto out; + } /* Now try a SMBtdis with the invald vuid set to zero. */ cli_state_set_uid(cli, 0); @@ -8206,9 +9662,11 @@ static bool run_uid_regression_test(int dummy) } else { d_printf("First tdis failed (%s)\n", nt_errstr(status)); correct = false; + cli_state_restore_tcon(cli, orig_tcon); goto out; } + cli_state_restore_tcon(cli, orig_tcon); cli_state_set_uid(cli, old_vuid); cli_state_set_tid(cli, old_cnum); @@ -8459,167 +9917,473 @@ static bool run_tldap(int dummy) d_printf("no defaultNamingContext\n"); return false; } - d_printf("defaultNamingContext: %s\n", basedn); + d_printf("defaultNamingContext: %s\n", basedn); + + ev = samba_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); + + /* 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); + if (!TLDAP_RC_IS_SUCCESS(rc)) { + 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_createtime"; + const char *fname = "\\testdir_createtime\\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, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + 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_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL, + DENY_NONE, &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_openx 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, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_rmdir(cli, dname); + if (!torture_close_connection(cli)) { + ret = false; + } + return ret; +} + + +static bool run_streamerror(int dummy) +{ + struct cli_state *cli; + const char *dname = "\\testdir_streamerror"; + const char *streamname = + "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA"; + NTSTATUS status; + time_t change_time, access_time, write_time; + off_t size; + uint16_t mode, fnum; + bool ret = true; + + if (!torture_open_connection(&cli, 0)) { + return false; + } + + cli_unlink(cli, "\\testdir_streamerror\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + 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; + } + + status = cli_qpathinfo1(cli, streamname, &change_time, &access_time, + &write_time, &size, &mode); + 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, NULL); + + 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; +} + +struct pidtest_state { + bool success; + uint16_t vwv[1]; + DATA_BLOB data; +}; + +static void pid_echo_done(struct tevent_req *subreq); + +static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli) +{ + struct tevent_req *req, *subreq; + struct pidtest_state *state; + + req = tevent_req_create(mem_ctx, &state, struct pidtest_state); + if (req == NULL) { + return NULL; + } + + SSVAL(state->vwv, 0, 1); + state->data = data_blob_const("hello", 5); + + subreq = smb1cli_req_send(state, + ev, + cli->conn, + SMBecho, + 0, 0, /* *_flags */ + 0, 0, /* *_flags2 */ + cli->timeout, + 0xDEADBEEF, /* pid */ + NULL, /* tcon */ + NULL, /* session */ + ARRAY_SIZE(state->vwv), state->vwv, + state->data.length, state->data.data); + + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, pid_echo_done, req); + return req; +} + +static void pid_echo_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct pidtest_state *state = tevent_req_data( + req, struct pidtest_state); + NTSTATUS status; + uint32_t num_bytes; + uint8_t *bytes = NULL; + struct iovec *recv_iov = NULL; + uint8_t *phdr = NULL; + uint16_t pidlow = 0; + uint16_t pidhigh = 0; + struct smb1cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .wct = 1, + }, + }; + + status = smb1cli_req_recv(subreq, state, + &recv_iov, + &phdr, + NULL, /* pwct */ + NULL, /* pvwv */ + NULL, /* pvwv_offset */ + &num_bytes, + &bytes, + NULL, /* pbytes_offset */ + NULL, /* pinbuf */ + expected, ARRAY_SIZE(expected)); + + TALLOC_FREE(subreq); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + + if (num_bytes != state->data.length) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + if (memcmp(bytes, state->data.data, num_bytes) != 0) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + /* Check pid low/high == DEADBEEF */ + pidlow = SVAL(phdr, HDR_PID); + if (pidlow != 0xBEEF){ + printf("Incorrect pidlow 0x%x, should be 0xBEEF\n", + (unsigned int)pidlow); + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + pidhigh = SVAL(phdr, HDR_PIDHIGH); + if (pidhigh != 0xDEAD){ + printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n", + (unsigned int)pidhigh); + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + tevent_req_done(req); +} + +static NTSTATUS pid_echo_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +static bool run_pidhigh(int dummy) +{ + bool success = false; + struct cli_state *cli = NULL; + NTSTATUS status; + struct tevent_context *ev = NULL; + struct tevent_req *req = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + printf("starting pid high test\n"); + if (!torture_open_connection(&cli, 0)) { + return false; + } + smbXcli_conn_set_sockopt(cli->conn, sockops); - ev = samba_tevent_context_init(talloc_tos()); + ev = samba_tevent_context_init(frame); if (ev == NULL) { - d_printf("tevent_context_init failed\n"); - return false; + goto fail; } - 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); + req = pid_echo_send(frame, ev, cli); if (req == NULL) { - d_printf("tldap_search_paged_send failed\n"); - return false; + goto fail; } - tevent_req_set_callback(req, pagedsearch_cb, NULL); - - tevent_req_poll(req, ev); - 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))))"; + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } - rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter, - NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0, - talloc_tos(), NULL); - if (!TLDAP_RC_IS_SUCCESS(rc)) { - d_printf("tldap_search with complex filter failed: %s\n", - tldap_errstr(talloc_tos(), ld, rc)); - return false; + status = pid_echo_recv(req); + if (NT_STATUS_IS_OK(status)) { + printf("pid high test ok\n"); + success = true; } - TALLOC_FREE(ld); - return true; -} + fail: -/* Torture test to ensure no regression of : -https://bugzilla.samba.org/show_bug.cgi?id=7084 -*/ + TALLOC_FREE(frame); + torture_close_connection(cli); + return success; +} -static bool run_dir_createtime(int dummy) +/* + Test Windows open on a bad POSIX symlink. + */ +static bool run_symlink_open_test(int dummy) { - struct cli_state *cli; - const char *dname = "\\testdir"; - const char *fname = "\\testdir\\testfile"; + static struct cli_state *cli; + const char *fname = "non_existant_file"; + const char *sname = "dangling_symlink"; + uint16_t fnum = (uint16_t)-1; + bool correct = false; NTSTATUS status; - struct timespec create_time; - struct timespec create_time1; - uint16_t fnum; - bool ret = false; + TALLOC_CTX *frame = NULL; + + frame = talloc_stackframe(); + + printf("Starting Windows bad symlink open test\n"); if (!torture_open_connection(&cli, 0)) { + TALLOC_FREE(frame); return false; } - cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); - cli_rmdir(cli, dname); + smbXcli_conn_set_sockopt(cli->conn, sockops); - status = cli_mkdir(cli, dname); + status = torture_setup_unix_extensions(cli); if (!NT_STATUS_IS_OK(status)) { - printf("mkdir failed: %s\n", nt_errstr(status)); - goto out; + TALLOC_FREE(frame); + return false; } - status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL, - NULL, NULL, NULL); + /* Ensure nothing exists. */ + cli_setatr(cli, fname, 0, 0); + cli_posix_unlink(cli, fname); + cli_setatr(cli, sname, 0, 0); + cli_posix_unlink(cli, sname); + + /* Create a symlink pointing nowhere. */ + status = cli_posix_symlink(cli, fname, sname); if (!NT_STATUS_IS_OK(status)) { - printf("cli_qpathinfo2 returned %s\n", - nt_errstr(status)); + printf("cli_posix_symlink of %s -> %s failed (%s)\n", + sname, + fname, + nt_errstr(status)); goto out; } - /* Sleep 3 seconds, then create a file. */ - sleep(3); + /* Now ensure that a Windows open doesn't hang. */ + status = cli_ntcreate(cli, + sname, + 0, + FILE_READ_DATA|FILE_WRITE_DATA, + 0, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_OPEN_IF, + 0x0, + 0x0, + &fnum, + NULL); - status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL, - DENY_NONE, &fnum); - if (!NT_STATUS_IS_OK(status)) { - printf("cli_openx failed: %s\n", nt_errstr(status)); + /* + * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or + * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if + * we use O_NOFOLLOW on the server or not. + */ + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) || + NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) + { + correct = true; + } else { + printf("cli_ntcreate of %s returned %s - should return" + " either (%s) or (%s)\n", + sname, + nt_errstr(status), + nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND), + nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND)); 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; - } + correct = true; - 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: + + if (fnum != (uint16_t)-1) { + cli_close(cli, fnum); + fnum = (uint16_t)-1; } - out: + cli_setatr(cli, sname, 0, 0); + cli_posix_unlink(cli, sname); + cli_setatr(cli, fname, 0, 0); + cli_posix_unlink(cli, fname); - cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); - cli_rmdir(cli, dname); if (!torture_close_connection(cli)) { - ret = false; + correct = false; } - return ret; + + TALLOC_FREE(frame); + return correct; } +/* + * Only testing minimal time strings, as the others + * need (locale-dependent) guessing at what strftime does and + * even may differ in builds. + */ +static bool timesubst_test(void) +{ + TALLOC_CTX *ctx = NULL; + /* Sa 23. Dez 04:33:20 CET 2017 */ + const struct timeval tv = { 1514000000, 123 }; + const char* expect_minimal = "20171223_033320"; + const char* expect_minus = "20171223_033320_000123"; + char *s; + char *env_tz, *orig_tz = NULL; + bool result = 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; - off_t size; - uint16_t mode, fnum; - bool ret = true; + ctx = talloc_new(NULL); - if (!torture_open_connection(&cli, 0)) { - return false; + env_tz = getenv("TZ"); + if(env_tz) { + orig_tz = talloc_strdup(ctx, env_tz); } + setenv("TZ", "UTC", 1); - cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); - cli_rmdir(cli, dname); + s = minimal_timeval_string(ctx, &tv, false); - status = cli_mkdir(cli, dname); - if (!NT_STATUS_IS_OK(status)) { - printf("mkdir failed: %s\n", nt_errstr(status)); - return false; + if(!s || strcmp(s, expect_minimal)) { + printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected " + "[%s]\n", s ? s : "", expect_minimal); + result = false; } - - status = cli_qpathinfo1(cli, streamname, &change_time, &access_time, - &write_time, &size, &mode); - 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; + TALLOC_FREE(s); + s = minimal_timeval_string(ctx, &tv, true); + if(!s || strcmp(s, expect_minus)) { + printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected " + "[%s]\n", s ? s : "", expect_minus); + result = false; } + TALLOC_FREE(s); - 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, NULL); - - 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; + if(orig_tz) { + setenv("TZ", orig_tz, 1); } - - cli_rmdir(cli, dname); - return ret; + TALLOC_FREE(ctx); + return result; } static bool run_local_substitute(int dummy) @@ -8634,6 +10398,10 @@ static bool run_local_substitute(int dummy) ok &= subst_test("%G", "", "", -1, 0, gidtoname(0)); ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu"); ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0"); + ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0"); + /* Substitution depends on current time, so better test the underlying + formatting function. At least covers %t. */ + ok &= timesubst_test(); /* Different captialization rules in sub_basic... */ @@ -8676,7 +10444,9 @@ static bool run_local_base64(int dummy) return ret; } -static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data) +static void parse_fn(const struct gencache_timeout *t, + DATA_BLOB blob, + void *private_data) { return; } @@ -8750,7 +10520,7 @@ static bool run_local_gencache(int dummy) blob = data_blob_string_const_null("bar"); tm = time(NULL) + 60; - if (!gencache_set_data_blob("foo", &blob, tm)) { + if (!gencache_set_data_blob("foo", blob, tm)) { d_printf("%s: gencache_set_data_blob() failed\n", __location__); return False; } @@ -8789,7 +10559,7 @@ static bool run_local_gencache(int dummy) blob.data = (uint8_t *)&v; blob.length = sizeof(v); - if (!gencache_set_data_blob("blob", &blob, tm)) { + if (!gencache_set_data_blob("blob", blob, tm)) { d_printf("%s: gencache_set_data_blob() failed\n", __location__); return false; @@ -9030,61 +10800,6 @@ failed: return false; } - -struct talloc_dict_test { - int content; -}; - -static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv) -{ - int *count = (int *)priv; - *count += 1; - return 0; -} - -static bool run_local_talloc_dict(int dummy) -{ - struct talloc_dict *dict; - struct talloc_dict_test *t; - int key, count, res; - bool ok; - - dict = talloc_dict_init(talloc_tos()); - if (dict == NULL) { - return false; - } - - t = talloc(talloc_tos(), struct talloc_dict_test); - if (t == NULL) { - return false; - } - - key = 1; - t->content = 1; - ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t); - if (!ok) { - return false; - } - - count = 0; - res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count); - if (res == -1) { - return false; - } - - if (count != 1) { - return false; - } - - if (count != res) { - return false; - } - - TALLOC_FREE(dict); - - return true; -} - static bool run_local_string_to_sid(int dummy) { struct dom_sid sid; @@ -9125,8 +10840,9 @@ static bool run_local_string_to_sid(int dummy) { return false; } if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) { + struct dom_sid_buf buf; printf("mis-parsed S-1-5-32-545 as %s\n", - sid_string_tos(&sid)); + dom_sid_str_buf(&sid, &buf)); return false; } return true; @@ -9162,6 +10878,7 @@ static bool run_local_sid_to_string(int dummy) { } static bool run_local_binary_to_sid(int dummy) { + struct sid_parse_ret ret; struct dom_sid *sid = talloc(NULL, struct dom_sid); static const uint8_t good_binary_sid[] = { 0x1, /* revision number */ @@ -9246,13 +10963,16 @@ static bool run_local_binary_to_sid(int dummy) { 0x1, 0x1, 0x1, 0x1, /* auth[31] */ }; - if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) { + ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid); + if (ret.len == -1) { return false; } - if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) { + ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid); + if (ret.len != -1) { return false; } - if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) { + ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid); + if (ret.len != -1) { return false; } return true; @@ -9433,15 +11153,25 @@ static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b) static bool run_local_memcache(int dummy) { struct memcache *cache; - DATA_BLOB k1, k2; - DATA_BLOB d1, d2, d3; - DATA_BLOB v1, v2, v3; + DATA_BLOB k1, k2, k3; + DATA_BLOB d1, d3; + DATA_BLOB v1, v3; TALLOC_CTX *mem_ctx; + char *ptr1 = NULL; + char *ptr2 = NULL; + char *str1, *str2; size_t size1, size2; bool ret = false; + mem_ctx = talloc_init("foo"); + if (mem_ctx == NULL) { + return false; + } + + /* STAT_CACHE TESTS */ + cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100); if (cache == NULL) { @@ -9450,14 +11180,13 @@ static bool run_local_memcache(int dummy) } d1 = data_blob_const("d1", 2); - d2 = data_blob_const("d2", 2); d3 = data_blob_const("d3", 2); k1 = data_blob_const("d1", 2); k2 = data_blob_const("d2", 2); + k3 = data_blob_const("d3", 2); memcache_add(cache, STAT_CACHE, k1, d1); - memcache_add(cache, GETWD_CACHE, k2, d2); if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) { printf("could not find k1\n"); @@ -9467,40 +11196,79 @@ static bool run_local_memcache(int dummy) return false; } - if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) { - printf("could not find k2\n"); + memcache_add(cache, STAT_CACHE, k1, d3); + + if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) { + printf("could not find replaced k1\n"); + return false; + } + if (!data_blob_equal(d3, v3)) { return false; } - if (!data_blob_equal(d2, v2)) { + + TALLOC_FREE(cache); + + /* GETWD_CACHE TESTS */ + str1 = talloc_strdup(mem_ctx, "string1"); + if (str1 == NULL) { return false; } + ptr2 = str1; /* Keep an alias for comparison. */ - memcache_add(cache, STAT_CACHE, k1, d3); + str2 = talloc_strdup(mem_ctx, "string2"); + if (str2 == NULL) { + return false; + } - if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) { - printf("could not find replaced k1\n"); + cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100); + if (cache == NULL) { + printf("memcache_init failed\n"); return false; } - if (!data_blob_equal(d3, v3)) { + + memcache_add_talloc(cache, GETWD_CACHE, k2, &str1); + /* str1 == NULL now. */ + ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2); + if (ptr1 == NULL) { + printf("could not find k2\n"); + return false; + } + if (ptr1 != ptr2) { + printf("fetch of k2 got wrong string\n"); return false; } - memcache_add(cache, GETWD_CACHE, k1, d1); + /* Add a blob to ensure k2 gets purged. */ + d3 = data_blob_talloc_zero(mem_ctx, 180); + memcache_add(cache, STAT_CACHE, k3, d3); - if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) { + ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2); + if (ptr2 != NULL) { printf("Did find k2, should have been purged\n"); return false; } TALLOC_FREE(cache); - - cache = memcache_init(NULL, 0); + TALLOC_FREE(mem_ctx); mem_ctx = talloc_init("foo"); + if (mem_ctx == NULL) { + return false; + } + + cache = memcache_init(NULL, 0); + if (cache == NULL) { + return false; + } str1 = talloc_strdup(mem_ctx, "string1"); + if (str1 == NULL) { + return false; + } str2 = talloc_strdup(mem_ctx, "string2"); - + if (str2 == NULL) { + return false; + } memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC, data_blob_string_const("torture"), &str1); size1 = talloc_total_size(cache); @@ -9587,59 +11355,6 @@ static bool run_wbclient_multi_ping(int dummy) return result; } -static void getaddrinfo_finished(struct tevent_req *req) -{ - char *name = (char *)tevent_req_callback_data_void(req); - struct addrinfo *ainfo; - int res; - - res = getaddrinfo_recv(req, &ainfo); - if (res != 0) { - d_printf("gai(%s) returned %s\n", name, gai_strerror(res)); - return; - } - d_printf("gai(%s) succeeded\n", name); - freeaddrinfo(ainfo); -} - -static bool run_getaddrinfo_send(int dummy) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct fncall_context *ctx; - struct tevent_context *ev; - bool result = false; - const char *names[4] = { "www.samba.org", "notfound.samba.org", - "www.slashdot.org", "heise.de" }; - struct tevent_req *reqs[4]; - int i; - - ev = samba_tevent_context_init(frame); - if (ev == NULL) { - goto fail; - } - - ctx = fncall_context_init(frame, 4); - - for (i=0; i %s != %s", + src[i], d, dst[i]); + return false; + } + talloc_free(d); + } + return true; +} + +static bool run_ign_bad_negprot(int dummy) +{ + struct tevent_context *ev; + struct tevent_req *req; + struct smbXcli_conn *conn; + struct sockaddr_storage ss; + NTSTATUS status; + int fd; + bool ok; + + printf("starting ignore bad negprot\n"); + + ok = resolve_name(host, &ss, 0x20, true); + if (!ok) { + d_fprintf(stderr, "Could not resolve name %s\n", host); + return false; + } + + status = open_socket_out(&ss, 445, 10000, &fd); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "open_socket_out failed: %s\n", + nt_errstr(status)); + return false; + } + + conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0, + NULL, 0); + if (conn == NULL) { + d_fprintf(stderr, "smbXcli_conn_create failed\n"); + return false; + } + + status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE); + if (NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "smbXcli_negprot succeeded!\n"); + return false; + } + + ev = samba_tevent_context_init(talloc_tos()); + if (ev == NULL) { + d_fprintf(stderr, "samba_tevent_context_init failed\n"); + return false; + } + + req = smb1cli_session_setup_nt1_send( + ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "", + data_blob_null, data_blob_null, 0x40, + "Windows 2000 2195", "Windows 2000 5.0"); + if (req == NULL) { + d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n"); + return false; + } + + ok = tevent_req_poll_ntstatus(req, ev, &status); + if (!ok) { + d_fprintf(stderr, "tevent_req_poll failed\n"); + return false; + } + + status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL, + NULL, NULL); + if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) { + d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned " + "%s, expected NT_STATUS_CONNECTION_RESET\n", + nt_errstr(status)); + return false; + } + + TALLOC_FREE(conn); + + printf("starting ignore bad negprot\n"); + + return true; +} + static double create_procs(bool (*fn)(int), bool *result) { int i, status; @@ -10100,146 +11933,627 @@ static struct { bool (*fn)(int); unsigned flags; } torture_ops[] = { - {"FDPASS", run_fdpasstest, 0}, - {"LOCK1", run_locktest1, 0}, - {"LOCK2", run_locktest2, 0}, - {"LOCK3", run_locktest3, 0}, - {"LOCK4", run_locktest4, 0}, - {"LOCK5", run_locktest5, 0}, - {"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}, - {"TRANS2", run_trans2test, 0}, - {"MAXFID", run_maxfidtest, FLAG_MULTIPROC}, - {"TORTURE",run_torture, FLAG_MULTIPROC}, - {"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}, - {"OPLOCK4", run_oplock4, 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}, - {"TCONDEV", run_tcon_devtype_test, 0}, - {"RW1", run_readwritetest, 0}, - {"RW2", run_readwritemulti, FLAG_MULTIPROC}, - {"RW3", run_readwritelarge, 0}, - {"RW-SIGNING", run_readwritelarge_signtest, 0}, - {"OPEN", run_opentest, 0}, - {"POSIX", run_simple_posix_open_test, 0}, - {"POSIX-APPEND", run_posix_append, 0}, - {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0}, - {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0}, - {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0}, - {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0}, - {"ASYNC-ECHO", run_async_echo, 0}, - { "UID-REGRESSION-TEST", run_uid_regression_test, 0}, - { "SHORTNAME-TEST", run_shortname_test, 0}, - { "ADDRCHANGE", run_addrchange, 0}, + { + .name = "FDPASS", + .fn = run_fdpasstest, + }, + { + .name = "LOCK1", + .fn = run_locktest1, + }, + { + .name = "LOCK2", + .fn = run_locktest2, + }, + { + .name = "LOCK3", + .fn = run_locktest3, + }, + { + .name = "LOCK4", + .fn = run_locktest4, + }, + { + .name = "LOCK5", + .fn = run_locktest5, + }, + { + .name = "LOCK6", + .fn = run_locktest6, + }, + { + .name = "LOCK7", + .fn = run_locktest7, + }, + { + .name = "LOCK8", + .fn = run_locktest8, + }, + { + .name = "LOCK9", + .fn = run_locktest9, + }, + { + .name = "UNLINK", + .fn = run_unlinktest, + }, + { + .name = "BROWSE", + .fn = run_browsetest, + }, + { + .name = "ATTR", + .fn = run_attrtest, + }, + { + .name = "TRANS2", + .fn = run_trans2test, + }, + { + .name = "MAXFID", + .fn = run_maxfidtest, + .flags = FLAG_MULTIPROC, + }, + { + .name = "TORTURE", + .fn = run_torture, + .flags = FLAG_MULTIPROC, + }, + { + .name = "RANDOMIPC", + .fn = run_randomipc, + }, + { + .name = "NEGNOWAIT", + .fn = run_negprot_nowait, + }, + { + .name = "NBENCH", + .fn = run_nbench, + }, + { + .name = "NBENCH2", + .fn = run_nbench2, + }, + { + .name = "OPLOCK1", + .fn = run_oplock1, + }, + { + .name = "OPLOCK2", + .fn = run_oplock2, + }, + { + .name = "OPLOCK4", + .fn = run_oplock4, + }, + { + .name = "DIR", + .fn = run_dirtest, + }, + { + .name = "DIR1", + .fn = run_dirtest1, + }, + { + .name = "DIR-CREATETIME", + .fn = run_dir_createtime, + }, + { + .name = "DENY1", + .fn = torture_denytest1, + }, + { + .name = "DENY2", + .fn = torture_denytest2, + }, + { + .name = "TCON", + .fn = run_tcon_test, + }, + { + .name = "TCONDEV", + .fn = run_tcon_devtype_test, + }, + { + .name = "RW1", + .fn = run_readwritetest, + }, + { + .name = "RW2", + .fn = run_readwritemulti, + .flags = FLAG_MULTIPROC + }, + { + .name = "RW3", + .fn = run_readwritelarge, + }, + { + .name = "RW-SIGNING", + .fn = run_readwritelarge_signtest, + }, + { + .name = "OPEN", + .fn = run_opentest, + }, + { + .name = "POSIX", + .fn = run_simple_posix_open_test, + }, + { + .name = "POSIX-APPEND", + .fn = run_posix_append, + }, + { + .name = "POSIX-SYMLINK-ACL", + .fn = run_acl_symlink_test, + }, + { + .name = "POSIX-SYMLINK-EA", + .fn = run_ea_symlink_test, + }, + { + .name = "POSIX-STREAM-DELETE", + .fn = run_posix_stream_delete, + }, + { + .name = "POSIX-OFD-LOCK", + .fn = run_posix_ofd_lock_test, + }, + { + .name = "POSIX-MKDIR", + .fn = run_posix_mkdir_test, + }, + { + .name = "WINDOWS-BAD-SYMLINK", + .fn = run_symlink_open_test, + }, + { + .name = "CASE-INSENSITIVE-CREATE", + .fn = run_case_insensitive_create, + }, + { + .name = "ASYNC-ECHO", + .fn = run_async_echo, + }, + { + .name = "UID-REGRESSION-TEST", + .fn = run_uid_regression_test, + }, + { + .name = "SHORTNAME-TEST", + .fn = run_shortname_test, + }, + { + .name = "ADDRCHANGE", + .fn = run_addrchange, + }, #if 1 - {"OPENATTR", run_openattrtest, 0}, + { + .name = "OPENATTR", + .fn = run_openattrtest, + }, #endif - {"XCOPY", run_xcopy, 0}, - {"RENAME", run_rename, 0}, - {"DELETE", run_deletetest, 0}, - {"WILDDELETE", run_wild_deletetest, 0}, - {"DELETE-LN", run_deletetest_ln, 0}, - {"PROPERTIES", run_properties, 0}, - {"MANGLE", torture_mangle, 0}, - {"MANGLE1", run_mangle1, 0}, - {"W2K", run_w2ktest, 0}, - {"TRANS2SCAN", torture_trans2_scan, 0}, - {"NTTRANSSCAN", torture_nttrans_scan, 0}, - {"UTABLE", torture_utable, 0}, - {"CASETABLE", torture_casetable, 0}, - {"ERRMAPEXTRACT", run_error_map_extract, 0}, - {"PIPE_NUMBER", run_pipe_number, 0}, - {"TCON2", run_tcon2_test, 0}, - {"IOCTL", torture_ioctl_test, 0}, - {"CHKPATH", torture_chkpath_test, 0}, - {"FDSESS", run_fdsesstest, 0}, - { "EATEST", run_eatest, 0}, - { "SESSSETUP_BENCH", run_sesssetup_bench, 0}, - { "CHAIN1", run_chain1, 0}, - { "CHAIN2", run_chain2, 0}, - { "CHAIN3", run_chain3, 0}, - { "WINDOWS-WRITE", run_windows_write, 0}, - { "LARGE_READX", run_large_readx, 0}, - { "NTTRANS-CREATE", run_nttrans_create, 0}, - { "NTTRANS-FSCTL", run_nttrans_fsctl, 0}, - { "CLI_ECHO", run_cli_echo, 0}, - { "GETADDRINFO", run_getaddrinfo_send, 0}, - { "TLDAP", run_tldap }, - { "STREAMERROR", run_streamerror }, - { "NOTIFY-BENCH", run_notify_bench }, - { "NOTIFY-BENCH2", run_notify_bench2 }, - { "NOTIFY-BENCH3", run_notify_bench3 }, - { "BAD-NBT-SESSION", run_bad_nbt_session }, - { "SMB-ANY-CONNECT", run_smb_any_connect }, - { "NOTIFY-ONLINE", run_notify_online }, - { "SMB2-BASIC", run_smb2_basic }, - { "SMB2-NEGPROT", run_smb2_negprot }, - { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect }, - { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence }, - { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel }, - { "SMB2-SESSION-REAUTH", run_smb2_session_reauth }, - { "CLEANUP1", run_cleanup1 }, - { "CLEANUP2", run_cleanup2 }, - { "CLEANUP3", run_cleanup3 }, - { "CLEANUP4", run_cleanup4 }, - { "OPLOCK-CANCEL", run_oplock_cancel }, - { "LOCAL-SUBSTITUTE", run_local_substitute, 0}, - { "LOCAL-GENCACHE", run_local_gencache, 0}, - { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0}, - { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 }, - { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 }, - { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 }, - { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 }, - { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 }, - { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 }, - { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 }, - { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 }, - { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 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}, - { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0}, - { "LOCAL-string_to_sid", run_local_string_to_sid, 0}, - { "LOCAL-sid_to_string", run_local_sid_to_string, 0}, - { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0}, - { "LOCAL-DBTRANS", run_local_dbtrans, 0}, - { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0}, - { "LOCAL-CONVERT-STRING", run_local_convert_string, 0}, - { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0}, - { "LOCAL-sprintf_append", run_local_sprintf_append, 0}, - { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0}, - { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0}, - { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0}, - { "local-tdb-opener", run_local_tdb_opener, 0 }, - { "local-tdb-writer", run_local_tdb_writer, 0 }, - { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 }, - { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 }, - { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 }, - {NULL, NULL, 0}}; - -/* - * dummy function to satisfy linker dependency - */ -struct tevent_context *winbind_event_context(void); -struct tevent_context *winbind_event_context(void) -{ - return NULL; -} + { + .name = "XCOPY", + .fn = run_xcopy, + }, + { + .name = "RENAME", + .fn = run_rename, + }, + { + .name = "RENAME-ACCESS", + .fn = run_rename_access, + }, + { + .name = "OWNER-RIGHTS", + .fn = run_owner_rights, + }, + { + .name = "DELETE", + .fn = run_deletetest, + }, + { + .name = "DELETE-PRINT", + .fn = run_delete_print_test, + }, + { + .name = "WILDDELETE", + .fn = run_wild_deletetest, + }, + { + .name = "DELETE-LN", + .fn = run_deletetest_ln, + }, + { + .name = "PROPERTIES", + .fn = run_properties, + }, + { + .name = "MANGLE", + .fn = torture_mangle, + }, + { + .name = "MANGLE1", + .fn = run_mangle1, + }, + { + .name = "MANGLE-ILLEGAL", + .fn = run_mangle_illegal, + }, + { + .name = "W2K", + .fn = run_w2ktest, + }, + { + .name = "TRANS2SCAN", + .fn = torture_trans2_scan, + }, + { + .name = "NTTRANSSCAN", + .fn = torture_nttrans_scan, + }, + { + .name = "UTABLE", + .fn = torture_utable, + }, + { + .name = "CASETABLE", + .fn = torture_casetable, + }, + { + .name = "ERRMAPEXTRACT", + .fn = run_error_map_extract, + }, + { + .name = "PIPE_NUMBER", + .fn = run_pipe_number, + }, + { + .name = "TCON2", + .fn = run_tcon2_test, + }, + { + .name = "IOCTL", + .fn = torture_ioctl_test, + }, + { + .name = "CHKPATH", + .fn = torture_chkpath_test, + }, + { + .name = "FDSESS", + .fn = run_fdsesstest, + }, + { + .name = "EATEST", + .fn = run_eatest, + }, + { + .name = "SESSSETUP_BENCH", + .fn = run_sesssetup_bench, + }, + { + .name = "CHAIN1", + .fn = run_chain1, + }, + { + .name = "CHAIN2", + .fn = run_chain2, + }, + { + .name = "CHAIN3", + .fn = run_chain3, + }, + { + .name = "WINDOWS-WRITE", + .fn = run_windows_write, + }, + { + .name = "LARGE_READX", + .fn = run_large_readx, + }, + { + .name = "NTTRANS-CREATE", + .fn = run_nttrans_create, + }, + { + .name = "NTTRANS-FSCTL", + .fn = run_nttrans_fsctl, + }, + { + .name = "CLI_ECHO", + .fn = run_cli_echo, + }, + { + .name = "CLI_SPLICE", + .fn = run_cli_splice, + }, + { + .name = "TLDAP", + .fn = run_tldap, + }, + { + .name = "STREAMERROR", + .fn = run_streamerror, + }, + { + .name = "NOTIFY-BENCH", + .fn = run_notify_bench, + }, + { + .name = "NOTIFY-BENCH2", + .fn = run_notify_bench2, + }, + { + .name = "NOTIFY-BENCH3", + .fn = run_notify_bench3, + }, + { + .name = "BAD-NBT-SESSION", + .fn = run_bad_nbt_session, + }, + { + .name = "IGN-BAD-NEGPROT", + .fn = run_ign_bad_negprot, + }, + { + .name = "SMB-ANY-CONNECT", + .fn = run_smb_any_connect, + }, + { + .name = "NOTIFY-ONLINE", + .fn = run_notify_online, + }, + { + .name = "SMB2-BASIC", + .fn = run_smb2_basic, + }, + { + .name = "SMB2-NEGPROT", + .fn = run_smb2_negprot, + }, + { + .name = "SMB2-ANONYMOUS", + .fn = run_smb2_anonymous, + }, + { + .name = "SMB2-SESSION-RECONNECT", + .fn = run_smb2_session_reconnect, + }, + { + .name = "SMB2-TCON-DEPENDENCE", + .fn = run_smb2_tcon_dependence, + }, + { + .name = "SMB2-MULTI-CHANNEL", + .fn = run_smb2_multi_channel, + }, + { + .name = "SMB2-SESSION-REAUTH", + .fn = run_smb2_session_reauth, + }, + { + .name = "SMB2-FTRUNCATE", + .fn = run_smb2_ftruncate, + }, + { + .name = "SMB2-DIR-FSYNC", + .fn = run_smb2_dir_fsync, + }, + { + .name = "CLEANUP1", + .fn = run_cleanup1, + }, + { + .name = "CLEANUP2", + .fn = run_cleanup2, + }, + { + .name = "CLEANUP3", + .fn = run_cleanup3, + }, + { + .name = "CLEANUP4", + .fn = run_cleanup4, + }, + { + .name = "OPLOCK-CANCEL", + .fn = run_oplock_cancel, + }, + { + .name = "PIDHIGH", + .fn = run_pidhigh, + }, + { + .name = "LOCAL-SUBSTITUTE", + .fn = run_local_substitute, + }, + { + .name = "LOCAL-GENCACHE", + .fn = run_local_gencache, + }, + { + .name = "LOCAL-DBWRAP-WATCH1", + .fn = run_dbwrap_watch1, + }, + { + .name = "LOCAL-DBWRAP-WATCH2", + .fn = run_dbwrap_watch2, + }, + { + .name = "LOCAL-DBWRAP-DO-LOCKED1", + .fn = run_dbwrap_do_locked1, + }, + { + .name = "LOCAL-MESSAGING-READ1", + .fn = run_messaging_read1, + }, + { + .name = "LOCAL-MESSAGING-READ2", + .fn = run_messaging_read2, + }, + { + .name = "LOCAL-MESSAGING-READ3", + .fn = run_messaging_read3, + }, + { + .name = "LOCAL-MESSAGING-READ4", + .fn = run_messaging_read4, + }, + { + .name = "LOCAL-MESSAGING-FDPASS1", + .fn = run_messaging_fdpass1, + }, + { + .name = "LOCAL-MESSAGING-FDPASS2", + .fn = run_messaging_fdpass2, + }, + { + .name = "LOCAL-MESSAGING-FDPASS2a", + .fn = run_messaging_fdpass2a, + }, + { + .name = "LOCAL-MESSAGING-FDPASS2b", + .fn = run_messaging_fdpass2b, + }, + { + .name = "LOCAL-MESSAGING-SEND-ALL", + .fn = run_messaging_send_all, + }, + { + .name = "LOCAL-BASE64", + .fn = run_local_base64, + }, + { + .name = "LOCAL-RBTREE", + .fn = run_local_rbtree, + }, + { + .name = "LOCAL-MEMCACHE", + .fn = run_local_memcache, + }, + { + .name = "LOCAL-STREAM-NAME", + .fn = run_local_stream_name, + }, + { + .name = "WBCLIENT-MULTI-PING", + .fn = run_wbclient_multi_ping, + }, + { + .name = "LOCAL-string_to_sid", + .fn = run_local_string_to_sid, + }, + { + .name = "LOCAL-sid_to_string", + .fn = run_local_sid_to_string, + }, + { + .name = "LOCAL-binary_to_sid", + .fn = run_local_binary_to_sid, + }, + { + .name = "LOCAL-DBTRANS", + .fn = run_local_dbtrans, + }, + { + .name = "LOCAL-TEVENT-POLL", + .fn = run_local_tevent_poll, + }, + { + .name = "LOCAL-CONVERT-STRING", + .fn = run_local_convert_string, + }, + { + .name = "LOCAL-CONV-AUTH-INFO", + .fn = run_local_conv_auth_info, + }, + { + .name = "LOCAL-hex_encode_buf", + .fn = run_local_hex_encode_buf, + }, + { + .name = "LOCAL-IDMAP-TDB-COMMON", + .fn = run_idmap_tdb_common_test, + }, + { + .name = "LOCAL-remove_duplicate_addrs2", + .fn = run_local_remove_duplicate_addrs2, + }, + { + .name = "local-tdb-opener", + .fn = run_local_tdb_opener, + }, + { + .name = "local-tdb-writer", + .fn = run_local_tdb_writer, + }, + { + .name = "LOCAL-DBWRAP-CTDB", + .fn = run_local_dbwrap_ctdb, + }, + { + .name = "LOCAL-BENCH-PTHREADPOOL", + .fn = run_bench_pthreadpool, + }, + { + .name = "LOCAL-PTHREADPOOL-TEVENT", + .fn = run_pthreadpool_tevent, + }, + { + .name = "LOCAL-G-LOCK1", + .fn = run_g_lock1, + }, + { + .name = "LOCAL-G-LOCK2", + .fn = run_g_lock2, + }, + { + .name = "LOCAL-G-LOCK3", + .fn = run_g_lock3, + }, + { + .name = "LOCAL-G-LOCK4", + .fn = run_g_lock4, + }, + { + .name = "LOCAL-G-LOCK5", + .fn = run_g_lock5, + }, + { + .name = "LOCAL-G-LOCK6", + .fn = run_g_lock6, + }, + { + .name = "LOCAL-G-LOCK-PING-PONG", + .fn = run_g_lock_ping_pong, + }, + { + .name = "LOCAL-CANONICALIZE-PATH", + .fn = run_local_canonicalize_path, + }, + { + .name = "LOCAL-NAMEMAP-CACHE1", + .fn = run_local_namemap_cache1, + }, + { + .name = "LOCAL-IDMAP-CACHE1", + .fn = run_local_idmap_cache1, + }, + { + .name = "qpathinfo-bufsize", + .fn = run_qpathinfo_bufsize, + }, + { + .name = "hide-new-files-timeout", + .fn = run_hidenewfiles, + }, + { + .name = NULL, + }, +}; /**************************************************************************** run a specified test or "ALL" @@ -10496,6 +12810,20 @@ static void usage(void) printf("host=%s share=%s user=%s myname=%s\n", host, share, username, myname); + torture_creds = cli_session_creds_init(frame, + username, + workgroup, + NULL, /* realm */ + password, + use_kerberos, + false, /* fallback_after_kerberos */ + false, /* use_ccache */ + false); /* password_is_nt_hash */ + if (torture_creds == NULL) { + d_printf("cli_session_creds_init() failed.\n"); + exit(1); + } + if (argc == optind) { correct = run_test("ALL"); } else {