#include "lib/util/asn1.h"
#include "lib/param/param.h"
#include "auth/gensec/gensec.h"
+#include "lib/util/string_wrappers.h"
+#include "source3/lib/substitute.h"
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
}
- if (use_kerberos) {
- flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
- }
-
if (force_dos_errors) {
flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
}
sharename,
"?????",
torture_creds,
- flags,
- signing_state);
+ flags);
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));
return ret;
}
+void torture_conn_set_sockopt(struct cli_state *cli)
+{
+ smbXcli_conn_set_sockopt(cli->conn, sockops);
+}
+
+static NTSTATUS torture_delete_fn(struct file_info *finfo,
+ const char *pattern,
+ void *state)
+{
+ NTSTATUS status;
+ char *filename = NULL;
+ char *dirname = NULL;
+ char *p = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct cli_state *cli = (struct cli_state *)state;
+
+ if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_OK;
+ }
+
+ dirname = talloc_strdup(frame, pattern);
+ if (dirname == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+ p = strrchr_m(dirname, '\\');
+ if (p != NULL) {
+ /* Remove the terminating '\' */
+ *p = '\0';
+ }
+ if (dirname[0] != '\0') {
+ filename = talloc_asprintf(frame,
+ "%s\\%s",
+ dirname,
+ finfo->name);
+ } else {
+ filename = talloc_asprintf(frame,
+ "%s",
+ finfo->name);
+ }
+ if (filename == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
+ char *subdirname = talloc_asprintf(frame,
+ "%s\\*",
+ filename);
+ if (subdirname == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+ status = cli_list(cli,
+ subdirname,
+ FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_HIDDEN |
+ FILE_ATTRIBUTE_SYSTEM,
+ torture_delete_fn,
+ cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("torture_delete_fn: cli_list "
+ "of %s failed (%s)\n",
+ subdirname,
+ nt_errstr(status));
+ TALLOC_FREE(frame);
+ return status;
+ }
+ status = cli_rmdir(cli, filename);
+ } else {
+ status = cli_unlink(cli,
+ filename,
+ FILE_ATTRIBUTE_SYSTEM |
+ FILE_ATTRIBUTE_HIDDEN);
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
+ printf("torture_delete_fn: cli_rmdir"
+ " of %s failed (%s)\n",
+ filename,
+ nt_errstr(status));
+ } else {
+ printf("torture_delete_fn: cli_unlink"
+ " of %s failed (%s)\n",
+ filename,
+ nt_errstr(status));
+ }
+ }
+ TALLOC_FREE(frame);
+ return status;
+}
+
+void torture_deltree(struct cli_state *cli, const char *dname)
+{
+ char *mask = NULL;
+ NTSTATUS status;
+
+ /* It might be a file */
+ (void)cli_unlink(cli,
+ dname,
+ FILE_ATTRIBUTE_SYSTEM |
+ FILE_ATTRIBUTE_HIDDEN);
+
+ mask = talloc_asprintf(cli,
+ "%s\\*",
+ dname);
+ if (mask == NULL) {
+ printf("torture_deltree: talloc_asprintf failed\n");
+ return;
+ }
+
+ status = cli_list(cli,
+ mask,
+ FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_HIDDEN|
+ FILE_ATTRIBUTE_SYSTEM,
+ torture_delete_fn,
+ cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("torture_deltree: cli_list of %s failed (%s)\n",
+ mask,
+ nt_errstr(status));
+ }
+ TALLOC_FREE(mask);
+ status = cli_rmdir(cli, dname);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("torture_deltree: cli_rmdir of %s failed (%s)\n",
+ dname,
+ nt_errstr(status));
+ }
+}
/* check if the server produced the expected dos or nt error code */
static bool check_both_error(int line, NTSTATUS status,
return True;
}
+NTSTATUS cli_qpathinfo1(struct cli_state *cli,
+ const char *fname,
+ time_t *change_time,
+ time_t *access_time,
+ time_t *write_time,
+ off_t *size,
+ uint32_t *pattr)
+{
+ int timezone = smb1cli_conn_server_time_zone(cli->conn);
+ time_t (*date_fn)(const void *buf, int serverzone) = NULL;
+ uint8_t *rdata = NULL;
+ uint32_t num_rdata;
+ NTSTATUS status;
+
+ status = cli_qpathinfo(talloc_tos(),
+ cli,
+ fname,
+ SMB_INFO_STANDARD,
+ 22,
+ CLI_BUFFER_SIZE,
+ &rdata,
+ &num_rdata);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ if (cli->win95) {
+ date_fn = make_unix_date;
+ } else {
+ date_fn = make_unix_date2;
+ }
+
+ if (change_time) {
+ *change_time = date_fn(rdata + 0, timezone);
+ }
+ if (access_time) {
+ *access_time = date_fn(rdata + 4, timezone);
+ }
+ if (write_time) {
+ *write_time = date_fn(rdata + 8, timezone);
+ }
+ if (size) {
+ *size = PULL_LE_U32(rdata, 12);
+ }
+ if (pattr) {
+ *pattr = PULL_LE_U16(rdata, l1_attrFile);
+ }
+ return NT_STATUS_OK;
+}
static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
{
correct = False;
}
-#if 0
- /* ToDo - set allocation. JRA */
- if(!cli_set_allocation_size(cli1, fnum1, 0)) {
- printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
- return False;
- }
- if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
- NULL, NULL)) {
- printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
- correct = False;
- }
- if (fsize != 0)
- printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
-#endif
-
status = cli_close(cli1, fnum1);
if (!NT_STATUS_IS_OK(status)) {
printf("close failed (%s)\n", nt_errstr(status));
uint16_t fnum1;
uint32_t cnum1, cnum2, cnum3;
struct smbXcli_tcon *orig_tcon = NULL;
+ char *orig_share = NULL;
uint16_t vuid1, vuid2;
char buf[4];
bool ret = True;
return False;
}
- orig_tcon = cli_state_save_tcon(cli);
- if (orig_tcon == NULL) {
- return false;
- }
+ cli_state_save_tcon_share(cli, &orig_tcon, &orig_share);
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));
+ cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
cli_shutdown(cli);
return False;
}
status = cli_close(cli, fnum1);
if (!NT_STATUS_IS_OK(status)) {
printf("close failed (%s)\n", nt_errstr(status));
+ cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
+ cli_shutdown(cli);
return False;
}
status = cli_tdis(cli);
if (!NT_STATUS_IS_OK(status)) {
printf("secondary tdis failed (%s)\n", nt_errstr(status));
+ cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
+ cli_shutdown(cli);
return False;
}
- cli_state_restore_tcon(cli, orig_tcon);
+ cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
cli_state_set_tid(cli, cnum1);
NULL, /* service */
NULL, /* service_type */
torture_creds,
- flags,
- signing_state);
+ flags);
if (!NT_STATUS_IS_OK(status)) {
printf("could not open connection\n");
for (i=0;i<50000;i++) {
struct tevent_req *req;
- req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
- PROTOCOL_CORE, PROTOCOL_NT1, 0);
+ req = smbXcli_negprot_send(
+ ev,
+ ev,
+ cli->conn,
+ cli->timeout,
+ PROTOCOL_CORE,
+ PROTOCOL_NT1,
+ 0,
+ NULL);
if (req == NULL) {
TALLOC_FREE(ev);
return false;
static bool check_attributes(struct cli_state *cli,
const char *fname,
- uint16_t expected_attrs)
+ uint32_t expected_attrs)
{
- uint16_t attrs = 0;
+ uint32_t attrs = 0;
NTSTATUS status = cli_getatr(cli,
fname,
&attrs,
return False;
}
+ /* Ensure we can't unlink with out-of-range (unknown) attribute. */
+ status = cli_unlink(cli, fname, 0x20000);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ correct = false;
+ goto out;
+ }
+
cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
cli_openx(cli, fname,
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
t2 = t-60*60*24; /* 1 day ago */
+ /* Ensure we can't set with out-of-range (unknown) attribute. */
+ status = cli_setatr(cli, fname, 0x20000, t2);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ correct = false;
+ goto out;
+ }
+
status = cli_setatr(cli, fname, 0, t2);
if (!NT_STATUS_IS_OK(status)) {
printf("setatr failed (%s)\n", nt_errstr(status));
(struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* access */
(struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* write */
(struct timespec) { .tv_nsec = SAMBA_UTIME_OMIT }, /* change */
- (uint16_t)-1);
+ (uint32_t)-1);
if (!NT_STATUS_IS_OK(status)) {
printf("cli_setpathinfo_ext failed with %s\n",
nt_errstr(status));
return correct;
}
+static NTSTATUS cli_qfilename(
+ struct cli_state *cli,
+ uint16_t fnum,
+ TALLOC_CTX *mem_ctx,
+ char **_name)
+{
+ uint16_t recv_flags2;
+ uint8_t *rdata;
+ uint32_t num_rdata;
+ NTSTATUS status;
+ char *name = NULL;
+ uint32_t namelen;
+
+ status = cli_qfileinfo(talloc_tos(), cli, fnum,
+ SMB_QUERY_FILE_NAME_INFO,
+ 4, CLI_BUFFER_SIZE, &recv_flags2,
+ &rdata, &num_rdata);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ namelen = IVAL(rdata, 0);
+ if (namelen > (num_rdata - 4)) {
+ TALLOC_FREE(rdata);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ pull_string_talloc(mem_ctx,
+ (const char *)rdata,
+ recv_flags2,
+ &name,
+ rdata + 4,
+ namelen,
+ STR_UNICODE);
+ if (name == NULL) {
+ status = map_nt_error_from_unix(errno);
+ TALLOC_FREE(rdata);
+ return status;
+ }
+
+ *_name = name;
+ TALLOC_FREE(rdata);
+ return NT_STATUS_OK;
+}
/*
This checks a couple of trans2 calls
const char *fname = "\\trans2.tst";
const char *dname = "\\trans2";
const char *fname2 = "\\trans2\\trans2.tst";
- char *pname;
+ char *pname = NULL;
bool correct = True;
NTSTATUS status;
uint32_t fs_attr;
fail:
/* FIXME: This will crash if we aborted before cli2 got
- * intialized, because these functions don't handle
+ * initialized, because these functions don't handle
* uninitialized connections. */
if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
return correct;
}
-/*
- Test wildcard delete.
- */
-static bool run_wild_deletetest(int dummy)
-{
- struct cli_state *cli = NULL;
- const char *dname = "\\WTEST";
- const char *fname = "\\WTEST\\A";
- const char *wunlink_name = "\\WTEST\\*";
- uint16_t fnum1 = (uint16_t)-1;
- bool correct = false;
- NTSTATUS status;
-
- printf("starting wildcard delete test\n");
-
- if (!torture_open_connection(&cli, 0)) {
- return false;
- }
-
- smbXcli_conn_set_sockopt(cli->conn, sockops);
-
- cli_unlink(cli, fname, 0);
- cli_rmdir(cli, dname);
- status = cli_mkdir(cli, dname);
- if (!NT_STATUS_IS_OK(status)) {
- printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
- goto fail;
- }
- status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
- if (!NT_STATUS_IS_OK(status)) {
- printf("open of %s failed %s!\n", fname, nt_errstr(status));
- goto fail;
- }
- status = cli_close(cli, fnum1);
- fnum1 = -1;
-
- /*
- * Note the unlink attribute-type of zero. This should
- * map into FILE_ATTRIBUTE_NORMAL at the server even
- * on a wildcard delete.
- */
-
- status = cli_unlink(cli, wunlink_name, 0);
- if (!NT_STATUS_IS_OK(status)) {
- printf("unlink of %s failed %s!\n",
- wunlink_name, nt_errstr(status));
- goto fail;
- }
-
- printf("finished wildcard delete test\n");
-
- correct = true;
-
- fail:
-
- if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
- cli_unlink(cli, fname, 0);
- cli_rmdir(cli, dname);
-
- if (cli && !torture_close_connection(cli)) {
- correct = false;
- }
- return correct;
-}
-
static bool run_deletetest_ln(int dummy)
{
struct cli_state *cli;
const char *fname1 = "\\test1.txt";
bool correct = True;
uint16_t fnum1;
- uint16_t attr;
+ uint32_t attr;
NTSTATUS status;
printf("starting rename test\n");
}
-#if 0
- {
- uint16_t fnum2;
-
- if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
- printf("Fourth open failed - %s\n", cli_errstr(cli1));
- return False;
- }
- if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
- printf("[8] setting delete_on_close on file failed !\n");
- return False;
- }
-
- if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
- printf("close - 4 failed (%s)\n", cli_errstr(cli1));
- return False;
- }
- }
-#endif
-
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));
printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
}
- /*
- * Now check if the first name still exists ...
- */
-
- /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
- printf("Opening original file after rename of open file fails: %s\n",
- cli_errstr(cli1));
- }
- else {
- printf("Opening original file after rename of open file works ...\n");
- (void)cli_close(cli1, fnum2);
- } */
-
/*--*/
status = cli_close(cli1, fnum1);
if (!NT_STATUS_IS_OK(status)) {
size_t nread;
const char *fname_windows = "windows_file";
uint16_t fnum2 = (uint16_t)-1;
+ bool ok;
printf("Starting simple POSIX open test\n");
if (NT_STATUS_IS_OK(status)) {
printf("POSIX open of %s succeeded (should have failed)\n", sname);
goto out;
- } else {
- if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
- NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
- printf("POSIX open of %s should have failed "
- "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
- "failed with %s instead.\n",
- sname, nt_errstr(status));
- goto out;
- }
+ }
+ ok = check_both_error(
+ __LINE__, status, ERRDOS, ERRbadpath,
+ NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ if (!ok) {
+ printf("POSIX open of %s should have failed "
+ "with NT_STATUS_OBJECT_NAME_NOT_FOUND, "
+ "failed with %s instead.\n",
+ sname, nt_errstr(status));
+ goto out;
}
- status = cli_posix_readlink(cli1, sname, talloc_tos(), &target);
+ status = cli_readlink(cli1, sname, talloc_tos(), &target, NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
goto out;
char *posix_acl_sym = NULL;
size_t posix_acl_len_sym = 0;
struct security_descriptor *sd = NULL;
- struct security_descriptor *sd_sym = NULL;
TALLOC_CTX *frame = NULL;
frame = talloc_stackframe();
goto out;
}
- /* Open a handle on the symlink. */
+ /* Try a stat-open on the symlink, should also fail. */
status = cli_ntcreate(cli,
sname,
0,
&fnum,
NULL);
- if (!NT_STATUS_IS_OK(status)) {
- printf("cli_posix_open of %s failed (%s)\n",
- sname,
- nt_errstr(status));
- goto out;
- }
-
- /* Get the Windows ACL on the symlink handle. Should fail */
- status = cli_query_secdesc(cli,
- fnum,
- frame,
- &sd_sym);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
- printf("cli_query_secdesc on a symlink gave %s. "
- "Should be NT_STATUS_ACCESS_DENIED.\n",
- nt_errstr(status));
+ if (NT_STATUS_IS_OK(status)) {
+ printf("Stat-open of symlink succeeded (should fail)\n");
goto out;
}
goto out;
}
- /* Set the Windows ACL on the symlink handle. Should fail */
- status = cli_set_security_descriptor(cli,
- fnum,
- SECINFO_DACL,
- sd);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
- printf("cli_query_secdesc on a symlink gave %s. "
- "Should be NT_STATUS_ACCESS_DENIED.\n",
- nt_errstr(status));
- goto out;
- }
-
/* Set the POSIX ACL on the symlink pathname. Should fail. */
status = cli_posix_setacl(cli,
sname,
return false;
}
+ status = torture_setup_unix_extensions(cli2);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
cli_setatr(cli1, fname, 0, 0);
cli_posix_unlink(cli1, fname);
const char *fname = "\\openattr.file";
uint16_t fnum1;
bool correct = True;
- uint16_t attr;
+ uint32_t attr;
unsigned int i, j, k, l;
NTSTATUS status;
return correct;
}
-static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
+static NTSTATUS list_fn(struct file_info *finfo,
const char *name, void *state)
{
int *matched = (int *)state;
return correct;
}
-static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
+static NTSTATUS del_fn(struct file_info *finfo, const char *mask,
void *state)
{
struct cli_state *pcli = (struct cli_state *)state;
if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
return NT_STATUS_OK;
- if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
+ if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
printf("del_fn: failed to rmdir %s\n,", fname );
} else {
}
+/*
+ send a raw ioctl - used by the torture code
+*/
+static NTSTATUS cli_raw_ioctl(struct cli_state *cli,
+ uint16_t fnum,
+ uint32_t code,
+ DATA_BLOB *blob)
+{
+ uint16_t vwv[3];
+ NTSTATUS status;
+
+ PUSH_LE_U16(vwv + 0, 0, fnum);
+ PUSH_LE_U16(vwv + 1, 0, code >> 16);
+ PUSH_LE_U16(vwv + 2, 0, (code & 0xFFFF));
+
+ status = cli_smb(talloc_tos(),
+ cli,
+ SMBioctl,
+ 0,
+ 3,
+ vwv,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ *blob = data_blob_null;
+ return NT_STATUS_OK;
+}
+
/*
sees what IOCTLs are supported
*/
/*
- tries varients of chkpath
+ tries variants of chkpath
*/
bool torture_chkpath_test(int dummy)
{
printf("starting chkpath test\n");
/* cleanup from an old run */
- cli_rmdir(cli, "\\chkpath.dir\\dir2");
- cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
- cli_rmdir(cli, "\\chkpath.dir");
+ torture_deltree(cli, "\\chkpath.dir");
status = cli_mkdir(cli, "\\chkpath.dir");
if (!NT_STATUS_IS_OK(status)) {
ret = False;
}
- cli_rmdir(cli, "\\chkpath.dir\\dir2");
- cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
- cli_rmdir(cli, "\\chkpath.dir");
+ torture_deltree(cli, "\\chkpath.dir");
if (!torture_close_connection(cli)) {
return False;
const char *fname = "\\eatest.txt";
bool correct = True;
uint16_t fnum;
- int i;
- size_t num_eas;
+ size_t i, num_eas;
struct ea_struct *ea_list = NULL;
TALLOC_CTX *mem_ctx = talloc_init("eatest");
NTSTATUS status;
for (i = 0; i < 10; i++) {
fstring ea_name, ea_val;
- slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
+ slprintf(ea_name, sizeof(ea_name), "EA_%zu", i);
memset(ea_val, (char)i+1, i+1);
status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
if (!NT_STATUS_IS_OK(status)) {
for (i = 0; i < 10; i++) {
fstring ea_name, ea_val;
- slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
+ slprintf(ea_name, sizeof(ea_name), "EA_%zu", i+10);
memset(ea_val, (char)i+1, i+1);
status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
if (!NT_STATUS_IS_OK(status)) {
}
for (i = 0; i < num_eas; i++) {
- printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
+ printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
dump_data(0, ea_list[i].value.data,
ea_list[i].value.length);
}
/* Setting EA's to zero length deletes them. Test this */
- printf("Now deleting all EA's - case indepenent....\n");
+ printf("Now deleting all EA's - case independent....\n");
#if 1
cli_set_ea_path(cli, fname, "", "", 0);
printf("num_eas = %d\n", (int)num_eas);
for (i = 0; i < num_eas; i++) {
- printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
+ printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
dump_data(0, ea_list[i].value.data,
ea_list[i].value.length);
}
correct = False;
/* Ensure if we have the "must have" bits we only see the
- * relevent entries.
+ * relevant entries.
*/
num_seen = 0;
cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
subreq, struct tevent_req);
struct torture_createdels_state *state = tevent_req_data(
req, struct torture_createdels_state);
- size_t num_parallel = talloc_array_length(state->reqs);
+ size_t i, num_parallel = talloc_array_length(state->reqs);
NTSTATUS status;
char *name;
- int i;
status = torture_createdel_recv(subreq);
if (!NT_STATUS_IS_OK(status)){
uint16_t fnum;
fstring alt_name;
NTSTATUS status;
- time_t change_time, access_time, write_time;
- off_t size;
- uint16_t mode;
printf("starting mangle1 test\n");
if (!torture_open_connection(&cli, 0)) {
}
cli_close(cli, fnum);
- status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
- &write_time, &size, &mode);
+ status = cli_qpathinfo1(cli, alt_name, NULL, NULL, NULL, NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
nt_errstr(status));
return true;
}
-static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
- struct file_info *f,
+static NTSTATUS mangle_illegal_list_shortname_fn(struct file_info *f,
const char *mask,
void *state)
{
return NT_STATUS_OBJECT_NAME_INVALID;
}
-static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
- struct file_info *f,
+static NTSTATUS mangle_illegal_list_name_fn(struct file_info *f,
const char *mask,
void *state)
{
return correct;
}
-static bool run_cli_echo(int dummy)
+static NTSTATUS msdfs_attribute_list_fn(struct file_info *finfo,
+ const char *mask,
+ void *private_data)
{
- struct cli_state *cli;
- NTSTATUS status;
+ uint32_t *p_attr = (uint32_t *)private_data;
- printf("starting cli_echo test\n");
- if (!torture_open_connection(&cli, 0)) {
- return false;
+ if (strequal(finfo->name, test_filename)) {
+ *p_attr = finfo->attr;
}
- 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;
+ return NT_STATUS_OK;
}
-static bool run_cli_splice(int dummy)
+static bool run_msdfs_attribute(int dummy)
{
- uint8_t *buf = NULL;
- struct cli_state *cli1 = NULL;
+ static struct cli_state *cli;
bool correct = false;
- const char *fname_src = "\\splice_src.dat";
- const char *fname_dst = "\\splice_dst.dat";
+ uint32_t attr = 0;
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;
- 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");
+ printf("Starting MSDFS-ATTRIBUTE test\n");
- if (!torture_open_connection(&cli1, 0)) {
- goto out;
+ if (test_filename == NULL || test_filename[0] == '\0') {
+ printf("MSDFS-ATTRIBUTE test "
+ "needs -f filename-of-msdfs-link\n");
+ return false;
}
- cli_unlink(cli1, fname_src,
- FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
- cli_unlink(cli1, fname_dst,
+ /*
+ * NB. We use torture_open_connection_flags() not
+ * torture_open_connection() as the latter forces
+ * SMB1.
+ */
+ if (!torture_open_connection_flags(&cli, 0, 0)) {
+ return false;
+ }
+
+ smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+ status = cli_list(cli,
+ "*",
+ FILE_ATTRIBUTE_DIRECTORY,
+ msdfs_attribute_list_fn,
+ &attr);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_list failed with %s\n",
+ nt_errstr(status));
+ goto out;
+ }
+ if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0) {
+ printf("file %s should have "
+ "FILE_ATTRIBUTE_REPARSE_POINT set. attr = 0x%x\n",
+ test_filename,
+ (unsigned int)attr);
+ goto out;
+ }
+
+ if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
+ printf("file %s should have "
+ "FILE_ATTRIBUTE_DIRECTORY set. attr = 0x%x\n",
+ test_filename,
+ (unsigned int)attr);
+ goto out;
+ }
+
+ correct = true;
+
+ out:
+
+ torture_close_connection(cli);
+ 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;
+ 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 */
int16_t old_vuid;
int32_t old_cnum;
bool correct = True;
- struct smbXcli_tcon *orig_tcon = NULL;
+ struct smbXcli_tcon *tcon_copy = NULL;
NTSTATUS status;
printf("starting uid regression test\n");
}
old_cnum = cli_state_get_tid(cli);
- orig_tcon = cli_state_save_tcon(cli);
- if (orig_tcon == NULL) {
+ /*
+ * This is an SMB1-only test.
+ * Copy the tcon, not "save/restore".
+ *
+ * In SMB1 the cli_tdis() below frees
+ * cli->smb1.tcon so we need a copy
+ * of the struct to put back for the
+ * second tdis call with invalid vuid.
+ *
+ * This is a test-only hack. Real client code
+ * uses cli_state_save_tcon_share()/cli_state_restore_tcon_share().
+ */
+ tcon_copy = smbXcli_tcon_copy(cli, cli->smb1.tcon);
+ if (tcon_copy == NULL) {
correct = false;
goto out;
}
} else {
d_printf("First tdis failed (%s)\n", nt_errstr(status));
correct = false;
- cli_state_restore_tcon(cli, orig_tcon);
+ cli->smb1.tcon = tcon_copy;
goto out;
}
- cli_state_restore_tcon(cli, orig_tcon);
+ cli->smb1.tcon = tcon_copy;
cli_state_set_uid(cli, old_vuid);
cli_state_set_tid(cli, old_cnum);
static const char *illegal_chars = "*\\/?<>|\":";
static char force_shortname_chars[] = " +,.[];=\177";
-static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
+static NTSTATUS shortname_del_fn(struct file_info *finfo,
const char *mask, void *state)
{
struct cli_state *pcli = (struct cli_state *)state;
if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
return NT_STATUS_OK;
- if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
+ if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
status = cli_rmdir(pcli, fname);
if (!NT_STATUS_IS_OK(status)) {
printf("del_fn: failed to rmdir %s\n,", fname );
bool val;
};
-static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
+static NTSTATUS shortname_list_fn(struct file_info *finfo,
const char *name, void *state)
{
struct sn_state *s = (struct sn_state *)state;
NTSTATUS status;
time_t change_time, access_time, write_time;
off_t size;
- uint16_t mode, fnum;
+ uint16_t fnum;
+ uint32_t attr;
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);
+ torture_deltree(cli, dname);
status = cli_mkdir(cli, dname);
if (!NT_STATUS_IS_OK(status)) {
}
status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
- &write_time, &size, &mode);
+ &write_time, &size, &attr);
if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
printf("pathinfo returned %s, expected "
"NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
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)
+static NTSTATUS smb1_wild_mangle_list_fn(struct file_info *finfo,
+ const char *name,
+ void *state)
{
- 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;
-
- ctx = talloc_new(NULL);
-
- env_tz = getenv("TZ");
- if(env_tz) {
- orig_tz = talloc_strdup(ctx, env_tz);
- }
- setenv("TZ", "UTC", 1);
-
- s = minimal_timeval_string(ctx, &tv, false);
-
- if(!s || strcmp(s, expect_minimal)) {
- printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
- "[%s]\n", s ? s : "<nil>", expect_minimal);
- result = 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 : "<nil>", expect_minus);
- result = false;
- }
- TALLOC_FREE(s);
+ char **mangled_name_return = (char **)state;
+ bool is_mangled = strchr(finfo->name, '~');
- if(orig_tz) {
- setenv("TZ", orig_tz, 1);
+ if (is_mangled) {
+ *mangled_name_return = talloc_strdup(NULL, finfo->name);
+ if (*mangled_name_return == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
}
-
- TALLOC_FREE(ctx);
- return result;
+ return NT_STATUS_OK;
}
-static bool run_local_substitute(int dummy)
+static bool run_smb1_wild_mangle_unlink_test(int dummy)
{
- bool ok = true;
-
- ok &= subst_test("%U", "bla", "", -1, -1, "bla");
- ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
- ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
- ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
- ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
- 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... */
-
- ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
- "blaDOM") == 0);
+ static struct cli_state *cli_posix = NULL;
+ static struct cli_state *cli = NULL;
+ uint16_t fnum = (uint16_t)-1;
+ bool correct = false;
+ const char *dname = "smb1_wild_mangle_unlink";
+ const char *aname = "smb1_wild_mangle_unlink/a";
+ const char *star_name = "smb1_wild_mangle_unlink/*";
+ char *windows_unlink_name = NULL;
+ char *mangled_name = NULL;
+ NTSTATUS status;
- return ok;
-}
+ printf("Starting SMB1 wild mangle unlink test\n");
-static bool run_local_base64(int dummy)
-{
- int i;
- bool ret = true;
+ /* Open a Windows connection. */
+ if (!torture_open_connection(&cli, 0)) {
+ return false;
+ }
- for (i=1; i<2000; i++) {
- DATA_BLOB blob1, blob2;
- char *b64;
+ smbXcli_conn_set_sockopt(cli->conn, sockops);
- blob1.data = talloc_array(talloc_tos(), uint8_t, i);
- blob1.length = i;
- generate_random_buffer(blob1.data, blob1.length);
+ /* Open a POSIX connection. */
+ if (!torture_open_connection(&cli_posix, 0)) {
+ goto out;
+ }
- b64 = base64_encode_data_blob(talloc_tos(), blob1);
- if (b64 == NULL) {
- d_fprintf(stderr, "base64_encode_data_blob failed "
- "for %d bytes\n", i);
- ret = false;
- }
- blob2 = base64_decode_data_blob(b64);
- TALLOC_FREE(b64);
+ smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
- if (data_blob_cmp(&blob1, &blob2)) {
- d_fprintf(stderr, "data_blob_cmp failed for %d "
- "bytes\n", i);
- ret = false;
- }
- TALLOC_FREE(blob1.data);
- data_blob_free(&blob2);
+ status = torture_setup_unix_extensions(cli_posix);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("server doesn't support POSIX\n");
+ goto out;
}
- return ret;
-}
-static void parse_fn(const struct gencache_timeout *t,
- DATA_BLOB blob,
- void *private_data)
-{
- return;
-}
+ /* Start fresh. */
+ torture_deltree(cli, dname);
-static bool run_local_gencache(int dummy)
-{
- char *val;
- time_t tm;
- DATA_BLOB blob;
- char v;
- struct memcache *mem;
- int i;
+ /*
+ * Create two files - 'a' and '*'.
+ * We need POSIX extensions for this as '*'
+ * is not a valid Windows name.
+ */
- mem = memcache_init(NULL, 0);
- if (mem == NULL) {
- d_printf("%s: memcache_init failed\n", __location__);
- return false;
+ status = cli_mkdir(cli, dname);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_mkdir of %s returned %s\n",
+ dname,
+ nt_errstr(status));
+ goto out;
}
- memcache_set_global(mem);
- if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
- d_printf("%s: gencache_set() failed\n", __location__);
- return False;
+ status = cli_posix_open(cli_posix,
+ aname,
+ O_RDWR|O_CREAT|O_EXCL,
+ 0660,
+ &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_open (create) of %s returned %s\n",
+ aname,
+ nt_errstr(status));
+ goto out;
}
-
- if (!gencache_get("foo", NULL, NULL, NULL)) {
- d_printf("%s: gencache_get() failed\n", __location__);
- return False;
+ status = cli_close(cli_posix, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
}
-
- for (i=0; i<1000000; i++) {
- gencache_parse("foo", parse_fn, NULL);
+ status = cli_posix_open(cli_posix,
+ star_name,
+ O_RDWR|O_CREAT|O_EXCL,
+ 0660,
+ &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_open (create) of %s returned %s\n",
+ star_name,
+ nt_errstr(status));
+ goto out;
+ }
+ status = cli_close(cli_posix, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
}
- if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
- d_printf("%s: gencache_get() failed\n", __location__);
- return False;
+ status = cli_list(cli,
+ star_name,
+ 0,
+ smb1_wild_mangle_list_fn,
+ &mangled_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_list of %s returned %s\n",
+ star_name,
+ nt_errstr(status));
+ goto out;
}
- TALLOC_FREE(val);
- if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
- d_printf("%s: gencache_get() failed\n", __location__);
- return False;
+ if (mangled_name == NULL) {
+ goto out;
}
- if (strcmp(val, "bar") != 0) {
- d_printf("%s: gencache_get() returned %s, expected %s\n",
- __location__, val, "bar");
- TALLOC_FREE(val);
- return False;
- }
+ printf("mangled_name = %s\n",
+ mangled_name);
- TALLOC_FREE(val);
+ /*
+ * Try a Windows unlink with the mangled name.
+ * This should *NOT* unlink the 'a' name.
+ */
- if (!gencache_del("foo")) {
- d_printf("%s: gencache_del() failed\n", __location__);
- return False;
- }
- if (gencache_del("foo")) {
- d_printf("%s: second gencache_del() succeeded\n",
- __location__);
- return False;
- }
+ windows_unlink_name = talloc_asprintf(cli_posix,
+ "%s\\%s",
+ dname,
+ mangled_name);
- if (gencache_get("foo", talloc_tos(), &val, &tm)) {
- d_printf("%s: gencache_get() on deleted entry "
- "succeeded\n", __location__);
- return False;
+ status = cli_unlink(cli, windows_unlink_name, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_unlink of %s returned %s\n",
+ windows_unlink_name,
+ nt_errstr(status));
+ goto out;
}
- blob = data_blob_string_const_null("bar");
- tm = time(NULL) + 60;
-
- if (!gencache_set_data_blob("foo", blob, tm)) {
- d_printf("%s: gencache_set_data_blob() failed\n", __location__);
- return False;
+ /* Does 'a' still exist ? */
+ status = cli_posix_open(cli_posix,
+ aname,
+ O_RDONLY,
+ 0,
+ &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_open O_RNONLY of %s returned %s\n",
+ aname,
+ nt_errstr(status));
+ goto out;
}
- if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
- d_printf("%s: gencache_get_data_blob() failed\n", __location__);
- return False;
+ status = cli_close(cli_posix, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
}
- if (strcmp((const char *)blob.data, "bar") != 0) {
- d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
- __location__, (const char *)blob.data, "bar");
- data_blob_free(&blob);
- return False;
- }
+ correct = true;
- data_blob_free(&blob);
+ out:
- if (!gencache_del("foo")) {
- d_printf("%s: gencache_del() failed\n", __location__);
- return False;
- }
- if (gencache_del("foo")) {
- d_printf("%s: second gencache_del() succeeded\n",
- __location__);
- return False;
- }
+ TALLOC_FREE(windows_unlink_name);
+ TALLOC_FREE(mangled_name);
- if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
- d_printf("%s: gencache_get_data_blob() on deleted entry "
- "succeeded\n", __location__);
- return False;
+ if (cli != NULL) {
+ torture_deltree(cli, dname);
+ torture_close_connection(cli);
}
- v = 1;
- blob.data = (uint8_t *)&v;
- blob.length = sizeof(v);
-
- if (!gencache_set_data_blob("blob", blob, tm)) {
- d_printf("%s: gencache_set_data_blob() failed\n",
- __location__);
- return false;
- }
- if (gencache_get("blob", talloc_tos(), &val, &tm)) {
- d_printf("%s: gencache_get succeeded\n", __location__);
- return false;
+ if (cli_posix != NULL) {
+ torture_close_connection(cli_posix);
}
- return True;
+ return correct;
}
-static bool rbt_testval(struct db_context *db, const char *key,
- const char *value)
+static bool run_smb1_wild_mangle_rename_test(int dummy)
{
- struct db_record *rec;
- TDB_DATA data = string_tdb_data(value);
- bool ret = false;
+ static struct cli_state *cli_posix = NULL;
+ static struct cli_state *cli = NULL;
+ uint16_t fnum = (uint16_t)-1;
+ bool correct = false;
+ const char *dname = "smb1_wild_mangle_rename";
+ const char *fooname = "smb1_wild_mangle_rename/foo";
+ const char *foostar_name = "smb1_wild_mangle_rename/fo*";
+ const char *wild_name = "smb1_wild_mangle_rename/*";
+ char *windows_rename_src = NULL;
+ const char *windows_rename_dst = "smb1_wild_mangle_rename\\bar";
+ char *mangled_name = NULL;
NTSTATUS status;
- TDB_DATA dbvalue;
- rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
- if (rec == NULL) {
- d_fprintf(stderr, "fetch_locked failed\n");
- goto done;
+ printf("Starting SMB1 wild mangle rename test\n");
+
+ if (!torture_open_connection(&cli_posix, 0)) {
+ return false;
}
- status = dbwrap_record_store(rec, data, 0);
+
+ smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
+
+ status = torture_setup_unix_extensions(cli_posix);
if (!NT_STATUS_IS_OK(status)) {
- d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
- goto done;
+ printf("server doesn't support POSIX\n");
+ return false;
}
- TALLOC_FREE(rec);
- rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
- if (rec == NULL) {
- d_fprintf(stderr, "second fetch_locked failed\n");
- goto done;
+ /* Open a Windows connection. */
+ if (!torture_open_connection(&cli, 0)) {
+ goto out;
}
- dbvalue = dbwrap_record_get_value(rec);
- if ((dbvalue.dsize != data.dsize)
- || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
- d_fprintf(stderr, "Got wrong data back\n");
- goto done;
- }
+ smbXcli_conn_set_sockopt(cli->conn, sockops);
- ret = true;
- done:
- TALLOC_FREE(rec);
- return ret;
-}
+ /* Ensure we start from fresh. */
+ torture_deltree(cli, dname);
-static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
-{
- int *count2 = (int *)private_data;
- (*count2)++;
- return 0;
-}
+ /*
+ * Create two files - 'foo' and 'fo*'.
+ * We need POSIX extensions for this as 'fo*'
+ * is not a valid Windows name.
+ */
-static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
-{
- int *count2 = (int *)private_data;
- (*count2)++;
- dbwrap_record_delete(rec);
- return 0;
-}
+ status = cli_posix_mkdir(cli_posix, dname, 0770);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_mkdir of %s returned %s\n",
+ dname,
+ nt_errstr(status));
+ goto out;
+ }
-static bool run_local_rbtree(int dummy)
-{
- struct db_context *db;
- bool ret = false;
- int i;
- NTSTATUS status;
- int count = 0;
- int count2 = 0;
+ status = cli_posix_open(cli_posix,
+ fooname,
+ O_RDWR|O_CREAT|O_EXCL,
+ 0660,
+ &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_open (create) of %s returned %s\n",
+ fooname,
+ nt_errstr(status));
+ goto out;
+ }
+ status = cli_close(cli_posix, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+ status = cli_posix_open(cli_posix,
+ foostar_name,
+ O_RDWR|O_CREAT|O_EXCL,
+ 0660,
+ &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_open (create) of %s returned %s\n",
+ foostar_name,
+ nt_errstr(status));
+ goto out;
+ }
+ status = cli_close(cli_posix, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
- db = db_open_rbt(NULL);
+ /*
+ * Get the mangled name. We can re-use the
+ * previous smb1_wild_mangle_list_fn for this.
+ */
- if (db == NULL) {
- d_fprintf(stderr, "db_open_rbt failed\n");
- return false;
+ status = cli_list(cli,
+ wild_name,
+ 0,
+ smb1_wild_mangle_list_fn,
+ &mangled_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_list of %s returned %s\n",
+ wild_name,
+ nt_errstr(status));
+ goto out;
}
- for (i=0; i<1000; i++) {
- char *key, *value;
-
- if (asprintf(&key, "key%ld", random()) == -1) {
- goto done;
- }
- if (asprintf(&value, "value%ld", random()) == -1) {
- SAFE_FREE(key);
- goto done;
- }
+ if (mangled_name == NULL) {
+ goto out;
+ }
- if (!rbt_testval(db, key, value)) {
- SAFE_FREE(key);
- SAFE_FREE(value);
- goto done;
- }
+ printf("mangled_name = %s\n",
+ mangled_name);
- SAFE_FREE(value);
- if (asprintf(&value, "value%ld", random()) == -1) {
- SAFE_FREE(key);
- goto done;
- }
+ /*
+ * Try a Windows rename with the mangled name.
+ * This should *NOT* rename the 'foo' name.
+ */
- if (!rbt_testval(db, key, value)) {
- SAFE_FREE(key);
- SAFE_FREE(value);
- goto done;
- }
+ windows_rename_src = talloc_asprintf(cli_posix,
+ "%s\\%s",
+ dname,
+ mangled_name);
- SAFE_FREE(key);
- SAFE_FREE(value);
+ status = cli_rename(cli,
+ windows_rename_src,
+ windows_rename_dst,
+ false);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_rename of %s -> %s returned %s\n",
+ windows_rename_src,
+ windows_rename_dst,
+ nt_errstr(status));
+ goto out;
}
- ret = true;
- count = 0; count2 = 0;
- status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
- &count2, &count);
- printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
- if ((count != count2) || (count != 1000)) {
- ret = false;
+ /* Does 'foo' still exist ? */
+ status = cli_posix_open(cli_posix,
+ fooname,
+ O_RDONLY,
+ 0,
+ &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_open O_RNONLY of %s returned %s\n",
+ fooname,
+ nt_errstr(status));
+ goto out;
}
- count = 0; count2 = 0;
- status = dbwrap_traverse(db, local_rbtree_traverse_delete,
- &count2, &count);
- printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
- if ((count != count2) || (count != 1000)) {
- ret = false;
+
+ status = cli_close(cli_posix, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
}
- count = 0; count2 = 0;
- status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
- &count2, &count);
- printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
- if ((count != count2) || (count != 0)) {
- ret = false;
+
+ correct = true;
+
+ out:
+
+ TALLOC_FREE(mangled_name);
+ TALLOC_FREE(windows_rename_src);
+
+ if (cli != NULL) {
+ torture_deltree(cli, dname);
+ torture_close_connection(cli);
}
- done:
- TALLOC_FREE(db);
- return ret;
-}
+ torture_close_connection(cli_posix);
+ return correct;
+}
/*
- local test for character set functions
-
- This is a very simple test for the functionality in convert_string_error()
+ * Only testing minimal time strings, as the others
+ * need (locale-dependent) guessing at what strftime does and
+ * even may differ in builds.
*/
-static bool run_local_convert_string(int dummy)
+static bool timesubst_test(void)
{
- TALLOC_CTX *tmp_ctx = talloc_new(NULL);
- const char *test_strings[2] = { "March", "M\303\244rz" };
- char dst[7];
- int i;
+ 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;
- for (i=0; i<2; i++) {
- const char *str = test_strings[i];
- int len = strlen(str);
- size_t converted_size;
- bool ret;
+ ctx = talloc_new(NULL);
- memset(dst, 'X', sizeof(dst));
+ env_tz = getenv("TZ");
+ if(env_tz) {
+ orig_tz = talloc_strdup(ctx, env_tz);
+ }
+ setenv("TZ", "UTC", 1);
- /* first try with real source length */
- ret = convert_string_error(CH_UNIX, CH_UTF8,
- str, len,
- dst, sizeof(dst),
- &converted_size);
- if (ret != true) {
- d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
- goto failed;
- }
+ s = minimal_timeval_string(ctx, &tv, false);
- if (converted_size != len) {
- d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
- str, len, (int)converted_size);
- goto failed;
- }
+ if(!s || strcmp(s, expect_minimal)) {
+ printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
+ "[%s]\n", s ? s : "<nil>", expect_minimal);
+ result = 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 : "<nil>", expect_minus);
+ result = false;
+ }
+ TALLOC_FREE(s);
- if (strncmp(str, dst, converted_size) != 0) {
- d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
- goto failed;
- }
+ if(orig_tz) {
+ setenv("TZ", orig_tz, 1);
+ }
- if (strlen(str) != converted_size) {
- d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
- (int)strlen(str), (int)converted_size);
- goto failed;
- }
+ TALLOC_FREE(ctx);
+ return result;
+}
- if (dst[converted_size] != 'X') {
- d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
- goto failed;
- }
+static bool run_local_substitute(int dummy)
+{
+ bool ok = true;
- /* now with srclen==-1, this causes the nul to be
- * converted too */
- ret = convert_string_error(CH_UNIX, CH_UTF8,
- str, -1,
- dst, sizeof(dst),
- &converted_size);
- if (ret != true) {
- d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
- goto failed;
- }
+ ok &= subst_test("%U", "bla", "", -1, -1, "bla");
+ ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
+ ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
+ ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
+ ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
+ 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();
- if (converted_size != len+1) {
- d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
- str, len, (int)converted_size);
- goto failed;
- }
+ /* Different captialization rules in sub_basic... */
- if (strncmp(str, dst, converted_size) != 0) {
- d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
- goto failed;
- }
+ ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
+ "blaDOM") == 0);
- if (len+1 != converted_size) {
- d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
- len+1, (int)converted_size);
- goto failed;
- }
+ return ok;
+}
- if (dst[converted_size] != 'X') {
- d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
- goto failed;
+static bool run_local_base64(int dummy)
+{
+ int i;
+ bool ret = true;
+
+ for (i=1; i<2000; i++) {
+ DATA_BLOB blob1, blob2;
+ char *b64;
+
+ blob1.data = talloc_array(talloc_tos(), uint8_t, i);
+ blob1.length = i;
+ generate_random_buffer(blob1.data, blob1.length);
+
+ b64 = base64_encode_data_blob(talloc_tos(), blob1);
+ if (b64 == NULL) {
+ d_fprintf(stderr, "base64_encode_data_blob failed "
+ "for %d bytes\n", i);
+ ret = false;
}
+ blob2 = base64_decode_data_blob(b64);
+ TALLOC_FREE(b64);
+ if (data_blob_cmp(&blob1, &blob2)) {
+ d_fprintf(stderr, "data_blob_cmp failed for %d "
+ "bytes\n", i);
+ ret = false;
+ }
+ TALLOC_FREE(blob1.data);
+ data_blob_free(&blob2);
}
+ return ret;
+}
-
- TALLOC_FREE(tmp_ctx);
- return true;
-failed:
- TALLOC_FREE(tmp_ctx);
- return false;
+static void parse_fn(const struct gencache_timeout *t,
+ DATA_BLOB blob,
+ void *private_data)
+{
+ return;
}
-static bool run_local_string_to_sid(int dummy) {
- struct dom_sid sid;
+static bool run_local_gencache(int dummy)
+{
+ char *val;
+ time_t tm;
+ DATA_BLOB blob;
+ char v;
+ struct memcache *mem;
+ int i;
- if (string_to_sid(&sid, "S--1-5-32-545")) {
- printf("allowing S--1-5-32-545\n");
+ mem = memcache_init(NULL, 0);
+ if (mem == NULL) {
+ d_printf("%s: memcache_init failed\n", __location__);
return false;
}
- if (string_to_sid(&sid, "S-1-5-32-+545")) {
- printf("allowing S-1-5-32-+545\n");
- return false;
+ memcache_set_global(mem);
+
+ if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
+ d_printf("%s: gencache_set() failed\n", __location__);
+ return False;
}
- if (string_to_sid(&sid, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
- printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
- return false;
+
+ if (!gencache_get("foo", NULL, NULL, NULL)) {
+ d_printf("%s: gencache_get() failed\n", __location__);
+ return False;
}
- if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
- printf("allowing S-1-5-32-545-abc\n");
- return false;
+
+ for (i=0; i<1000000; i++) {
+ gencache_parse("foo", parse_fn, NULL);
}
- if (string_to_sid(&sid, "S-300-5-32-545")) {
- printf("allowing S-300-5-32-545\n");
- return false;
+
+ if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
+ d_printf("%s: gencache_get() failed\n", __location__);
+ return False;
}
- if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
- printf("allowing S-1-0xfffffffffffffe-32-545\n");
- return false;
+ TALLOC_FREE(val);
+
+ if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
+ d_printf("%s: gencache_get() failed\n", __location__);
+ return False;
}
- if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
- printf("allowing S-1-0xffffffffffff-5294967297-545\n");
- return false;
+
+ if (strcmp(val, "bar") != 0) {
+ d_printf("%s: gencache_get() returned %s, expected %s\n",
+ __location__, val, "bar");
+ TALLOC_FREE(val);
+ return False;
}
- if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
- printf("could not parse S-1-0xfffffffffffe-32-545\n");
- return false;
+
+ TALLOC_FREE(val);
+
+ if (!gencache_del("foo")) {
+ d_printf("%s: gencache_del() failed\n", __location__);
+ return False;
}
- if (!string_to_sid(&sid, "S-1-5-32-545")) {
- printf("could not parse S-1-5-32-545\n");
- return false;
+ if (gencache_del("foo")) {
+ d_printf("%s: second gencache_del() succeeded\n",
+ __location__);
+ 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",
- dom_sid_str_buf(&sid, &buf));
- return false;
+
+ if (gencache_get("foo", talloc_tos(), &val, &tm)) {
+ d_printf("%s: gencache_get() on deleted entry "
+ "succeeded\n", __location__);
+ return False;
}
- return true;
-}
-static bool sid_to_string_test(const char *expected) {
- char *str;
- bool res = true;
- struct dom_sid sid;
+ blob = data_blob_string_const_null("bar");
+ tm = time(NULL) + 60;
- if (!string_to_sid(&sid, expected)) {
- printf("could not parse %s\n", expected);
- return false;
+ if (!gencache_set_data_blob("foo", blob, tm)) {
+ d_printf("%s: gencache_set_data_blob() failed\n", __location__);
+ return False;
}
- str = dom_sid_string(NULL, &sid);
- if (strcmp(str, expected)) {
- printf("Comparison failed (%s != %s)\n", str, expected);
- res = false;
+ if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
+ d_printf("%s: gencache_get_data_blob() failed\n", __location__);
+ return False;
}
- TALLOC_FREE(str);
- return res;
-}
-static bool run_local_sid_to_string(int dummy) {
- if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
- return false;
- if (!sid_to_string_test("S-1-545"))
- return false;
- if (!sid_to_string_test("S-255-3840-1-1-1-1"))
- return false;
- return true;
-}
-
-static bool run_local_binary_to_sid(int dummy) {
- ssize_t ret;
- struct dom_sid *sid = talloc(NULL, struct dom_sid);
- static const uint8_t good_binary_sid[] = {
- 0x1, /* revision number */
- 15, /* num auths */
- 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
- 0x1, 0x1, 0x1, 0x1, /* auth[0] */
- 0x1, 0x1, 0x1, 0x1, /* auth[1] */
- 0x1, 0x1, 0x1, 0x1, /* auth[2] */
- 0x1, 0x1, 0x1, 0x1, /* auth[3] */
- 0x1, 0x1, 0x1, 0x1, /* auth[4] */
- 0x1, 0x1, 0x1, 0x1, /* auth[5] */
- 0x1, 0x1, 0x1, 0x1, /* auth[6] */
- 0x1, 0x1, 0x1, 0x1, /* auth[7] */
- 0x1, 0x1, 0x1, 0x1, /* auth[8] */
- 0x1, 0x1, 0x1, 0x1, /* auth[9] */
- 0x1, 0x1, 0x1, 0x1, /* auth[10] */
- 0x1, 0x1, 0x1, 0x1, /* auth[11] */
- 0x1, 0x1, 0x1, 0x1, /* auth[12] */
- 0x1, 0x1, 0x1, 0x1, /* auth[13] */
- 0x1, 0x1, 0x1, 0x1, /* auth[14] */
- };
+ if (strcmp((const char *)blob.data, "bar") != 0) {
+ d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
+ __location__, (const char *)blob.data, "bar");
+ data_blob_free(&blob);
+ return False;
+ }
- static const uint8_t long_binary_sid[] = {
- 0x1, /* revision number */
- 15, /* num auths */
- 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
- 0x1, 0x1, 0x1, 0x1, /* auth[0] */
- 0x1, 0x1, 0x1, 0x1, /* auth[1] */
- 0x1, 0x1, 0x1, 0x1, /* auth[2] */
- 0x1, 0x1, 0x1, 0x1, /* auth[3] */
- 0x1, 0x1, 0x1, 0x1, /* auth[4] */
- 0x1, 0x1, 0x1, 0x1, /* auth[5] */
- 0x1, 0x1, 0x1, 0x1, /* auth[6] */
- 0x1, 0x1, 0x1, 0x1, /* auth[7] */
- 0x1, 0x1, 0x1, 0x1, /* auth[8] */
- 0x1, 0x1, 0x1, 0x1, /* auth[9] */
- 0x1, 0x1, 0x1, 0x1, /* auth[10] */
- 0x1, 0x1, 0x1, 0x1, /* auth[11] */
- 0x1, 0x1, 0x1, 0x1, /* auth[12] */
- 0x1, 0x1, 0x1, 0x1, /* auth[13] */
- 0x1, 0x1, 0x1, 0x1, /* auth[14] */
- 0x1, 0x1, 0x1, 0x1, /* auth[15] */
- 0x1, 0x1, 0x1, 0x1, /* auth[16] */
- 0x1, 0x1, 0x1, 0x1, /* auth[17] */
- };
+ data_blob_free(&blob);
- static const uint8_t long_binary_sid2[] = {
- 0x1, /* revision number */
- 32, /* num auths */
- 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
- 0x1, 0x1, 0x1, 0x1, /* auth[0] */
- 0x1, 0x1, 0x1, 0x1, /* auth[1] */
- 0x1, 0x1, 0x1, 0x1, /* auth[2] */
- 0x1, 0x1, 0x1, 0x1, /* auth[3] */
- 0x1, 0x1, 0x1, 0x1, /* auth[4] */
- 0x1, 0x1, 0x1, 0x1, /* auth[5] */
- 0x1, 0x1, 0x1, 0x1, /* auth[6] */
- 0x1, 0x1, 0x1, 0x1, /* auth[7] */
- 0x1, 0x1, 0x1, 0x1, /* auth[8] */
- 0x1, 0x1, 0x1, 0x1, /* auth[9] */
- 0x1, 0x1, 0x1, 0x1, /* auth[10] */
- 0x1, 0x1, 0x1, 0x1, /* auth[11] */
- 0x1, 0x1, 0x1, 0x1, /* auth[12] */
- 0x1, 0x1, 0x1, 0x1, /* auth[13] */
- 0x1, 0x1, 0x1, 0x1, /* auth[14] */
- 0x1, 0x1, 0x1, 0x1, /* auth[15] */
- 0x1, 0x1, 0x1, 0x1, /* auth[16] */
- 0x1, 0x1, 0x1, 0x1, /* auth[17] */
- 0x1, 0x1, 0x1, 0x1, /* auth[18] */
- 0x1, 0x1, 0x1, 0x1, /* auth[19] */
- 0x1, 0x1, 0x1, 0x1, /* auth[20] */
- 0x1, 0x1, 0x1, 0x1, /* auth[21] */
- 0x1, 0x1, 0x1, 0x1, /* auth[22] */
- 0x1, 0x1, 0x1, 0x1, /* auth[23] */
- 0x1, 0x1, 0x1, 0x1, /* auth[24] */
- 0x1, 0x1, 0x1, 0x1, /* auth[25] */
- 0x1, 0x1, 0x1, 0x1, /* auth[26] */
- 0x1, 0x1, 0x1, 0x1, /* auth[27] */
- 0x1, 0x1, 0x1, 0x1, /* auth[28] */
- 0x1, 0x1, 0x1, 0x1, /* auth[29] */
- 0x1, 0x1, 0x1, 0x1, /* auth[30] */
- 0x1, 0x1, 0x1, 0x1, /* auth[31] */
- };
+ if (!gencache_del("foo")) {
+ d_printf("%s: gencache_del() failed\n", __location__);
+ return False;
+ }
+ if (gencache_del("foo")) {
+ d_printf("%s: second gencache_del() succeeded\n",
+ __location__);
+ return False;
+ }
- ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid);
- if (ret == -1) {
- return false;
+ if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
+ d_printf("%s: gencache_get_data_blob() on deleted entry "
+ "succeeded\n", __location__);
+ return False;
}
- ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid);
- if (ret != -1) {
+
+ v = 1;
+ blob.data = (uint8_t *)&v;
+ blob.length = sizeof(v);
+
+ if (!gencache_set_data_blob("blob", blob, tm)) {
+ d_printf("%s: gencache_set_data_blob() failed\n",
+ __location__);
return false;
}
- ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid);
- if (ret != -1) {
+ if (gencache_get("blob", talloc_tos(), &val, &tm)) {
+ d_printf("%s: gencache_get succeeded\n", __location__);
return false;
}
- return true;
-}
-/* Split a path name into filename and stream name components. Canonicalise
- * such that an implicit $DATA token is always explicit.
- *
- * The "specification" of this function can be found in the
- * run_local_stream_name() function in torture.c, I've tried those
- * combinations against a W2k3 server.
- */
+ return True;
+}
-static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
- char **pbase, char **pstream)
+static bool rbt_testflags(struct db_context *db, const char *key,
+ const char *value)
{
- char *base = NULL;
- char *stream = NULL;
- char *sname; /* stream name */
- const char *stype; /* stream type */
-
- DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
-
- sname = strchr_m(fname, ':');
+ bool ret = false;
+ NTSTATUS status;
+ struct db_record *rec;
- if (sname == NULL) {
- if (pbase != NULL) {
- base = talloc_strdup(mem_ctx, fname);
- NT_STATUS_HAVE_NO_MEMORY(base);
- }
+ rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
+ if (rec == NULL) {
+ d_fprintf(stderr, "fetch_locked failed\n");
goto done;
}
- if (pbase != NULL) {
- base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
- NT_STATUS_HAVE_NO_MEMORY(base);
- }
-
- sname += 1;
-
- stype = strchr_m(sname, ':');
-
- if (stype == NULL) {
- sname = talloc_strdup(mem_ctx, sname);
- stype = "$DATA";
- }
- else {
- if (strcasecmp_m(stype, ":$DATA") != 0) {
- /*
- * If there is an explicit stream type, so far we only
- * allow $DATA. Is there anything else allowed? -- vl
- */
- DEBUG(10, ("[%s] is an invalid stream type\n", stype));
- TALLOC_FREE(base);
- return NT_STATUS_OBJECT_NAME_INVALID;
- }
- sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
- stype += 1;
+ status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ d_fprintf(stderr, "store TDB_MODIFY unexpected status: %s\n",
+ nt_errstr(status));
+ goto done;
}
- if (sname == NULL) {
- TALLOC_FREE(base);
- return NT_STATUS_NO_MEMORY;
+ status = dbwrap_record_store(rec, string_tdb_data("overwriteme"),
+ TDB_INSERT);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "store TDB_INSERT failed: %s\n",
+ nt_errstr(status));
+ goto done;
}
- if (sname[0] == '\0') {
- /*
- * no stream name, so no stream
- */
+ status = dbwrap_record_store(rec, string_tdb_data(value), TDB_INSERT);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
+ d_fprintf(stderr, "store TDB_INSERT unexpected status: %s\n",
+ nt_errstr(status));
goto done;
}
- if (pstream != NULL) {
- stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
- if (stream == NULL) {
- TALLOC_FREE(sname);
- TALLOC_FREE(base);
- return NT_STATUS_NO_MEMORY;
- }
- /*
- * upper-case the type field
- */
- (void)strupper_m(strchr_m(stream, ':')+1);
+ status = dbwrap_record_store(rec, string_tdb_data(value), TDB_MODIFY);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "store TDB_MODIFY failed: %s\n",
+ nt_errstr(status));
+ goto done;
}
- done:
- if (pbase != NULL) {
- *pbase = base;
- }
- if (pstream != NULL) {
- *pstream = stream;
- }
- return NT_STATUS_OK;
+ ret = true;
+done:
+ TALLOC_FREE(rec);
+ return ret;
}
-static bool test_stream_name(const char *fname, const char *expected_base,
- const char *expected_stream,
- NTSTATUS expected_status)
+static bool rbt_testval(struct db_context *db, const char *key,
+ const char *value)
{
+ struct db_record *rec;
+ TDB_DATA data = string_tdb_data(value);
+ bool ret = false;
NTSTATUS status;
- char *base = NULL;
- char *stream = NULL;
+ TDB_DATA dbvalue;
- status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
- if (!NT_STATUS_EQUAL(status, expected_status)) {
- goto error;
+ rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
+ if (rec == NULL) {
+ d_fprintf(stderr, "fetch_locked failed\n");
+ goto done;
}
-
+ status = dbwrap_record_store(rec, data, 0);
if (!NT_STATUS_IS_OK(status)) {
- return true;
+ d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
+ goto done;
}
+ TALLOC_FREE(rec);
- if (base == NULL) goto error;
-
- if (strcmp(expected_base, base) != 0) goto error;
+ rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
+ if (rec == NULL) {
+ d_fprintf(stderr, "second fetch_locked failed\n");
+ goto done;
+ }
- if ((expected_stream != NULL) && (stream == NULL)) goto error;
- if ((expected_stream == NULL) && (stream != NULL)) goto error;
-
- if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
- goto error;
-
- TALLOC_FREE(base);
- TALLOC_FREE(stream);
- return true;
+ dbvalue = dbwrap_record_get_value(rec);
+ if ((dbvalue.dsize != data.dsize)
+ || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
+ d_fprintf(stderr, "Got wrong data back\n");
+ goto done;
+ }
- error:
- d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
- fname, expected_base ? expected_base : "<NULL>",
- expected_stream ? expected_stream : "<NULL>",
- nt_errstr(expected_status));
- d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
- base ? base : "<NULL>", stream ? stream : "<NULL>",
- nt_errstr(status));
- TALLOC_FREE(base);
- TALLOC_FREE(stream);
- return false;
+ ret = true;
+ done:
+ TALLOC_FREE(rec);
+ return ret;
}
-static bool run_local_stream_name(int dummy)
+static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
{
- bool ret = true;
-
- ret &= test_stream_name(
- "bla", "bla", NULL, NT_STATUS_OK);
- ret &= test_stream_name(
- "bla::$DATA", "bla", NULL, NT_STATUS_OK);
- ret &= test_stream_name(
- "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
- ret &= test_stream_name(
- "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
- ret &= test_stream_name(
- "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
- ret &= test_stream_name(
- "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
- ret &= test_stream_name(
- "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
- ret &= test_stream_name(
- "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
-
- return ret;
+ int *count2 = (int *)private_data;
+ (*count2)++;
+ return 0;
}
-static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
+static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
{
- if (a.length != b.length) {
- printf("a.length=%d != b.length=%d\n",
- (int)a.length, (int)b.length);
- return false;
- }
- if (memcmp(a.data, b.data, a.length) != 0) {
- printf("a.data and b.data differ\n");
- return false;
- }
- return true;
+ int *count2 = (int *)private_data;
+ (*count2)++;
+ dbwrap_record_delete(rec);
+ return 0;
}
-static bool run_local_memcache(int dummy)
+static bool run_local_rbtree(int dummy)
{
- struct memcache *cache;
- DATA_BLOB k1, k2, k3, k4, k5;
- DATA_BLOB d1, d3;
- DATA_BLOB v1, v3;
-
- TALLOC_CTX *mem_ctx;
- char *ptr1 = NULL;
- char *ptr2 = NULL;
- char *ptr3 = NULL;
-
- char *str1, *str2;
- size_t size1, size2;
+ struct db_context *db;
bool ret = false;
+ int i;
+ NTSTATUS status;
+ int count = 0;
+ int count2 = 0;
- mem_ctx = talloc_init("foo");
- if (mem_ctx == NULL) {
- return false;
- }
-
- /* STAT_CACHE TESTS */
-
- cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
+ db = db_open_rbt(NULL);
- if (cache == NULL) {
- printf("memcache_init failed\n");
+ if (db == NULL) {
+ d_fprintf(stderr, "db_open_rbt failed\n");
return false;
}
- d1 = data_blob_const("d1", 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);
- k4 = data_blob_const("d4", 2);
- k5 = data_blob_const("d5", 2);
-
- memcache_add(cache, STAT_CACHE, k1, d1);
-
- if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
- printf("could not find k1\n");
- return false;
- }
- if (!data_blob_equal(d1, v1)) {
- return false;
+ if (!rbt_testflags(db, "firstkey", "firstval")) {
+ goto done;
}
- memcache_add(cache, STAT_CACHE, k1, d3);
+ for (i = 0; i < 999; i++) {
+ char key[sizeof("key-9223372036854775807")];
+ char value[sizeof("value-9223372036854775807")];
- 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;
- }
+ snprintf(key, sizeof(key), "key%ld", random());
+ snprintf(value, sizeof(value) ,"value%ld", random());
- TALLOC_FREE(cache);
+ if (!rbt_testval(db, key, value)) {
+ goto done;
+ }
- /* GETWD_CACHE TESTS */
- str1 = talloc_strdup(mem_ctx, "string1");
- if (str1 == NULL) {
- return false;
- }
- ptr2 = str1; /* Keep an alias for comparison. */
+ snprintf(value, sizeof(value) ,"value%ld", random());
- str2 = talloc_strdup(mem_ctx, "string2");
- if (str2 == NULL) {
- return false;
+ if (!rbt_testval(db, key, value)) {
+ goto done;
+ }
}
- cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
- if (cache == NULL) {
- printf("memcache_init failed\n");
- return false;
+ ret = true;
+ count = 0; count2 = 0;
+ status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
+ &count2, &count);
+ printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
+ if ((count != count2) || (count != 1000)) {
+ ret = false;
}
-
- 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;
+ count = 0; count2 = 0;
+ status = dbwrap_traverse(db, local_rbtree_traverse_delete,
+ &count2, &count);
+ printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
+ if ((count != count2) || (count != 1000)) {
+ ret = false;
}
- if (ptr1 != ptr2) {
- printf("fetch of k2 got wrong string\n");
- return false;
+ count = 0; count2 = 0;
+ status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
+ &count2, &count);
+ printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
+ if ((count != count2) || (count != 0)) {
+ ret = false;
}
- /* Add a blob to ensure k2 gets purged. */
- d3 = data_blob_talloc_zero(mem_ctx, 180);
- memcache_add(cache, STAT_CACHE, k3, d3);
+ done:
+ TALLOC_FREE(db);
+ return ret;
+}
- ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
- if (ptr2 != NULL) {
- printf("Did find k2, should have been purged\n");
- return false;
- }
- /*
- * Test that talloc size also is accounted in memcache and
- * causes purge of other object.
- */
+/*
+ local test for character set functions
- str1 = talloc_zero_size(mem_ctx, 100);
- str2 = talloc_zero_size(mem_ctx, 100);
+ This is a very simple test for the functionality in convert_string_error()
+ */
+static bool run_local_convert_string(int dummy)
+{
+ TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+ const char *test_strings[2] = { "March", "M\303\244rz" };
+ char dst[7];
+ int i;
- memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
- memcache_add_talloc(cache, GETWD_CACHE, k5, &str1);
+ for (i=0; i<2; i++) {
+ const char *str = test_strings[i];
+ int len = strlen(str);
+ size_t converted_size;
+ bool ret;
- ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
- if (ptr3 != NULL) {
- printf("Did find k4, should have been purged\n");
- return false;
- }
+ memset(dst, 'X', sizeof(dst));
- /*
- * Test that adding a duplicate non-talloced
- * key/value on top of a talloced key/value takes account
- * of the talloc_freed value size.
- */
- TALLOC_FREE(cache);
- TALLOC_FREE(mem_ctx);
+ /* first try with real source length */
+ ret = convert_string_error(CH_UNIX, CH_UTF8,
+ str, len,
+ dst, sizeof(dst),
+ &converted_size);
+ if (ret != true) {
+ d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
+ goto failed;
+ }
- mem_ctx = talloc_init("key_replace");
- if (mem_ctx == NULL) {
- return false;
- }
+ if (converted_size != len) {
+ d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
+ str, len, (int)converted_size);
+ goto failed;
+ }
- cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
- if (cache == NULL) {
- return false;
- }
+ if (strncmp(str, dst, converted_size) != 0) {
+ d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
+ goto failed;
+ }
- /*
- * Add a 100 byte talloced string. This will
- * store a (4 or 8 byte) pointer and record the
- * total talloced size.
+ if (strlen(str) != converted_size) {
+ d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
+ (int)strlen(str), (int)converted_size);
+ goto failed;
+ }
+
+ if (dst[converted_size] != 'X') {
+ d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
+ goto failed;
+ }
+
+ /* now with srclen==-1, this causes the nul to be
+ * converted too */
+ ret = convert_string_error(CH_UNIX, CH_UTF8,
+ str, -1,
+ dst, sizeof(dst),
+ &converted_size);
+ if (ret != true) {
+ d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
+ goto failed;
+ }
+
+ if (converted_size != len+1) {
+ d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
+ str, len, (int)converted_size);
+ goto failed;
+ }
+
+ if (strncmp(str, dst, converted_size) != 0) {
+ d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
+ goto failed;
+ }
+
+ if (len+1 != converted_size) {
+ d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
+ len+1, (int)converted_size);
+ goto failed;
+ }
+
+ if (dst[converted_size] != 'X') {
+ d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
+ goto failed;
+ }
+
+ }
+
+
+ TALLOC_FREE(tmp_ctx);
+ return true;
+failed:
+ TALLOC_FREE(tmp_ctx);
+ return false;
+}
+
+static bool run_local_string_to_sid(int dummy) {
+ struct dom_sid sid;
+
+ if (string_to_sid(&sid, "S--1-5-32-545")) {
+ printf("allowing S--1-5-32-545\n");
+ return false;
+ }
+ if (string_to_sid(&sid, "S-1-5-32-+545")) {
+ printf("allowing S-1-5-32-+545\n");
+ return false;
+ }
+ if (string_to_sid(&sid, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
+ printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
+ return false;
+ }
+ if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
+ printf("allowing S-1-5-32-545-abc\n");
+ return false;
+ }
+ if (string_to_sid(&sid, "S-300-5-32-545")) {
+ printf("allowing S-300-5-32-545\n");
+ return false;
+ }
+ if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
+ printf("allowing S-1-0xfffffffffffffe-32-545\n");
+ return false;
+ }
+ if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
+ printf("allowing S-1-0xffffffffffff-5294967297-545\n");
+ return false;
+ }
+ if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
+ printf("could not parse S-1-0xfffffffffffe-32-545\n");
+ return false;
+ }
+ if (!string_to_sid(&sid, "S-1-5-32-545")) {
+ printf("could not parse S-1-5-32-545\n");
+ return false;
+ }
+ if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
+ struct dom_sid_buf buf;
+ printf("mis-parsed S-1-5-32-545 as %s\n",
+ dom_sid_str_buf(&sid, &buf));
+ return false;
+ }
+ return true;
+}
+
+static bool sid_to_string_test(const char *expected) {
+ char *str;
+ bool res = true;
+ struct dom_sid sid;
+
+ if (!string_to_sid(&sid, expected)) {
+ printf("could not parse %s\n", expected);
+ return false;
+ }
+
+ str = dom_sid_string(NULL, &sid);
+ if (strcmp(str, expected)) {
+ printf("Comparison failed (%s != %s)\n", str, expected);
+ res = false;
+ }
+ TALLOC_FREE(str);
+ return res;
+}
+
+static bool run_local_sid_to_string(int dummy) {
+ if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
+ return false;
+ if (!sid_to_string_test("S-1-545"))
+ return false;
+ if (!sid_to_string_test("S-255-3840-1-1-1-1"))
+ return false;
+ return true;
+}
+
+static bool run_local_binary_to_sid(int dummy) {
+ ssize_t ret;
+ struct dom_sid *sid = talloc(NULL, struct dom_sid);
+ static const uint8_t good_binary_sid[] = {
+ 0x1, /* revision number */
+ 15, /* num auths */
+ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
+ 0x1, 0x1, 0x1, 0x1, /* auth[0] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[1] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[2] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[3] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[4] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[5] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[6] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[7] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[8] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[9] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[10] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[11] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[12] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[13] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[14] */
+ };
+
+ static const uint8_t long_binary_sid[] = {
+ 0x1, /* revision number */
+ 15, /* num auths */
+ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
+ 0x1, 0x1, 0x1, 0x1, /* auth[0] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[1] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[2] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[3] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[4] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[5] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[6] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[7] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[8] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[9] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[10] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[11] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[12] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[13] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[14] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[15] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[16] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[17] */
+ };
+
+ static const uint8_t long_binary_sid2[] = {
+ 0x1, /* revision number */
+ 32, /* num auths */
+ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
+ 0x1, 0x1, 0x1, 0x1, /* auth[0] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[1] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[2] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[3] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[4] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[5] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[6] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[7] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[8] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[9] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[10] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[11] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[12] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[13] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[14] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[15] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[16] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[17] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[18] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[19] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[20] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[21] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[22] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[23] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[24] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[25] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[26] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[27] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[28] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[29] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[30] */
+ 0x1, 0x1, 0x1, 0x1, /* auth[31] */
+ };
+
+ ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid);
+ if (ret == -1) {
+ return false;
+ }
+ ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid);
+ if (ret != -1) {
+ return false;
+ }
+ ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid);
+ if (ret != -1) {
+ return false;
+ }
+ return true;
+}
+
+/* Split a path name into filename and stream name components. Canonicalise
+ * such that an implicit $DATA token is always explicit.
+ *
+ * The "specification" of this function can be found in the
+ * run_local_stream_name() function in torture.c, I've tried those
+ * combinations against a W2k3 server.
+ */
+
+static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
+ char **pbase, char **pstream)
+{
+ char *base = NULL;
+ char *stream = NULL;
+ char *sname; /* stream name */
+ const char *stype; /* stream type */
+
+ DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
+
+ sname = strchr_m(fname, ':');
+
+ if (sname == NULL) {
+ if (pbase != NULL) {
+ base = talloc_strdup(mem_ctx, fname);
+ NT_STATUS_HAVE_NO_MEMORY(base);
+ }
+ goto done;
+ }
+
+ if (pbase != NULL) {
+ base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
+ NT_STATUS_HAVE_NO_MEMORY(base);
+ }
+
+ sname += 1;
+
+ stype = strchr_m(sname, ':');
+
+ if (stype == NULL) {
+ sname = talloc_strdup(mem_ctx, sname);
+ stype = "$DATA";
+ }
+ else {
+ if (strcasecmp_m(stype, ":$DATA") != 0) {
+ /*
+ * If there is an explicit stream type, so far we only
+ * allow $DATA. Is there anything else allowed? -- vl
+ */
+ DEBUG(10, ("[%s] is an invalid stream type\n", stype));
+ TALLOC_FREE(base);
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
+ stype += 1;
+ }
+
+ if (sname == NULL) {
+ TALLOC_FREE(base);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (sname[0] == '\0') {
+ /*
+ * no stream name, so no stream
+ */
+ goto done;
+ }
+
+ if (pstream != NULL) {
+ stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
+ if (stream == NULL) {
+ TALLOC_FREE(sname);
+ TALLOC_FREE(base);
+ return NT_STATUS_NO_MEMORY;
+ }
+ /*
+ * upper-case the type field
+ */
+ (void)strupper_m(strchr_m(stream, ':')+1);
+ }
+
+ done:
+ if (pbase != NULL) {
+ *pbase = base;
+ }
+ if (pstream != NULL) {
+ *pstream = stream;
+ }
+ return NT_STATUS_OK;
+}
+
+static bool test_stream_name(const char *fname, const char *expected_base,
+ const char *expected_stream,
+ NTSTATUS expected_status)
+{
+ NTSTATUS status;
+ char *base = NULL;
+ char *stream = NULL;
+
+ status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
+ if (!NT_STATUS_EQUAL(status, expected_status)) {
+ goto error;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return true;
+ }
+
+ if (base == NULL) goto error;
+
+ if (strcmp(expected_base, base) != 0) goto error;
+
+ if ((expected_stream != NULL) && (stream == NULL)) goto error;
+ if ((expected_stream == NULL) && (stream != NULL)) goto error;
+
+ if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
+ goto error;
+
+ TALLOC_FREE(base);
+ TALLOC_FREE(stream);
+ return true;
+
+ error:
+ d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
+ fname, expected_base ? expected_base : "<NULL>",
+ expected_stream ? expected_stream : "<NULL>",
+ nt_errstr(expected_status));
+ d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
+ base ? base : "<NULL>", stream ? stream : "<NULL>",
+ nt_errstr(status));
+ TALLOC_FREE(base);
+ TALLOC_FREE(stream);
+ return false;
+}
+
+static bool run_local_stream_name(int dummy)
+{
+ bool ret = true;
+
+ ret &= test_stream_name(
+ "bla", "bla", NULL, NT_STATUS_OK);
+ ret &= test_stream_name(
+ "bla::$DATA", "bla", NULL, NT_STATUS_OK);
+ ret &= test_stream_name(
+ "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
+ ret &= test_stream_name(
+ "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
+ ret &= test_stream_name(
+ "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
+ ret &= test_stream_name(
+ "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
+ ret &= test_stream_name(
+ "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
+ ret &= test_stream_name(
+ "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
+
+ return ret;
+}
+
+static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
+{
+ if (a.length != b.length) {
+ printf("a.length=%d != b.length=%d\n",
+ (int)a.length, (int)b.length);
+ return false;
+ }
+ if (memcmp(a.data, b.data, a.length) != 0) {
+ printf("a.data and b.data differ\n");
+ return false;
+ }
+ return true;
+}
+
+static bool run_local_memcache(int dummy)
+{
+ struct memcache *cache;
+ DATA_BLOB k1, k2, k3, k4, k5;
+ DATA_BLOB d1, d3;
+ DATA_BLOB v1, v3;
+
+ TALLOC_CTX *mem_ctx;
+ char *ptr1 = NULL;
+ char *ptr2 = NULL;
+ char *ptr3 = 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) {
+ printf("memcache_init failed\n");
+ return false;
+ }
+
+ d1 = data_blob_const("d1", 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);
+ k4 = data_blob_const("d4", 2);
+ k5 = data_blob_const("d5", 2);
+
+ memcache_add(cache, STAT_CACHE, k1, d1);
+
+ if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
+ printf("could not find k1\n");
+ return false;
+ }
+ if (!data_blob_equal(d1, v1)) {
+ return false;
+ }
+
+ 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;
+ }
+
+ TALLOC_FREE(cache);
+
+ /* GETWD_CACHE TESTS */
+ str1 = talloc_strdup(mem_ctx, "string1");
+ if (str1 == NULL) {
+ return false;
+ }
+ ptr2 = str1; /* Keep an alias for comparison. */
+
+ str2 = talloc_strdup(mem_ctx, "string2");
+ if (str2 == NULL) {
+ return false;
+ }
+
+ cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
+ if (cache == NULL) {
+ printf("memcache_init failed\n");
+ return false;
+ }
+
+ 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;
+ }
+
+ /* Add a blob to ensure k2 gets purged. */
+ d3 = data_blob_talloc_zero(mem_ctx, 180);
+ memcache_add(cache, STAT_CACHE, k3, d3);
+
+ ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
+ if (ptr2 != NULL) {
+ printf("Did find k2, should have been purged\n");
+ return false;
+ }
+
+ /*
+ * Test that talloc size also is accounted in memcache and
+ * causes purge of other object.
+ */
+
+ str1 = talloc_zero_size(mem_ctx, 100);
+ str2 = talloc_zero_size(mem_ctx, 100);
+
+ memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
+ memcache_add_talloc(cache, GETWD_CACHE, k5, &str1);
+
+ ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
+ if (ptr3 != NULL) {
+ printf("Did find k4, should have been purged\n");
+ return false;
+ }
+
+ /*
+ * Test that adding a duplicate non-talloced
+ * key/value on top of a talloced key/value takes account
+ * of the talloc_freed value size.
+ */
+ TALLOC_FREE(cache);
+ TALLOC_FREE(mem_ctx);
+
+ mem_ctx = talloc_init("key_replace");
+ if (mem_ctx == NULL) {
+ return false;
+ }
+
+ cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
+ if (cache == NULL) {
+ return false;
+ }
+
+ /*
+ * Add a 100 byte talloced string. This will
+ * store a (4 or 8 byte) pointer and record the
+ * total talloced size.
*/
str1 = talloc_zero_size(mem_ctx, 100);
memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
str2 = talloc_zero_size(mem_ctx, 20);
memcache_add_talloc(cache, GETWD_CACHE, k5, &str2);
- ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
- if (ptr3 == NULL) {
- printf("Did not find k4, should not have been purged\n");
+ ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
+ if (ptr3 == NULL) {
+ printf("Did not find k4, should not have been purged\n");
+ return false;
+ }
+
+ TALLOC_FREE(cache);
+ 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);
+
+ memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
+ data_blob_string_const("torture"), &str2);
+ size2 = talloc_total_size(cache);
+
+ printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
+
+ if (size2 > size1) {
+ printf("memcache leaks memory!\n");
+ goto fail;
+ }
+
+ ret = true;
+ fail:
+ TALLOC_FREE(cache);
+ return ret;
+}
+
+static void wbclient_done(struct tevent_req *req)
+{
+ wbcErr wbc_err;
+ struct winbindd_response *wb_resp;
+ int *i = (int *)tevent_req_callback_data_void(req);
+
+ wbc_err = wb_trans_recv(req, req, &wb_resp);
+ TALLOC_FREE(req);
+ *i += 1;
+ d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
+}
+
+static bool run_wbclient_multi_ping(int dummy)
+{
+ struct tevent_context *ev;
+ struct wb_context **wb_ctx;
+ struct winbindd_request wb_req;
+ bool result = false;
+ int i, j;
+
+ BlockSignals(True, SIGPIPE);
+
+ ev = tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ goto fail;
+ }
+
+ wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
+ if (wb_ctx == NULL) {
+ goto fail;
+ }
+
+ ZERO_STRUCT(wb_req);
+ wb_req.cmd = WINBINDD_PING;
+
+ d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
+
+ for (i=0; i<torture_nprocs; i++) {
+ wb_ctx[i] = wb_context_init(ev, NULL);
+ if (wb_ctx[i] == NULL) {
+ goto fail;
+ }
+ for (j=0; j<torture_numops; j++) {
+ struct tevent_req *req;
+ req = wb_trans_send(ev, ev, wb_ctx[i],
+ (j % 2) == 0, &wb_req);
+ if (req == NULL) {
+ goto fail;
+ }
+ tevent_req_set_callback(req, wbclient_done, &i);
+ }
+ }
+
+ i = 0;
+
+ while (i < torture_nprocs * torture_numops) {
+ tevent_loop_once(ev);
+ }
+
+ result = true;
+ fail:
+ TALLOC_FREE(ev);
+ return result;
+}
+
+static bool dbtrans_inc(struct db_context *db)
+{
+ struct db_record *rec;
+ uint32_t val;
+ bool ret = false;
+ NTSTATUS status;
+ TDB_DATA value;
+
+ rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
+ if (rec == NULL) {
+ printf(__location__ "fetch_lock failed\n");
return false;
}
- TALLOC_FREE(cache);
- TALLOC_FREE(mem_ctx);
+ value = dbwrap_record_get_value(rec);
- mem_ctx = talloc_init("foo");
- if (mem_ctx == NULL) {
- return false;
+ if (value.dsize != sizeof(uint32_t)) {
+ printf(__location__ "value.dsize = %d\n",
+ (int)value.dsize);
+ goto fail;
}
- cache = memcache_init(NULL, 0);
- if (cache == NULL) {
+ memcpy(&val, value.dptr, sizeof(val));
+ val += 1;
+
+ status = dbwrap_record_store(
+ rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf(__location__ "store failed: %s\n",
+ nt_errstr(status));
+ goto fail;
+ }
+
+ ret = true;
+fail:
+ TALLOC_FREE(rec);
+ return ret;
+}
+
+static bool run_local_dbtrans(int dummy)
+{
+ struct db_context *db;
+ struct db_record *rec;
+ NTSTATUS status;
+ uint32_t initial;
+ int res;
+ TDB_DATA value;
+
+ db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
+ O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
+ DBWRAP_FLAG_NONE);
+ if (db == NULL) {
+ printf("Could not open transtest.db\n");
return false;
}
- str1 = talloc_strdup(mem_ctx, "string1");
- if (str1 == NULL) {
+ res = dbwrap_transaction_start(db);
+ if (res != 0) {
+ printf(__location__ "transaction_start failed\n");
return false;
}
- str2 = talloc_strdup(mem_ctx, "string2");
- if (str2 == NULL) {
+
+ rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
+ if (rec == NULL) {
+ printf(__location__ "fetch_lock failed\n");
return false;
}
- memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
- data_blob_string_const("torture"), &str1);
- size1 = talloc_total_size(cache);
- memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
- data_blob_string_const("torture"), &str2);
- size2 = talloc_total_size(cache);
+ value = dbwrap_record_get_value(rec);
- printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
+ if (value.dptr == NULL) {
+ initial = 0;
+ status = dbwrap_record_store(
+ rec, make_tdb_data((uint8_t *)&initial,
+ sizeof(initial)),
+ 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf(__location__ "store returned %s\n",
+ nt_errstr(status));
+ return false;
+ }
+ }
- if (size2 > size1) {
- printf("memcache leaks memory!\n");
- goto fail;
+ TALLOC_FREE(rec);
+
+ res = dbwrap_transaction_commit(db);
+ if (res != 0) {
+ printf(__location__ "transaction_commit failed\n");
+ return false;
}
- ret = true;
- fail:
- TALLOC_FREE(cache);
- return ret;
-}
+ while (true) {
+ uint32_t val, val2;
+ int i;
-static void wbclient_done(struct tevent_req *req)
-{
- wbcErr wbc_err;
- struct winbindd_response *wb_resp;
- int *i = (int *)tevent_req_callback_data_void(req);
+ res = dbwrap_transaction_start(db);
+ if (res != 0) {
+ printf(__location__ "transaction_start failed\n");
+ break;
+ }
- wbc_err = wb_trans_recv(req, req, &wb_resp);
- TALLOC_FREE(req);
- *i += 1;
- d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
+ status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
+ nt_errstr(status));
+ break;
+ }
+
+ for (i=0; i<10; i++) {
+ if (!dbtrans_inc(db)) {
+ return false;
+ }
+ }
+
+ status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
+ nt_errstr(status));
+ break;
+ }
+
+ if (val2 != val + 10) {
+ printf(__location__ "val=%d, val2=%d\n",
+ (int)val, (int)val2);
+ break;
+ }
+
+ printf("val2=%d\r", val2);
+
+ res = dbwrap_transaction_commit(db);
+ if (res != 0) {
+ printf(__location__ "transaction_commit failed\n");
+ break;
+ }
+ }
+
+ TALLOC_FREE(db);
+ return true;
}
-static bool run_wbclient_multi_ping(int dummy)
+/*
+ * Just a dummy test to be run under a debugger. There's no real way
+ * to inspect the tevent_poll specific function from outside of
+ * tevent_poll.c.
+ */
+
+static bool run_local_tevent_poll(int dummy)
{
struct tevent_context *ev;
- struct wb_context **wb_ctx;
- struct winbindd_request wb_req;
+ struct tevent_fd *fd1, *fd2;
bool result = false;
- int i, j;
-
- BlockSignals(True, SIGPIPE);
- ev = tevent_context_init(talloc_tos());
+ ev = tevent_context_init_byname(NULL, "poll");
if (ev == NULL) {
+ d_fprintf(stderr, "tevent_context_init_byname failed\n");
goto fail;
}
- wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
- if (wb_ctx == NULL) {
+ fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
+ if (fd1 == NULL) {
+ d_fprintf(stderr, "tevent_add_fd failed\n");
goto fail;
}
+ fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
+ if (fd2 == NULL) {
+ d_fprintf(stderr, "tevent_add_fd failed\n");
+ goto fail;
+ }
+ TALLOC_FREE(fd2);
+
+ fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
+ if (fd2 == NULL) {
+ d_fprintf(stderr, "tevent_add_fd failed\n");
+ goto fail;
+ }
+
+ result = true;
+fail:
+ TALLOC_FREE(ev);
+ return result;
+}
+
+static bool run_local_hex_encode_buf(int dummy)
+{
+ char buf[17];
+ uint8_t src[8];
+ size_t i;
+
+ for (i=0; i<sizeof(src); i++) {
+ src[i] = i;
+ }
+ hex_encode_buf(buf, src, sizeof(src));
+ if (strcmp(buf, "0001020304050607") != 0) {
+ return false;
+ }
+ hex_encode_buf(buf, NULL, 0);
+ if (buf[0] != '\0') {
+ return false;
+ }
+ return true;
+}
+
+static const char *remove_duplicate_addrs2_test_strings_vector[] = {
+ "0.0.0.0",
+ "::0",
+ "1.2.3.1",
+ "0.0.0.0",
+ "0.0.0.0",
+ "1.2.3.2",
+ "1.2.3.3",
+ "1.2.3.4",
+ "1.2.3.5",
+ "::0",
+ "1.2.3.6",
+ "1.2.3.7",
+ "::0",
+ "::0",
+ "::0",
+ "1.2.3.8",
+ "1.2.3.9",
+ "1.2.3.10",
+ "1.2.3.11",
+ "1.2.3.12",
+ "1.2.3.13",
+ "1001:1111:1111:1000:0:1111:1111:1111",
+ "1.2.3.1",
+ "1.2.3.2",
+ "1.2.3.3",
+ "1.2.3.12",
+ "::0",
+ "::0"
+};
+
+static const char *remove_duplicate_addrs2_test_strings_result[] = {
+ "1.2.3.1",
+ "1.2.3.2",
+ "1.2.3.3",
+ "1.2.3.4",
+ "1.2.3.5",
+ "1.2.3.6",
+ "1.2.3.7",
+ "1.2.3.8",
+ "1.2.3.9",
+ "1.2.3.10",
+ "1.2.3.11",
+ "1.2.3.12",
+ "1.2.3.13",
+ "1001:1111:1111:1000:0:1111:1111:1111"
+};
- ZERO_STRUCT(wb_req);
- wb_req.cmd = WINBINDD_PING;
+static bool run_local_remove_duplicate_addrs2(int dummy)
+{
+ struct samba_sockaddr test_vector[28];
+ size_t count, i;
- d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
+ /* Construct the sockaddr_storage test vector. */
+ for (i = 0; i < 28; i++) {
+ struct addrinfo hints;
+ struct addrinfo *res = NULL;
+ int ret;
- for (i=0; i<torture_nprocs; i++) {
- wb_ctx[i] = wb_context_init(ev, NULL);
- if (wb_ctx[i] == NULL) {
- goto fail;
- }
- for (j=0; j<torture_numops; j++) {
- struct tevent_req *req;
- req = wb_trans_send(ev, ev, wb_ctx[i],
- (j % 2) == 0, &wb_req);
- if (req == NULL) {
- goto fail;
- }
- tevent_req_set_callback(req, wbclient_done, &i);
+ memset(&hints, '\0', sizeof(hints));
+ hints.ai_flags = AI_NUMERICHOST;
+ ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
+ NULL,
+ &hints,
+ &res);
+ if (ret) {
+ fprintf(stderr, "getaddrinfo failed on [%s]\n",
+ remove_duplicate_addrs2_test_strings_vector[i]);
+ return false;
}
+ memset(&test_vector[i], '\0', sizeof(test_vector[i]));
+ memcpy(&test_vector[i].u.ss,
+ res->ai_addr,
+ res->ai_addrlen);
+ freeaddrinfo(res);
}
- i = 0;
-
- while (i < torture_nprocs * torture_numops) {
- tevent_loop_once(ev);
- }
-
- result = true;
- fail:
- TALLOC_FREE(ev);
- return result;
-}
-
-static bool dbtrans_inc(struct db_context *db)
-{
- struct db_record *rec;
- uint32_t val;
- bool ret = false;
- NTSTATUS status;
- TDB_DATA value;
+ count = remove_duplicate_addrs2(test_vector, i);
- rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
- if (rec == NULL) {
- printf(__location__ "fetch_lock failed\n");
+ if (count != 14) {
+ fprintf(stderr, "count wrong (%zu) should be 14\n",
+ count);
return false;
}
- value = dbwrap_record_get_value(rec);
-
- if (value.dsize != sizeof(uint32_t)) {
- printf(__location__ "value.dsize = %d\n",
- (int)value.dsize);
- goto fail;
- }
+ for (i = 0; i < count; i++) {
+ char addr[INET6_ADDRSTRLEN];
- memcpy(&val, value.dptr, sizeof(val));
- val += 1;
+ print_sockaddr(addr, sizeof(addr), &test_vector[i].u.ss);
- status = dbwrap_record_store(
- rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
- if (!NT_STATUS_IS_OK(status)) {
- printf(__location__ "store failed: %s\n",
- nt_errstr(status));
- goto fail;
+ if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
+ fprintf(stderr, "mismatch on [%zu] [%s] [%s]\n",
+ i,
+ addr,
+ remove_duplicate_addrs2_test_strings_result[i]);
+ return false;
+ }
}
- ret = true;
-fail:
- TALLOC_FREE(rec);
- return ret;
+ printf("run_local_remove_duplicate_addrs2: success\n");
+ return true;
}
-static bool run_local_dbtrans(int dummy)
+static bool run_local_tdb_opener(int dummy)
{
- struct db_context *db;
- struct db_record *rec;
- NTSTATUS status;
- uint32_t initial;
- int res;
- TDB_DATA value;
-
- db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
- O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
- DBWRAP_FLAG_NONE);
- if (db == NULL) {
- printf("Could not open transtest.db\n");
- return false;
- }
-
- res = dbwrap_transaction_start(db);
- if (res != 0) {
- printf(__location__ "transaction_start failed\n");
- return false;
- }
-
- rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
- if (rec == NULL) {
- printf(__location__ "fetch_lock failed\n");
- return false;
- }
-
- value = dbwrap_record_get_value(rec);
+ TDB_CONTEXT *t;
+ unsigned v = 0;
- if (value.dptr == NULL) {
- initial = 0;
- status = dbwrap_record_store(
- rec, make_tdb_data((uint8_t *)&initial,
- sizeof(initial)),
- 0);
- if (!NT_STATUS_IS_OK(status)) {
- printf(__location__ "store returned %s\n",
- nt_errstr(status));
+ while (1) {
+ t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
+ O_RDWR|O_CREAT, 0755);
+ if (t == NULL) {
+ perror("tdb_open failed");
return false;
}
+ tdb_close(t);
+
+ v += 1;
+ printf("\r%u", v);
}
+ return true;
+}
- TALLOC_FREE(rec);
+static bool run_local_tdb_writer(int dummy)
+{
+ TDB_CONTEXT *t;
+ unsigned v = 0;
+ TDB_DATA val;
- res = dbwrap_transaction_commit(db);
- if (res != 0) {
- printf(__location__ "transaction_commit failed\n");
- return false;
+ t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
+ if (t == 0) {
+ perror("tdb_open failed");
+ return 1;
}
- while (true) {
- uint32_t val, val2;
- int i;
+ val.dptr = (uint8_t *)&v;
+ val.dsize = sizeof(v);
- res = dbwrap_transaction_start(db);
- if (res != 0) {
- printf(__location__ "transaction_start failed\n");
- break;
+ while (1) {
+ TDB_DATA data;
+ int ret;
+
+ ret = tdb_store(t, val, val, 0);
+ if (ret != 0) {
+ printf("%s\n", tdb_errorstr(t));
}
+ v += 1;
+ printf("\r%u", v);
- status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
- if (!NT_STATUS_IS_OK(status)) {
- printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
- nt_errstr(status));
- break;
+ data = tdb_fetch(t, val);
+ if (data.dptr != NULL) {
+ SAFE_FREE(data.dptr);
}
+ }
+ return true;
+}
+
+static bool run_local_canonicalize_path(int dummy)
+{
+ const char *src[] = {
+ "/foo/..",
+ "/..",
+ "/foo/bar/../baz",
+ "/foo/././",
+ "/../foo",
+ ".././././",
+ ".././././../../../boo",
+ "./..",
+ "/",
+ "/../../",
+ "/foo/../",
+ "/./././",
+ "/./././.",
+ "/.../././.",
+ "/./././.foo",
+ "/./././.foo.",
+ "/./././foo.",
+ "/foo/bar/..",
+ "/foo/bar/../baz/",
+ "////////////////",
+ "/////////./././././.",
+ "/./.././../.boo/../baz",
+ "/a/component/path",
+ "/a/component/path/",
+ "/a/component/path/..",
+ "/a/component/../path/",
+ "///a/./././///component/../////path/",
+ NULL
+ };
+ const char *dst[] = {
+ "/",
+ "/",
+ "/foo/baz",
+ "/foo",
+ "/foo",
+ "/",
+ "/boo",
+ "/",
+ "/",
+ "/",
+ "/",
+ "/",
+ "/",
+ "/...",
+ "/.foo",
+ "/.foo.",
+ "/foo.",
+ "/foo",
+ "/foo/baz",
+ "/",
+ "/",
+ "/baz",
+ "/a/component/path",
+ "/a/component/path",
+ "/a/component",
+ "/a/path",
+ "/a/path",
+ NULL
+ };
+ unsigned int i;
- for (i=0; i<10; i++) {
- if (!dbtrans_inc(db)) {
- return false;
- }
+ for (i = 0; src[i] != NULL; i++) {
+ char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
+ if (d == NULL) {
+ perror("talloc fail\n");
+ return false;
}
-
- status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
- if (!NT_STATUS_IS_OK(status)) {
- printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
- nt_errstr(status));
- break;
+ if (strcmp(d, dst[i]) != 0) {
+ d_fprintf(stderr,
+ "canonicalize mismatch %s -> %s != %s",
+ src[i], d, dst[i]);
+ return false;
}
+ talloc_free(d);
+ }
+ return true;
+}
+struct session_setup_nt1_truncated_state {
+ uint16_t vwv[13];
+ uint8_t bytes[20];
+};
- if (val2 != val + 10) {
- printf(__location__ "val=%d, val2=%d\n",
- (int)val, (int)val2);
- break;
- }
+static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq);
- printf("val2=%d\r", val2);
+static struct tevent_req *smb1_session_setup_nt1_truncated_send(
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct smbXcli_conn *conn)
+{
+ uint16_t *vwv = NULL;
+ uint8_t *bytes = NULL;
+ const char *pass = "12345678";
+ const char *uname = "z";
+ struct session_setup_nt1_truncated_state *state = NULL;
+ struct tevent_req *req = NULL;
+ struct tevent_req *subreq = NULL;
- res = dbwrap_transaction_commit(db);
- if (res != 0) {
- printf(__location__ "transaction_commit failed\n");
- break;
- }
+ req = tevent_req_create(mem_ctx,
+ &state,
+ struct session_setup_nt1_truncated_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ vwv = &state->vwv[0];
+ bytes = &state->bytes[0];
+
+ SCVAL(vwv+0, 0, 0xff);
+ SCVAL(vwv+0, 1, 0);
+ SSVAL(vwv+1, 0, 0);
+ SSVAL(vwv+2, 0, 8192);
+ SSVAL(vwv+3, 0, 2);
+ SSVAL(vwv+4, 0, 1);
+ SIVAL(vwv+5, 0, 0);
+ SSVAL(vwv+7, 0, strlen(pass)); /* OEMPasswordLen */
+ SSVAL(vwv+8, 0, 0); /* UnicodePasswordLen */
+ SSVAL(vwv+9, 0, 0); /* reserved */
+ SSVAL(vwv+10, 0, 0); /* reserved */
+ SIVAL(vwv+11, 0, CAP_STATUS32);
+
+ memcpy(bytes, pass, strlen(pass));
+ bytes += strlen(pass);
+ memcpy(bytes, uname, strlen(uname)+1);
+
+ subreq = smb1cli_req_send(state, ev, conn,
+ SMBsesssetupX,
+ 0, /* additional_flags */
+ 0, /* clear_flags */
+ 0, /* additional_flags2 */
+ 0, /* clear_flags2 */
+ 10000, /* timeout_msec */
+ getpid(),
+ NULL, /* tcon */
+ NULL, /* session */
+ 13, /* wct */
+ state->vwv,
+ strlen(pass), /* Truncate length at password. */
+ state->bytes);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
+ tevent_req_set_callback(subreq,
+ smb1_session_setup_nt1_truncated_done,
+ req);
+ return req;
+}
- TALLOC_FREE(db);
- return true;
+static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req =
+ tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct session_setup_nt1_truncated_state *state =
+ tevent_req_data(req,
+ struct session_setup_nt1_truncated_state);
+ NTSTATUS status;
+ struct smb1cli_req_expected_response expected[] = {
+ {
+ .status = NT_STATUS_OK,
+ .wct = 3,
+ },
+ };
+
+ status = smb1cli_req_recv(subreq, state,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* pvwv_offset */
+ NULL,
+ NULL,
+ NULL, /* pbytes_offset */
+ NULL,
+ expected, ARRAY_SIZE(expected));
+ TALLOC_FREE(subreq);
+ if (tevent_req_nterror(req, status)) {
+ return;
+ }
+ tevent_req_done(req);
}
-/*
- * Just a dummy test to be run under a debugger. There's no real way
- * to inspect the tevent_poll specific function from outside of
- * tevent_poll.c.
- */
+static NTSTATUS smb1_session_setup_nt1_truncated_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
-static bool run_local_tevent_poll(int dummy)
+static bool run_smb1_truncated_sesssetup(int dummy)
{
struct tevent_context *ev;
- struct tevent_fd *fd1, *fd2;
- bool result = false;
+ struct tevent_req *req;
+ struct smbXcli_conn *conn;
+ struct sockaddr_storage ss;
+ NTSTATUS status;
+ int fd;
+ bool ok;
- ev = tevent_context_init_byname(NULL, "poll");
- if (ev == NULL) {
- d_fprintf(stderr, "tevent_context_init_byname failed\n");
- goto fail;
- }
+ printf("Starting send truncated SMB1 sesssetup.\n");
- fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
- if (fd1 == NULL) {
- d_fprintf(stderr, "tevent_add_fd failed\n");
- goto fail;
+ ok = resolve_name(host, &ss, 0x20, true);
+ if (!ok) {
+ d_fprintf(stderr, "Could not resolve name %s\n", host);
+ return false;
}
- fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
- if (fd2 == NULL) {
- d_fprintf(stderr, "tevent_add_fd failed\n");
- goto fail;
+
+ 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;
}
- TALLOC_FREE(fd2);
- fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
- if (fd2 == NULL) {
- d_fprintf(stderr, "tevent_add_fd failed\n");
- goto fail;
+ conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
+ NULL, 0, NULL);
+ if (conn == NULL) {
+ d_fprintf(stderr, "smbXcli_conn_create failed\n");
+ return false;
}
- result = true;
-fail:
- TALLOC_FREE(ev);
- return result;
-}
+ status = smbXcli_negprot(conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "smbXcli_negprot failed!\n");
+ return false;
+ }
-static bool run_local_hex_encode_buf(int dummy)
-{
- char buf[17];
- uint8_t src[8];
- int i;
+ ev = samba_tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ d_fprintf(stderr, "samba_tevent_context_init failed\n");
+ return false;
+ }
- for (i=0; i<sizeof(src); i++) {
- src[i] = i;
+ req = smb1_session_setup_nt1_truncated_send(ev, ev, conn);
+ if (req == NULL) {
+ d_fprintf(stderr, "smb1_session_setup_nt1_truncated_send failed\n");
+ return false;
}
- hex_encode_buf(buf, src, sizeof(src));
- if (strcmp(buf, "0001020304050607") != 0) {
- return false;
+
+ ok = tevent_req_poll_ntstatus(req, ev, &status);
+ if (!ok) {
+ d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
+ nt_errstr(status));
+ return false;
}
- hex_encode_buf(buf, NULL, 0);
- if (buf[0] != '\0') {
+
+ status = smb1_session_setup_nt1_truncated_recv(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "smb1_session_setup_nt1_truncated_recv returned "
+ "%s, expected NT_STATUS_OK\n",
+ nt_errstr(status));
return false;
}
+
+ TALLOC_FREE(conn);
return true;
}
-static const char *remove_duplicate_addrs2_test_strings_vector[] = {
- "0.0.0.0",
- "::0",
- "1.2.3.1",
- "0.0.0.0",
- "0.0.0.0",
- "1.2.3.2",
- "1.2.3.3",
- "1.2.3.4",
- "1.2.3.5",
- "::0",
- "1.2.3.6",
- "1.2.3.7",
- "::0",
- "::0",
- "::0",
- "1.2.3.8",
- "1.2.3.9",
- "1.2.3.10",
- "1.2.3.11",
- "1.2.3.12",
- "1.2.3.13",
- "1001:1111:1111:1000:0:1111:1111:1111",
- "1.2.3.1",
- "1.2.3.2",
- "1.2.3.3",
- "1.2.3.12",
- "::0",
- "::0"
+struct smb1_negotiate_exit_state {
+ int dummy;
};
-static const char *remove_duplicate_addrs2_test_strings_result[] = {
- "1.2.3.1",
- "1.2.3.2",
- "1.2.3.3",
- "1.2.3.4",
- "1.2.3.5",
- "1.2.3.6",
- "1.2.3.7",
- "1.2.3.8",
- "1.2.3.9",
- "1.2.3.10",
- "1.2.3.11",
- "1.2.3.12",
- "1.2.3.13",
- "1001:1111:1111:1000:0:1111:1111:1111"
-};
+static void smb1_negotiate_exit_done(struct tevent_req *subreq);
-static bool run_local_remove_duplicate_addrs2(int dummy)
+static struct tevent_req *smb1_negotiate_exit_send(
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct smbXcli_conn *conn)
{
- struct ip_service test_vector[28];
- int count, i;
-
- /* Construct the sockaddr_storage test vector. */
- for (i = 0; i < 28; i++) {
- struct addrinfo hints;
- struct addrinfo *res = NULL;
- int ret;
+ struct smb1_negotiate_exit_state *state = NULL;
+ struct tevent_req *req = NULL;
+ struct tevent_req *subreq = NULL;
- memset(&hints, '\0', sizeof(hints));
- hints.ai_flags = AI_NUMERICHOST;
- ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
- NULL,
- &hints,
- &res);
- if (ret) {
- fprintf(stderr, "getaddrinfo failed on [%s]\n",
- remove_duplicate_addrs2_test_strings_vector[i]);
- return false;
- }
- memset(&test_vector[i], '\0', sizeof(test_vector[i]));
- memcpy(&test_vector[i].ss,
- res->ai_addr,
- res->ai_addrlen);
- freeaddrinfo(res);
+ req = tevent_req_create(mem_ctx,
+ &state,
+ struct smb1_negotiate_exit_state);
+ if (req == NULL) {
+ return NULL;
}
-
- count = remove_duplicate_addrs2(test_vector, i);
-
- if (count != 14) {
- fprintf(stderr, "count wrong (%d) should be 14\n",
- count);
- return false;
+ subreq = smb1cli_req_send(state, ev, conn,
+ SMBexit,
+ 0, /* additional_flags */
+ 0, /* clear_flags */
+ 0, /* additional_flags2 */
+ 0, /* clear_flags2 */
+ 10000, /* timeout_msec */
+ getpid(),
+ NULL, /* tcon */
+ NULL, /* session */
+ 0, /* wct */
+ NULL,
+ 0,
+ NULL);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
+ tevent_req_set_callback(subreq,
+ smb1_negotiate_exit_done,
+ req);
+ return req;
+}
- for (i = 0; i < count; i++) {
- char addr[INET6_ADDRSTRLEN];
-
- print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
+static void smb1_negotiate_exit_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req =
+ tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct smb1_negotiate_exit_state *state =
+ tevent_req_data(req,
+ struct smb1_negotiate_exit_state);
+ NTSTATUS status;
+ struct smb1cli_req_expected_response expected[] = {
+ {
+ .status = NT_STATUS_OK,
+ .wct = 0,
+ },
+ };
- if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
- fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
- i,
- addr,
- remove_duplicate_addrs2_test_strings_result[i]);
- return false;
- }
+ status = smb1cli_req_recv(subreq, state,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* pvwv_offset */
+ NULL,
+ NULL,
+ NULL, /* pbytes_offset */
+ NULL,
+ expected, ARRAY_SIZE(expected));
+ TALLOC_FREE(subreq);
+ if (tevent_req_nterror(req, status)) {
+ return;
}
+ tevent_req_done(req);
+}
- printf("run_local_remove_duplicate_addrs2: success\n");
- return true;
+static NTSTATUS smb1_negotiate_exit_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
}
-static bool run_local_tdb_opener(int dummy)
+static bool do_smb1_exit(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct smbXcli_conn *conn)
{
- TDB_CONTEXT *t;
- unsigned v = 0;
+ struct tevent_req *req;
+ bool ok;
+ NTSTATUS status;
+ NTSTATUS expected_status = NT_STATUS_DOS(ERRSRV, ERRinvnid);;
- while (1) {
- t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
- O_RDWR|O_CREAT, 0755);
- if (t == NULL) {
- perror("tdb_open failed");
- return false;
- }
- tdb_close(t);
+ req = smb1_negotiate_exit_send(ev, ev, conn);
+ if (req == NULL) {
+ d_fprintf(stderr, "smb1_negotiate_exit_send failed\n");
+ return false;
+ }
- v += 1;
- printf("\r%u", v);
+ ok = tevent_req_poll_ntstatus(req, ev, &status);
+ if (!ok) {
+ d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
+ nt_errstr(status));
+ return false;
+ }
+
+ status = smb1_negotiate_exit_recv(req);
+ if (!NT_STATUS_EQUAL(status, expected_status)) {
+ d_fprintf(stderr, "smb1_negotiate_exit_recv returned "
+ "%s, expected ERRSRV, ERRinvnid\n",
+ nt_errstr(status));
+ return false;
}
return true;
}
-static bool run_local_tdb_writer(int dummy)
+static bool run_smb1_negotiate_exit(int dummy)
{
- TDB_CONTEXT *t;
- unsigned v = 0;
- TDB_DATA val;
+ struct tevent_context *ev;
+ struct smbXcli_conn *conn;
+ struct sockaddr_storage ss;
+ NTSTATUS status;
+ int fd;
+ bool ok;
- t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
- if (t == 0) {
- perror("tdb_open failed");
- return 1;
+ printf("Starting send SMB1 negotiate+exit.\n");
+
+ ok = resolve_name(host, &ss, 0x20, true);
+ if (!ok) {
+ d_fprintf(stderr, "Could not resolve name %s\n", host);
+ return false;
}
- val.dptr = (uint8_t *)&v;
- val.dsize = sizeof(v);
+ 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;
+ }
- while (1) {
- TDB_DATA data;
- int ret;
+ conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
+ NULL, 0, NULL);
+ if (conn == NULL) {
+ d_fprintf(stderr, "smbXcli_conn_create failed\n");
+ return false;
+ }
- ret = tdb_store(t, val, val, 0);
- if (ret != 0) {
- printf("%s\n", tdb_errorstr(t));
- }
- v += 1;
- printf("\r%u", v);
+ status = smbXcli_negprot(conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "smbXcli_negprot failed!\n");
+ return false;
+ }
- data = tdb_fetch(t, val);
- if (data.dptr != NULL) {
- SAFE_FREE(data.dptr);
- }
+ ev = samba_tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ d_fprintf(stderr, "samba_tevent_context_init failed\n");
+ return false;
}
+
+ /*
+ * Call do_smb1_exit twice to catch a server crash, the
+ * server sends the first return code then crashes.
+ */
+ ok = do_smb1_exit(ev, ev, conn);
+ if (!ok) {
+ d_fprintf(stderr, "do_smb1_exit (1) failed\n");
+ return false;
+ }
+ ok = do_smb1_exit(ev, ev, conn);
+ if (!ok) {
+ d_fprintf(stderr, "do_smb1_exit (2) failed\n");
+ return false;
+ }
+
+ TALLOC_FREE(conn);
return true;
}
-static bool run_local_canonicalize_path(int dummy)
+static bool run_smb1_negotiate_tcon(int dummy)
{
- const char *src[] = {
- "/foo/..",
- "/..",
- "/foo/bar/../baz",
- "/foo/././",
- "/../foo",
- ".././././",
- ".././././../../../boo",
- "./..",
- "/",
- "/../../",
- "/foo/../",
- "/./././",
- "/./././.",
- "/.../././.",
- "/./././.foo",
- "/./././.foo.",
- "/./././foo.",
- "/foo/bar/..",
- "/foo/bar/../baz/",
- "////////////////",
- "/////////./././././.",
- "/./.././../.boo/../baz",
- "/a/component/path",
- "/a/component/path/",
- "/a/component/path/..",
- "/a/component/../path/",
- "///a/./././///component/../////path/",
- NULL
- };
- const char *dst[] = {
- "/",
- "/",
- "/foo/baz",
- "/foo",
- "/foo",
- "/",
- "/boo",
- "/",
- "/",
- "/",
- "/",
- "/",
- "/",
- "/...",
- "/.foo",
- "/.foo.",
- "/foo.",
- "/foo",
- "/foo/baz",
- "/",
- "/",
- "/baz",
- "/a/component/path",
- "/a/component/path",
- "/a/component",
- "/a/path",
- "/a/path",
- NULL
- };
- unsigned int i;
+ struct cli_state *cli = NULL;
+ uint16_t cnum = 0;
+ uint16_t max_xmit = 0;
+ NTSTATUS status;
- for (i = 0; src[i] != NULL; i++) {
- char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
- if (d == NULL) {
- perror("talloc fail\n");
- return false;
- }
- if (strcmp(d, dst[i]) != 0) {
- d_fprintf(stderr,
- "canonicalize mismatch %s -> %s != %s",
- src[i], d, dst[i]);
- return false;
- }
- talloc_free(d);
+ printf("Starting send SMB1 negotiate+tcon.\n");
+ cli = open_nbt_connection();
+ if (cli == NULL) {
+ d_fprintf(stderr, "open_nbt_connection failed!\n");
+ return false;
+ }
+ smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+ status = smbXcli_negprot(cli->conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "smbXcli_negprot failed %s!\n",
+ nt_errstr(status));
+ return false;
+ }
+ status = cli_raw_tcon(cli,
+ share,
+ "",
+ "?????",
+ &max_xmit,
+ &cnum);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ d_fprintf(stderr, "cli_raw_tcon failed - got %s "
+ "(should get NT_STATUS_ACCESS_DENIED)!\n",
+ nt_errstr(status));
+ return false;
}
return true;
}
}
conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
- NULL, 0);
+ NULL, 0, NULL);
if (conn == NULL) {
d_fprintf(stderr, "smbXcli_conn_create failed\n");
return false;
return true;
}
+
static double create_procs(bool (*fn)(int), bool *result)
{
int i, status;
.name = "POSIX-ACL-SHAREROOT",
.fn = run_posix_acl_shareroot_test,
},
+ {
+ .name = "POSIX-LS-WILDCARD",
+ .fn = run_posix_ls_wildcard_test,
+ },
+ {
+ .name = "POSIX-LS-SINGLE",
+ .fn = run_posix_ls_single_test,
+ },
+ {
+ .name = "POSIX-READLINK",
+ .fn = run_posix_readlink_test,
+ },
+ {
+ .name = "POSIX-STAT",
+ .fn = run_posix_stat_test,
+ },
+ {
+ .name = "POSIX-SYMLINK-PARENT",
+ .fn = run_posix_symlink_parent_test,
+ },
+ {
+ .name = "POSIX-SYMLINK-CHMOD",
+ .fn = run_posix_symlink_chmod_test,
+ },
+ {
+ .name = "POSIX-SYMLINK-RENAME",
+ .fn = run_posix_symlink_rename_test,
+ },
+ {
+ .name = "POSIX-DIR-DEFAULT-ACL",
+ .fn = run_posix_dir_default_acl_test,
+ },
+ {
+ .name = "POSIX-SYMLINK-GETPATHINFO",
+ .fn = run_posix_symlink_getpathinfo_test,
+ },
+ {
+ .name = "POSIX-SYMLINK-SETPATHINFO",
+ .fn = run_posix_symlink_setpathinfo_test,
+ },
{
.name = "WINDOWS-BAD-SYMLINK",
.fn = run_symlink_open_test,
},
+ {
+ .name = "SMB1-WILD-MANGLE-UNLINK",
+ .fn = run_smb1_wild_mangle_unlink_test,
+ },
+ {
+ .name = "SMB1-WILD-MANGLE-RENAME",
+ .fn = run_smb1_wild_mangle_rename_test,
+ },
{
.name = "CASE-INSENSITIVE-CREATE",
.fn = run_case_insensitive_create,
.name = "DELETE-PRINT",
.fn = run_delete_print_test,
},
- {
- .name = "WILDDELETE",
- .fn = run_wild_deletetest,
- },
{
.name = "DELETE-LN",
.fn = run_deletetest_ln,
.name = "LARGE_READX",
.fn = run_large_readx,
},
+ {
+ .name = "MSDFS-ATTRIBUTE",
+ .fn = run_msdfs_attribute,
+ },
{
.name = "NTTRANS-CREATE",
.fn = run_nttrans_create,
.name = "SMB2-SACL",
.fn = run_smb2_sacl,
},
+ {
+ .name = "SMB2-QUOTA1",
+ .fn = run_smb2_quota1,
+ },
+ {
+ .name = "SMB2-STREAM-ACL",
+ .fn = run_smb2_stream_acl,
+ },
+ {
+ .name = "SMB2-LIST-DIR-ASYNC",
+ .fn = run_list_dir_async_test,
+ },
+ {
+ .name = "SMB2-DEL-ON-CLOSE-NONEMPTY",
+ .fn = run_delete_on_close_non_empty,
+ },
+ {
+ .name = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-YES",
+ .fn = run_delete_on_close_nonwrite_delete_yes_test,
+ },
+ {
+ .name = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-NO",
+ .fn = run_delete_on_close_nonwrite_delete_no_test,
+ },
+ {
+ .name = "SMB2-DFS-PATHS",
+ .fn = run_smb2_dfs_paths,
+ },
+ {
+ .name = "SMB2-NON-DFS-SHARE",
+ .fn = run_smb2_non_dfs_share,
+ },
+ {
+ .name = "SMB2-DFS-SHARE-NON-DFS-PATH",
+ .fn = run_smb2_dfs_share_non_dfs_path,
+ },
+ {
+ .name = "SMB2-DFS-FILENAME-LEADING-BACKSLASH",
+ .fn = run_smb2_dfs_filename_leading_backslash,
+ },
+ {
+ .name = "SMB1-TRUNCATED-SESSSETUP",
+ .fn = run_smb1_truncated_sesssetup,
+ },
+ {
+ .name = "SMB1-NEGOTIATE-EXIT",
+ .fn = run_smb1_negotiate_exit,
+ },
+ {
+ .name = "SMB1-NEGOTIATE-TCON",
+ .fn = run_smb1_negotiate_tcon,
+ },
+ {
+ .name = "SMB1-DFS-PATHS",
+ .fn = run_smb1_dfs_paths,
+ },
+ {
+ .name = "SMB1-DFS-SEARCH-PATHS",
+ .fn = run_smb1_dfs_search_paths,
+ },
+ {
+ .name = "SMB1-DFS-OPERATIONS",
+ .fn = run_smb1_dfs_operations,
+ },
+ {
+ .name = "SMB1-DFS-BADPATH",
+ .fn = run_smb1_dfs_check_badpath,
+ },
{
.name = "CLEANUP1",
.fn = run_cleanup1,
.name = "LOCAL-STREAM-NAME",
.fn = run_local_stream_name,
},
+ {
+ .name = "LOCAL-STR-MATCH-MSWILD",
+ .fn = run_str_match_mswild,
+ },
+ {
+ .name = "LOCAL-STR-MATCH-REGEX-SUB1",
+ .fn = run_str_match_regex_sub1,
+ },
{
.name = "WBCLIENT-MULTI-PING",
.fn = run_wbclient_multi_ping,
.name = "LOCAL-G-LOCK7",
.fn = run_g_lock7,
},
+ {
+ .name = "LOCAL-G-LOCK8",
+ .fn = run_g_lock8,
+ },
{
.name = "LOCAL-G-LOCK-PING-PONG",
.fn = run_g_lock_ping_pong,
.name = "hide-new-files-timeout",
.fn = run_hidenewfiles,
},
+ {
+ .name = "hide-new-files-timeout-showdirs",
+ .fn = run_hidenewfiles_showdirs,
+ },
#ifdef CLUSTER_SUPPORT
{
.name = "ctdbd-conn1",
.name = "readdir-timestamp",
.fn = run_readdir_timestamp,
},
+ {
+ .name = "rpc-scale",
+ .fn = run_rpc_scale,
+ },
+ {
+ .name = "LOCAL-TDB-VALIDATE",
+ .fn = run_tdb_validate,
+ },
{
.name = NULL,
},