The branch, v3-2-test has been updated
       via  d4481329438d27a23ded85f01f5cf06725221d0e (commit)
      from  e2f699a5d1a2415ce37c052bf24bbecf0d41bae7 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit d4481329438d27a23ded85f01f5cf06725221d0e
Author: Jeremy Allison <[EMAIL PROTECTED]>
Date:   Fri Nov 21 12:32:11 2008 -0800

    Second part of the fix for bug #5903 - vfs_streams_xattr breaks contents of 
the file
    Jeremy.

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

Summary of changes:
 source/configure.in                |    2 +-
 source/modules/vfs_streams_xattr.c |   61 +++++++++++++++++++++++++++++++++++-
 source/smbd/open.c                 |   59 ++++++++++++++++++++++++++--------
 3 files changed, 106 insertions(+), 16 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/configure.in b/source/configure.in
index 64a4681..733c31e 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -404,7 +404,7 @@ dnl These have to be built static:
 default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr 
rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl2 rpc_ntsvcs2 
rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog2 auth_sam auth_unix 
auth_winbind auth_server auth_domain auth_builtin vfs_default nss_info_template"
 
 dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit 
vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap 
vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 
auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr 
vfs_smb_traffic_analyzer"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit 
vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap 
vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 
auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot 
vfs_smb_traffic_analyzer"
 
 if test "x$developer" = xyes; then
    default_static_modules="$default_static_modules rpc_rpcecho"
diff --git a/source/modules/vfs_streams_xattr.c 
b/source/modules/vfs_streams_xattr.c
index b74c4f7..9df88e5 100644
--- a/source/modules/vfs_streams_xattr.c
+++ b/source/modules/vfs_streams_xattr.c
@@ -624,7 +624,7 @@ static ssize_t streams_xattr_pread(vfs_handle_struct 
*handle,
                (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
        struct ea_struct ea;
        NTSTATUS status;
-        size_t length, overlap;
+       size_t length, overlap;
 
        if (sio == NULL) {
                return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
@@ -651,6 +651,63 @@ static ssize_t streams_xattr_pread(vfs_handle_struct 
*handle,
         return overlap;
 }
 
+static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
+                                       struct files_struct *fsp,
+                                       SMB_OFF_T offset)
+{
+       int ret;
+       uint8 *tmp;
+       struct ea_struct ea;
+       NTSTATUS status;
+        struct stream_io *sio =
+               (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+
+       DEBUG(10, ("streams_xattr_ftruncate called for file %s offset %.0f\n",
+               fsp->fsp_name,
+               (double)offset ));
+
+       if (sio == NULL) {
+               return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
+       }
+
+       status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
+                             sio->base, sio->xattr_name, &ea);
+       if (!NT_STATUS_IS_OK(status)) {
+               return -1;
+       }
+
+       tmp = TALLOC_REALLOC_ARRAY(talloc_tos(), ea.value.data, uint8,
+                                  offset + 1);
+
+       if (tmp == NULL) {
+               TALLOC_FREE(ea.value.data);
+               errno = ENOMEM;
+               return -1;
+       }
+
+       /* Did we expand ? */
+       if (ea.value.length < offset + 1) {
+               memset(&tmp[ea.value.length], '\0',
+                       offset + 1 - ea.value.length);
+       }
+
+       ea.value.data = tmp;
+       ea.value.length = offset + 1;
+       ea.value.data[offset] = 0;
+
+       ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+                               sio->xattr_name,
+                               ea.value.data, ea.value.length, 0);
+
+       TALLOC_FREE(ea.value.data);
+
+       if (ret == -1) {
+               return -1;
+       }
+
+       return 0;
+}
+
 /* VFS operations structure */
 
 static vfs_op_tuple streams_xattr_ops[] = {
@@ -672,6 +729,8 @@ static vfs_op_tuple streams_xattr_ops[] = {
         SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(streams_xattr_unlink), SMB_VFS_OP_UNLINK,
         SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(streams_xattr_ftruncate),  SMB_VFS_OP_FTRUNCATE,
+         SMB_VFS_LAYER_TRANSPARENT},
        {SMB_VFS_OP(streams_xattr_streaminfo), SMB_VFS_OP_STREAMINFO,
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 6ba6df2..298d5e6 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -2774,10 +2774,42 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
                 * Ordinary file case.
                 */
 
-               status = open_file_ntcreate(
-                       conn, req, fname, &sbuf, access_mask, share_access,
-                       create_disposition, create_options, file_attributes,
-                       oplock_request, &info, &fsp);
+               if (base_fsp) {
+                       /*
+                        * We're opening the stream element of a base_fsp
+                        * we already opened. We need to initialize
+                        * the fsp first, and set up the base_fsp pointer.
+                        */
+                       status = file_new(conn, &fsp);
+                       if(!NT_STATUS_IS_OK(status)) {
+                               goto fail;
+                       }
+
+                       fsp->base_fsp = base_fsp;
+
+                       status = open_file_ntcreate_internal(conn,
+                                               req,
+                                               fname,
+                                               &sbuf,
+                                               access_mask,
+                                               share_access,
+                                               create_disposition,
+                                               create_options,
+                                               file_attributes,
+                                               oplock_request,
+                                               &info,
+                                               fsp);
+
+                       if(!NT_STATUS_IS_OK(status)) {
+                               file_free(fsp);
+                               fsp = NULL;
+                       }
+               } else {
+                       status = open_file_ntcreate(
+                               conn, req, fname, &sbuf, access_mask, 
share_access,
+                               create_disposition, create_options, 
file_attributes,
+                               oplock_request, &info, &fsp);
+               }
 
                if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
 
@@ -2804,6 +2836,8 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
                goto fail;
        }
 
+       fsp->base_fsp = base_fsp;
+
        /*
         * According to the MS documentation, the only time the security
         * descriptor is applied to the opened file is iff we *created* the
@@ -2881,16 +2915,6 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
 
        DEBUG(10, ("create_file_unixpath: info=%d\n", info));
 
-       /*
-        * Set fsp->base_fsp late enough that we can't "goto fail" anymore. In
-        * the fail: branch we call close_file(fsp, ERROR_CLOSE) which would
-        * also close fsp->base_fsp which we have to also do explicitly in
-        * this routine here, as not in all "goto fail:" we have the fsp set
-        * up already to be initialized with the base_fsp.
-        */
-
-       fsp->base_fsp = base_fsp;
-
        *result = fsp;
        if (pinfo != NULL) {
                *pinfo = info;
@@ -2909,6 +2933,13 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
        DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
 
        if (fsp != NULL) {
+               if (base_fsp && fsp->base_fsp == base_fsp) {
+                       /*
+                        * The close_file below will close
+                        * fsp->base_fsp.
+                        */
+                       base_fsp = NULL;
+               }
                close_file(fsp, ERROR_CLOSE);
                fsp = NULL;
        }


-- 
Samba Shared Repository

Reply via email to