r25035: Fix some more warnings, use service pointer rather than service number in...
[samba.git] / source4 / torture / smb2 / util.c
index 7afce0137f14cb4b0e9de290cd0cbcd6cf1d1384..8c55813c8c2e244c6c5e38ba3b9f30d45847df33 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-#include "libcli/raw/libcliraw.h"
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
 #include "lib/cmdline/popt_common.h"
 #include "lib/events/events.h"
 #include "system/time.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "param/param.h"
+#include "torture/smb2/proto.h"
 
 
 /*
@@ -37,7 +38,7 @@ NTSTATUS smb2_util_close(struct smb2_tree *tree, struct smb2_handle h)
        struct smb2_close c;
 
        ZERO_STRUCT(c);
-       c.in.handle = h;
+       c.in.file.handle = h;
 
        return smb2_close(tree, &c);
 }
@@ -67,7 +68,7 @@ NTSTATUS smb2_util_unlink(struct smb2_tree *tree, const char *fname)
        }
        NT_STATUS_NOT_OK_RETURN(status);
 
-       return smb2_util_close(tree, io.out.handle);
+       return smb2_util_close(tree, io.out.file.handle);
 }
 
 /*
@@ -80,8 +81,8 @@ NTSTATUS smb2_util_write(struct smb2_tree *tree,
        struct smb2_write w;
 
        ZERO_STRUCT(w);
+       w.in.file.handle = handle;
        w.in.offset      = offset;
-       w.in.handle      = handle;
        w.in.data        = data_blob_const(buf, size);
 
        return smb2_write(tree, &w);
@@ -103,7 +104,7 @@ static NTSTATUS smb2_create_complex(struct smb2_tree *tree, const char *fname,
 
        smb2_util_unlink(tree, fname);
        ZERO_STRUCT(io);
-       io.in.access_mask = SEC_RIGHTS_FILE_ALL;
+       io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        io.in.file_attr   = FILE_ATTRIBUTE_NORMAL;
        io.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
        io.in.share_access = 
@@ -119,18 +120,6 @@ static NTSTATUS smb2_create_complex(struct smb2_tree *tree, const char *fname,
                io.in.open_disposition = NTCREATEX_DISP_CREATE;
        }
 
-       io.in.sd = security_descriptor_create(tmp_ctx,
-                                             NULL, NULL,
-                                             SID_NT_AUTHENTICATED_USERS,
-                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
-                                             SEC_RIGHTS_FILE_ALL | SEC_STD_ALL,
-                                             0,
-                                             SID_WORLD,
-                                             SEC_ACE_TYPE_ACCESS_ALLOWED,
-                                             SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
-                                             0,
-                                             NULL);
-
        if (strchr(fname, ':') == NULL) {
                /* setup some EAs */
                io.in.eas.num_eas = 2;
