r4547: - added talloc_new(ctx) macro that is a neater form of the common talloc(ctx...
[kamenim/samba.git] / source4 / torture / torture_util.c
index 8dbec60b123200a6a9cad6fced7de5b161501b78..3df1f3be41cd4474aa0269b4c915f671a4e3ac7b 100644 (file)
 */
 
 #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;
@@ -50,7 +53,7 @@ int create_directory_handle(struct cli_tree *tree, const char *dname)
        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;
@@ -74,7 +77,7 @@ int create_directory_handle(struct cli_tree *tree, const char *dname)
   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";
@@ -83,44 +86,43 @@ int create_complex_file(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *
        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)) {
@@ -192,13 +194,20 @@ void *shm_setup(int size)
   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++;
@@ -211,20 +220,12 @@ BOOL wire_bad_flags(WIRE_STRING *str, int flags)
        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;
 }
 
 /*
@@ -232,13 +233,13 @@ BOOL nt_time_equal(NTTIME *t1, NTTIME *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);
@@ -249,9 +250,9 @@ void dump_all_info(TALLOC_CTX *mem_ctx, union smb_fileinfo *finfo)
 /*
   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;
 
@@ -311,7 +312,7 @@ BOOL split_username(const char *pair, char **user, char **pass)
 /*
   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;
@@ -329,7 +330,7 @@ BOOL torture_set_file_attribute(struct cli_tree *tree, const char *fname, uint16
 /*
   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;
@@ -352,3 +353,70 @@ NTSTATUS torture_set_sparse(struct cli_tree *tree, int fnum)
 
        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;
+}
+