The branch, master has been updated
       via  29384794ccac1904cdbd4544ffb77996eaa9fcff (commit)
       via  f2269e6cc85ffcd38134df2e430c4c0fabde17f8 (commit)
       via  6dde84553c1f4d14f075982377f5af97ff5abc44 (commit)
       via  a65f1b9655498850864946d89528f3a475a88248 (commit)
      from  22a96cbe31875a1adfbfc7157b308eebb5d0f2ec (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 29384794ccac1904cdbd4544ffb77996eaa9fcff
Author: Tim Prouty <tpro...@samba.org>
Date:   Fri Jan 9 11:50:28 2009 -0800

    s3: Remove rendundant op_tuple entry in xattr streams

commit f2269e6cc85ffcd38134df2e430c4c0fabde17f8
Author: Tim Prouty <tpro...@samba.org>
Date:   Fri Jan 9 11:07:45 2009 -0800

    s3: Fix open path to delete streams depending on the create disposition
    
    The new create disposition test in smbtorture RAW-STREAMS verifies
    this fix.

commit 6dde84553c1f4d14f075982377f5af97ff5abc44
Author: Tim Prouty <tpro...@samba.org>
Date:   Sun Dec 21 15:49:46 2008 -0800

    s3: Add delete_all_streams to proto.h

commit a65f1b9655498850864946d89528f3a475a88248
Author: Tim Prouty <tpro...@samba.org>
Date:   Fri Jan 9 11:38:58 2009 -0800

    s4 torture: Add new create disposition test to RAW-STREAMS

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h             |    1 +
 source3/modules/vfs_streams_xattr.c |    2 -
 source3/smbd/close.c                |    2 +-
 source3/smbd/open.c                 |   14 +++
 source4/torture/raw/streams.c       |  168 ++++++++++++++++++++++++++++++++++-
 5 files changed, 183 insertions(+), 4 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index d4aefea..2a75473 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6532,6 +6532,7 @@ void msg_close_file(struct messaging_context *msg_ctx,
                    uint32_t msg_type,
                    struct server_id server_id,
                    DATA_BLOB *data);
+NTSTATUS delete_all_streams(connection_struct *conn, const char *fname);
 
 /* The following definitions come from smbd/conn.c  */
 
diff --git a/source3/modules/vfs_streams_xattr.c 
b/source3/modules/vfs_streams_xattr.c
index 7124c57..1df4932 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -950,8 +950,6 @@ static vfs_op_tuple streams_xattr_ops[] = {
         SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(streams_xattr_pwrite), SMB_VFS_OP_PWRITE,
         SMB_VFS_LAYER_TRANSPARENT},
-       {SMB_VFS_OP(streams_xattr_lstat), SMB_VFS_OP_LSTAT,
-        SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(streams_xattr_unlink), SMB_VFS_OP_UNLINK,
         SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(streams_xattr_rename), SMB_VFS_OP_RENAME,
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index a6dff20..abcd651 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -167,7 +167,7 @@ static void notify_deferred_opens(struct share_mode_lock 
*lck)
  Delete all streams
 ****************************************************************************/
 
-static NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
+NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
 {
        struct stream_struct *stream_info;
        int i;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 52e31df..7d23b92 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1330,6 +1330,7 @@ static NTSTATUS open_file_ntcreate(connection_struct 
*conn,
        bool def_acl = False;
        bool posix_open = False;
        bool new_file_created = False;
+       bool clear_ads = false;
        struct file_id id;
        NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
        mode_t new_unx_mode = (mode_t)0;
@@ -1461,12 +1462,14 @@ static NTSTATUS open_file_ntcreate(connection_struct 
*conn,
                        /* If file exists replace/overwrite. If file doesn't
                         * exist create. */
                        flags2 |= (O_CREAT | O_TRUNC);
+                       clear_ads = true;
                        break;
 
                case FILE_OVERWRITE_IF:
                        /* If file exists replace/overwrite. If file doesn't
                         * exist create. */
                        flags2 |= (O_CREAT | O_TRUNC);
+                       clear_ads = true;
                        break;
 
                case FILE_OPEN:
@@ -1491,6 +1494,7 @@ static NTSTATUS open_file_ntcreate(connection_struct 
*conn,
                                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
                        }
                        flags2 |= O_TRUNC;
+                       clear_ads = true;
                        break;
 
                case FILE_CREATE:
@@ -1925,6 +1929,16 @@ static NTSTATUS open_file_ntcreate(connection_struct 
*conn,
 
        SMB_ASSERT(lck != NULL);
 
+       /* Delete streams if create_disposition requires it */
+       if (file_existed && clear_ads) {
+               status = delete_all_streams(conn, fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(lck);
+                       fd_close(fsp);
+                       return status;
+               }
+       }
+
        /* note that we ignore failure for the following. It is
            basically a hack for NFS, and NFS will never set one of
            these only read them. Nobody but Samba can ever set a deny
diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c
index 35204f3..aff97d0 100644
--- a/source4/torture/raw/streams.c
+++ b/source4/torture/raw/streams.c
@@ -1306,6 +1306,171 @@ static bool test_stream_rename2(struct torture_context 
*tctx,
        return ret;
 }
 
+static bool create_file_with_stream(struct torture_context *tctx,
+                                   struct smbcli_state *cli,
+                                   TALLOC_CTX *mem_ctx,
+                                   const char *base_fname,
+                                   const char *stream)
+{
+       NTSTATUS status;
+       bool ret = true;
+       union smb_open io;
+
+       /* Create a file with a stream */
+       io.generic.level = RAW_OPEN_NTCREATEX;
+       io.ntcreatex.in.root_fid = 0;
+       io.ntcreatex.in.flags = 0;
+       io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|
+           SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL);
+       io.ntcreatex.in.create_options = 0;
+       io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+       io.ntcreatex.in.share_access = 0;
+       io.ntcreatex.in.alloc_size = 0;
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+       io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+       io.ntcreatex.in.security_flags = 0;
+       io.ntcreatex.in.fname = stream;
+
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+ done:
+       smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+       return ret;
+}
+
+/* Test how streams interact with create dispositions */
+static bool test_stream_create_disposition(struct torture_context *tctx,
+                                          struct smbcli_state *cli,
+                                          TALLOC_CTX *mem_ctx)
+{
+       NTSTATUS status;
+       union smb_open io;
+       const char *fname = BASEDIR "\\stream.txt";
+       const char *stream = "Stream One:$DATA";
+       const char *fname_stream;
+       const char *default_stream_name = "::$DATA";
+       const char *stream_list[2];
+       bool ret = true;
+       int fnum = -1;
+
+       fname_stream = talloc_asprintf(mem_ctx, "%s:%s", fname, stream);
+
+       stream_list[0] = talloc_asprintf(mem_ctx, ":%s", stream);
+       stream_list[1] = default_stream_name;
+
+       if (!create_file_with_stream(tctx, cli, mem_ctx, fname,
+                                    fname_stream)) {
+               goto done;
+       }
+
+       /* Open the base file with OPEN */
+       io.generic.level = RAW_OPEN_NTCREATEX;
+       io.ntcreatex.in.root_fid = 0;
+       io.ntcreatex.in.flags = 0;
+       io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|
+           SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL);
+       io.ntcreatex.in.create_options = 0;
+       io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+       io.ntcreatex.in.share_access = 0;
+       io.ntcreatex.in.alloc_size = 0;
+       io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+       io.ntcreatex.in.security_flags = 0;
+       io.ntcreatex.in.fname = fname;
+
+       /*
+        * check ntcreatex open: sanity check
+        */
+       printf("(%s) Checking ntcreatex disp: open\n", __location__);
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+       if (!check_stream_list(cli, fname, 2, stream_list)) {
+               goto done;
+       }
+
+       /*
+        * check ntcreatex overwrite
+        */
+       printf("(%s) Checking ntcreatex disp: overwrite\n", __location__);
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+       if (!check_stream_list(cli, fname, 1, &default_stream_name)) {
+               goto done;
+       }
+
+       /*
+        * check ntcreatex overwrite_if
+        */
+       printf("(%s) Checking ntcreatex disp: overwrite_if\n", __location__);
+       smbcli_unlink(cli->tree, fname);
+       if (!create_file_with_stream(tctx, cli, mem_ctx, fname,
+                                    fname_stream)) {
+               goto done;
+       }
+
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+       if (!check_stream_list(cli, fname, 1, &default_stream_name)) {
+               goto done;
+       }
+
+       /*
+        * check ntcreatex supersede
+        */
+       printf("(%s) Checking ntcreatex disp: supersede\n", __location__);
+       smbcli_unlink(cli->tree, fname);
+       if (!create_file_with_stream(tctx, cli, mem_ctx, fname,
+                                    fname_stream)) {
+               goto done;
+       }
+
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_SUPERSEDE;
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+       if (!check_stream_list(cli, fname, 1, &default_stream_name)) {
+               goto done;
+       }
+
+       /*
+        * check openx overwrite_if
+        */
+       printf("(%s) Checking openx disp: overwrite_if\n", __location__);
+       smbcli_unlink(cli->tree, fname);
+       if (!create_file_with_stream(tctx, cli, mem_ctx, fname,
+                                    fname_stream)) {
+               goto done;
+       }
+
+       io.openx.level = RAW_OPEN_OPENX;
+       io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
+       io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
+       io.openx.in.search_attrs = 0;
+       io.openx.in.file_attrs = 0;
+       io.openx.in.write_time = 0;
+       io.openx.in.size = 1024*1024;
+       io.openx.in.timeout = 0;
+       io.openx.in.fname = fname;
+
+       io.openx.in.open_func = OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE;
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smbcli_close(cli->tree, io.openx.out.file.fnum);
+       if (!check_stream_list(cli, fname, 1, &default_stream_name)) {
+               goto done;
+       }
+
+ done:
+       smbcli_close(cli->tree, fnum);
+       smbcli_unlink(cli->tree, fname);
+       return ret;
+}
 
 /* 
    basic testing of streams calls
@@ -1336,8 +1501,9 @@ bool torture_raw_streams(struct torture_context *torture,
        smb_raw_exit(cli->session);
        ret &= test_stream_rename2(torture, cli, torture);
        smb_raw_exit(cli->session);
-
+       ret &= test_stream_create_disposition(torture, cli, torture);
        smb_raw_exit(cli->session);
+
        smbcli_deltree(cli->tree, BASEDIR);
 
        return ret;


-- 
Samba Shared Repository

Reply via email to