@@ -147,7 +136,7 @@ static NTSTATUS smb2_create_complex(struct smb2_tree *tree, const char *fname,
        talloc_free(tmp_ctx);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       *handle = io.out.handle;
+       *handle = io.out.file.handle;
 
        if (!dir) {
                status = smb2_util_write(tree, *handle, buf, 0, sizeof(buf));
@@ -157,39 +146,49 @@ static NTSTATUS smb2_create_complex(struct smb2_tree *tree, const char *fname,
        /* make sure all the timestamps aren't the same, and are also 
           in different DST zones*/
        setfile.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
-       setfile.generic.file.handle = *handle;
+       setfile.generic.in.file.handle = *handle;
 
-       setfile.basic_info.in.create_time = t +  9*30*24*60*60;
-       setfile.basic_info.in.access_time = t +  6*30*24*60*60;
-       setfile.basic_info.in.write_time  = t +  3*30*24*60*60;
-       setfile.basic_info.in.change_time = t +  1*30*24*60*60;
+       unix_to_nt_time(&setfile.basic_info.in.create_time, t + 9*30*24*60*60);
+       unix_to_nt_time(&setfile.basic_info.in.access_time, t + 6*30*24*60*60);
+       unix_to_nt_time(&setfile.basic_info.in.write_time,  t + 3*30*24*60*60);
+       unix_to_nt_time(&setfile.basic_info.in.change_time, t + 1*30*24*60*60);
        setfile.basic_info.in.attrib      = FILE_ATTRIBUTE_NORMAL;
 
        status = smb2_setinfo_file(tree, &setfile);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Failed to setup file times - %s\n", nt_errstr(status));
+               return status;
        }
 
        /* make sure all the timestamps aren't the same */
-       fileinfo.generic.level = RAW_FILEINFO_BASIC_INFORMATION;
-       fileinfo.generic.in.handle = *handle;
+       fileinfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+       fileinfo.generic.in.file.handle = *handle;
 
        status = smb2_getinfo_file(tree, tree, &fileinfo);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Failed to query file times - %s\n", nt_errstr(status));
+               return status;
+               
        }
 
-       if (setfile.basic_info.in.create_time != fileinfo.basic_info.out.create_time) {
-               printf("create_time not setup correctly\n");
-       }
-       if (setfile.basic_info.in.access_time != fileinfo.basic_info.out.access_time) {
-               printf("access_time not setup correctly\n");
-       }
-       if (setfile.basic_info.in.write_time != fileinfo.basic_info.out.write_time) {
-               printf("write_time not setup correctly\n");
-       }
-       
-       return NT_STATUS_OK;
+#define CHECK_TIME(field) do {\
+       if (setfile.basic_info.in.field != fileinfo.all_info2.out.field) { \
+               printf("(%s) " #field " not setup correctly: %s(%llu) => %s(%llu)\n", \
+                       __location__, \
+                       nt_time_string(tree, setfile.basic_info.in.field), \
+                       (unsigned long long)setfile.basic_info.in.field, \
+                       nt_time_string(tree, fileinfo.basic_info.out.field), \
+                       (unsigned long long)fileinfo.basic_info.out.field); \
+               status = NT_STATUS_INVALID_PARAMETER; \
+       } \
+} while (0)
+
+       CHECK_TIME(create_time);
+       CHECK_TIME(access_time);
+       CHECK_TIME(write_time);
+       CHECK_TIME(change_time);
+
+       return status;
 }
 
 /*
@@ -220,7 +219,7 @@ void torture_smb2_all_info(struct smb2_tree *tree, struct smb2_handle handle)
        union smb_fileinfo io;
 
        io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
-       io.generic.in.handle = handle;
+       io.generic.in.file.handle = handle;
 
        status = smb2_getinfo_file(tree, tmp_ctx, &io);
        if (!NT_STATUS_IS_OK(status)) {
@@ -236,16 +235,16 @@ void torture_smb2_all_info(struct smb2_tree *tree, struct smb2_handle handle)
        d_printf("\tchange_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.change_time));
        d_printf("\tattrib:         0x%x\n", io.all_info2.out.attrib);
        d_printf("\tunknown1:       0x%x\n", io.all_info2.out.unknown1);
-       d_printf("\talloc_size:     %llu\n", (uint64_t)io.all_info2.out.alloc_size);
-       d_printf("\tsize:           %llu\n", (uint64_t)io.all_info2.out.size);
+       d_printf("\talloc_size:     %llu\n", (long long)io.all_info2.out.alloc_size);
+       d_printf("\tsize:           %llu\n", (long long)io.all_info2.out.size);
        d_printf("\tnlink:          %u\n", io.all_info2.out.nlink);
        d_printf("\tdelete_pending: %u\n", io.all_info2.out.delete_pending);
        d_printf("\tdirectory:      %u\n", io.all_info2.out.directory);
-       d_printf("\tfile_id:        %llu\n", io.all_info2.out.file_id);
+       d_printf("\tfile_id:        %llu\n", (long long)io.all_info2.out.file_id);
        d_printf("\tea_size:        %u\n", io.all_info2.out.ea_size);
        d_printf("\taccess_mask:    0x%08x\n", io.all_info2.out.access_mask);
-       d_printf("\tunknown2:       0x%llx\n", io.all_info2.out.unknown2);
-       d_printf("\tunknown3:       0x%llx\n", io.all_info2.out.unknown3);
+       d_printf("\tposition:       0x%llx\n", (long long)io.all_info2.out.position);
+       d_printf("\tmode:           0x%llx\n", (long long)io.all_info2.out.mode);
 
        /* short name, if any */
        io.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
