*/
#include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "system/shmem.h"
+#include "system/time.h"
+#include "librpc/gen_ndr/ndr_security.h"
-static struct timeval tp1,tp2;
-
-void start_timer(void)
-{
- gettimeofday(&tp1,NULL);
-}
-
-double end_timer(void)
+/*
+ setup a directory ready for a test
+*/
+BOOL torture_setup_dir(struct smbcli_state *cli, const char *dname)
{
- gettimeofday(&tp2,NULL);
- return((tp2.tv_sec - tp1.tv_sec) +
- (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
+ smb_raw_exit(cli->session);
+ if (smbcli_deltree(cli->tree, dname) == -1 ||
+ NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
+ printf("Unable to setup %s - %s\n", dname, smbcli_errstr(cli->tree));
+ return False;
+ }
+ return True;
}
-
/*
create a directory, returning a handle to it
*/
-int create_directory_handle(struct cli_tree *tree, const char *dname)
+int create_directory_handle(struct smbcli_tree *tree, const char *dname)
{
NTSTATUS status;
union smb_open io;
io.generic.level = RAW_OPEN_NTCREATEX;
io.ntcreatex.in.root_fid = 0;
io.ntcreatex.in.flags = 0;
- io.ntcreatex.in.access_mask = SA_RIGHT_FILE_ALL_ACCESS;
+ io.ntcreatex.in.access_mask = SEC_FILE_ALL;
io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
sometimes we need a fairly complex file to work with, so we can test
all possible attributes.
*/
-int create_complex_file(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *fname)
+int create_complex_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char *fname)
{
int fnum;
char buf[7] = "abc";
time_t t = (time(NULL) & ~1);
NTSTATUS status;
- cli_unlink(cli, fname);
- fnum = cli_nt_create_full(cli, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
- FILE_ATTRIBUTE_NORMAL,
- NTCREATEX_SHARE_ACCESS_DELETE|
- NTCREATEX_SHARE_ACCESS_READ|
- NTCREATEX_SHARE_ACCESS_WRITE,
- NTCREATEX_DISP_OVERWRITE_IF,
- 0, 0);
+ smbcli_unlink(cli->tree, fname);
+ fnum = smbcli_nt_create_full(cli->tree, fname, 0,
+ SEC_RIGHTS_FILE_ALL,
+ FILE_ATTRIBUTE_NORMAL,
+ NTCREATEX_SHARE_ACCESS_DELETE|
+ NTCREATEX_SHARE_ACCESS_READ|
+ NTCREATEX_SHARE_ACCESS_WRITE,
+ NTCREATEX_DISP_OVERWRITE_IF,
+ 0, 0);
if (fnum == -1) return -1;
- cli_write(cli, fnum, 0, buf, 0, sizeof(buf));
+ smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
/* setup some EAs */
setfile.generic.level = RAW_SFILEINFO_EA_SET;
setfile.generic.file.fnum = fnum;
- setfile.ea_set.in.ea.flags = 0;
- setfile.ea_set.in.ea.name.s = "EAONE";
- setfile.ea_set.in.ea.value = data_blob_talloc(mem_ctx, "VALUE1", 6);
-
- status = smb_raw_setfileinfo(cli->tree, &setfile);
- if (!NT_STATUS_IS_OK(status)) {
- printf("Failed to setup EAs\n");
- }
-
- setfile.ea_set.in.ea.name.s = "SECONDEA";
- setfile.ea_set.in.ea.value = data_blob_talloc(mem_ctx, "ValueTwo", 8);
+ setfile.ea_set.in.num_eas = 2;
+ setfile.ea_set.in.eas = talloc_array_p(mem_ctx, struct ea_struct, 2);
+ setfile.ea_set.in.eas[0].flags = 0;
+ setfile.ea_set.in.eas[0].name.s = "EAONE";
+ setfile.ea_set.in.eas[0].value = data_blob_talloc(mem_ctx, "VALUE1", 6);
+ setfile.ea_set.in.eas[1].flags = 0;
+ setfile.ea_set.in.eas[1].name.s = "SECONDEA";
+ setfile.ea_set.in.eas[1].value = data_blob_talloc(mem_ctx, "ValueTwo", 8);
status = smb_raw_setfileinfo(cli->tree, &setfile);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to setup EAs\n");
}
- /* make sure all the timestamps aren't the same */
+ /* make sure all the timestamps aren't the same, and are also
+ in different DST zones*/
setfile.generic.level = RAW_SFILEINFO_SETATTRE;
setfile.generic.file.fnum = fnum;
- setfile.setattre.in.create_time = t + 60;
- setfile.setattre.in.access_time = t + 120;
- setfile.setattre.in.write_time = t + 180;
+ setfile.setattre.in.create_time = t + 9*30*24*60*60;
+ setfile.setattre.in.access_time = t + 6*30*24*60*60;
+ setfile.setattre.in.write_time = t + 3*30*24*60*60;
status = smb_raw_setfileinfo(cli->tree, &setfile);
if (!NT_STATUS_IS_OK(status)) {
check that a wire string matches the flags specified
not 100% accurate, but close enough for testing
*/
-BOOL wire_bad_flags(WIRE_STRING *str, int flags)
+BOOL wire_bad_flags(WIRE_STRING *str, int flags, struct smbcli_state *cli)
{
+ BOOL server_unicode;
int len;
if (!str || !str->s) return True;
len = strlen(str->s);
if (flags & STR_TERMINATE) len++;
- if ((flags & STR_UNICODE) || !getenv("CLI_FORCE_ASCII")) {
+
+ server_unicode = (cli->transport->negotiate.capabilities&CAP_UNICODE)?True:False;
+ if (getenv("CLI_FORCE_ASCII") || !lp_unicode()) {
+ server_unicode = False;
+ }
+
+ if ((flags & STR_UNICODE) || server_unicode) {
len *= 2;
} else if (flags & STR_TERMINATE_ASCII) {
len++;
return False;
}
-/*
- return a talloced string representing a time_t for human consumption
-*/
-const char *time_string(TALLOC_CTX *mem_ctx, time_t t)
-{
- return talloc_strdup(mem_ctx, http_timestring(mem_ctx, t));
-}
-
/*
check if 2 NTTIMEs are equal
*/
BOOL nt_time_equal(NTTIME *t1, NTTIME *t2)
{
- return t1->low == t2->low && t1->high == t2->high;
+ return *t1 == *t2;
}
/*
*/
void dump_all_info(TALLOC_CTX *mem_ctx, union smb_fileinfo *finfo)
{
- d_printf("\tcreate_time: %s\n", nt_time_string(mem_ctx, &finfo->all_info.out.create_time));
- d_printf("\taccess_time: %s\n", nt_time_string(mem_ctx, &finfo->all_info.out.access_time));
- d_printf("\twrite_time: %s\n", nt_time_string(mem_ctx, &finfo->all_info.out.write_time));
- d_printf("\tchange_time: %s\n", nt_time_string(mem_ctx, &finfo->all_info.out.change_time));
+ d_printf("\tcreate_time: %s\n", nt_time_string(mem_ctx, finfo->all_info.out.create_time));
+ d_printf("\taccess_time: %s\n", nt_time_string(mem_ctx, finfo->all_info.out.access_time));
+ d_printf("\twrite_time: %s\n", nt_time_string(mem_ctx, finfo->all_info.out.write_time));
+ d_printf("\tchange_time: %s\n", nt_time_string(mem_ctx, finfo->all_info.out.change_time));
d_printf("\tattrib: 0x%x\n", finfo->all_info.out.attrib);
- d_printf("\talloc_size: %llu\n", (unsigned long long)finfo->all_info.out.alloc_size);
- d_printf("\tsize: %llu\n", (unsigned long long)finfo->all_info.out.size);
+ d_printf("\talloc_size: %llu\n", (uint64_t)finfo->all_info.out.alloc_size);
+ d_printf("\tsize: %llu\n", (uint64_t)finfo->all_info.out.size);
d_printf("\tnlink: %u\n", finfo->all_info.out.nlink);
d_printf("\tdelete_pending: %u\n", finfo->all_info.out.delete_pending);
d_printf("\tdirectory: %u\n", finfo->all_info.out.directory);
/*
dump file infor by name
*/
-void torture_all_info(struct cli_tree *tree, const char *fname)
+void torture_all_info(struct smbcli_tree *tree, const char *fname)
{
- TALLOC_CTX *mem_ctx = talloc_init(fname);
+ TALLOC_CTX *mem_ctx = talloc_init("%s", fname);
union smb_fileinfo finfo;
NTSTATUS status;
/*
set a attribute on a file
*/
-BOOL torture_set_file_attribute(struct cli_tree *tree, const char *fname, uint16 attrib)
+BOOL torture_set_file_attribute(struct smbcli_tree *tree, const char *fname, uint16_t attrib)
{
union smb_setfileinfo sfinfo;
NTSTATUS status;
/*
set a file descriptor as sparse
*/
-NTSTATUS torture_set_sparse(struct cli_tree *tree, int fnum)
+NTSTATUS torture_set_sparse(struct smbcli_tree *tree, int fnum)
{
union smb_ioctl nt;
NTSTATUS status;
return status;
}
+
+/*
+ check that an EA has the right value
+*/
+NTSTATUS torture_check_ea(struct smbcli_state *cli,
+ const char *fname, const char *eaname, const char *value)
+{
+ union smb_fileinfo info;
+ NTSTATUS status;
+ struct ea_name ea;
+ TALLOC_CTX *mem_ctx = talloc_new(cli);
+
+ info.ea_list.level = RAW_FILEINFO_EA_LIST;
+ info.ea_list.file.fname = fname;
+ info.ea_list.in.num_names = 1;
+ info.ea_list.in.ea_names = &ea;
+
+ ea.name.s = eaname;
+
+ status = smb_raw_pathinfo(cli->tree, mem_ctx, &info);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(mem_ctx);
+ return status;
+ }
+
+ if (info.ea_list.out.num_eas != 1) {
+ printf("Expected 1 ea in ea_list\n");
+ talloc_free(mem_ctx);
+ return NT_STATUS_EA_CORRUPT_ERROR;
+ }
+
+ if (StrCaseCmp(eaname, info.ea_list.out.eas[0].name.s) != 0) {
+ printf("Expected ea '%s' not '%s' in ea_list\n",
+ eaname, info.ea_list.out.eas[0].name.s);
+ talloc_free(mem_ctx);
+ return NT_STATUS_EA_CORRUPT_ERROR;
+ }
+
+ if (value == NULL) {
+ if (info.ea_list.out.eas[0].value.length != 0) {
+ printf("Expected zero length ea for %s\n", eaname);
+ talloc_free(mem_ctx);
+ return NT_STATUS_EA_CORRUPT_ERROR;
+ }
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+ }
+
+ if (strlen(value) == info.ea_list.out.eas[0].value.length &&
+ memcmp(value, info.ea_list.out.eas[0].value.data,
+ info.ea_list.out.eas[0].value.length) == 0) {
+ talloc_free(mem_ctx);
+ return NT_STATUS_OK;
+ }
+
+ printf("Expected value '%s' not '%*.*s' for ea %s\n",
+ value,
+ info.ea_list.out.eas[0].value.length,
+ info.ea_list.out.eas[0].value.length,
+ info.ea_list.out.eas[0].value.data,
+ eaname);
+
+ talloc_free(mem_ctx);
+
+ return NT_STATUS_EA_CORRUPT_ERROR;
+}
+