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