@@ -282,14 +281,16 @@ void torture_smb2_all_info(struct smb2_tree *tree, struct smb2_handle handle)
                }
        }       
 
-       /* the security descriptor */
-       io.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
-       io.query_secdesc.secinfo_flags = 
-               SECINFO_OWNER|SECINFO_GROUP|
-               SECINFO_DACL;
-       status = smb2_getinfo_file(tree, tmp_ctx, &io);
-       if (NT_STATUS_IS_OK(status)) {
-               NDR_PRINT_DEBUG(security_descriptor, io.query_secdesc.out.sd);
+       if (DEBUGLVL(1)) {
+               /* the security descriptor */
+               io.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
+               io.query_secdesc.in.secinfo_flags = 
+                       SECINFO_OWNER|SECINFO_GROUP|
+                       SECINFO_DACL;
+               status = smb2_getinfo_file(tree, tmp_ctx, &io);
+               if (NT_STATUS_IS_OK(status)) {
+                       NDR_PRINT_DEBUG(security_descriptor, io.query_secdesc.out.sd);
+               }
        }
 
        talloc_free(tmp_ctx);   
@@ -302,8 +303,8 @@ void torture_smb2_all_info(struct smb2_tree *tree, struct smb2_handle handle)
 BOOL torture_smb2_connection(TALLOC_CTX *mem_ctx, struct smb2_tree **tree)
 {
        NTSTATUS status;
-       const char *host = lp_parm_string(-1, "torture", "host");
-       const char *share = lp_parm_string(-1, "torture", "share");
+       const char *host = lp_parm_string(NULL, "torture", "host");
+       const char *share = lp_parm_string(NULL, "torture", "share");
        struct cli_credentials *credentials = cmdline_credentials;
 
        status = smb2_connect(mem_ctx, host, share, credentials, tree, 
@@ -342,12 +343,12 @@ NTSTATUS torture_smb2_testfile(struct smb2_tree *tree, const char *fname,
        status = smb2_create(tree, tree, &io);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       *handle = io.out.handle;
+       *handle = io.out.file.handle;
 
        ZERO_STRUCT(r);
+       r.in.file.handle = *handle;
        r.in.length      = 5;
        r.in.offset      = 0;
-       r.in.handle      = *handle;
 
        smb2_read(tree, tree, &r);
 
@@ -375,7 +376,7 @@ NTSTATUS torture_smb2_testdir(struct smb2_tree *tree, const char *fname,
        status = smb2_create(tree, tree, &io);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       *handle = io.out.handle;
+       *handle = io.out.file.handle;
 
        return NT_STATUS_OK;
 }
@@ -406,3 +407,28 @@ NTSTATUS torture_setup_complex_dir(struct smb2_tree *tree, const char *fname)
        return smb2_util_close(tree, handle);
 }
 
+
+/*
+  return a handle to the root of the share
+*/
+NTSTATUS smb2_util_roothandle(struct smb2_tree *tree, struct smb2_handle *handle)
+{
+       struct smb2_create io;
+       NTSTATUS status;
+
+       ZERO_STRUCT(io);
+       io.in.oplock_flags = 0;
+       io.in.access_mask = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE | SEC_DIR_LIST;
+       io.in.file_attr   = 0;
+       io.in.open_disposition = NTCREATEX_DISP_OPEN;
+       io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE;
+       io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT;
+       io.in.fname = "";
+
+       status = smb2_create(tree, tree, &io);
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       *handle = io.out.file.handle;
+
+       return NT_STATUS_OK;
+}