[SCM] Samba Shared Repository - branch master updated - 8d674e351ada654ab79d635851ac73cef71d4753

Jeremy Allison jra at samba.org
Fri Nov 21 23:43:28 GMT 2008


The branch, master has been updated
       via  8d674e351ada654ab79d635851ac73cef71d4753 (commit)
      from  dd54e680143675698330f49b9aed7188f37bec65 (commit)

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


- Log -----------------------------------------------------------------
commit 8d674e351ada654ab79d635851ac73cef71d4753
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Nov 21 15:42:03 2008 -0800

    Second part of the fix for bug #5903 - vfs_streams_xattr breaks contents of the file
    (also fix a bad merge of the previous patch from 3.3).
    Jeremy.

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

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


Changeset truncated at 500 lines:

diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index b74c4f7..9df88e5 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/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/source3/smbd/open.c b/source3/smbd/open.c
index aca6491..a6867e0 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1651,7 +1651,7 @@ static NTSTATUS open_file_ntcreate_internal(connection_struct *conn,
 							share_access,
 							create_options);
 
-				if (!NT_STATUS_IS_OK(status)) {
+				if (NT_STATUS_IS_OK(status)) {
 					TALLOC_FREE(lck);
 					if (pinfo) {
 						*pinfo = FILE_WAS_OPENED;
@@ -2878,10 +2878,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(req, 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(req, 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)) {
 
@@ -2908,6 +2940,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
@@ -2994,16 +3028,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;
@@ -3022,6 +3046,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(req, fsp, ERROR_CLOSE);
 		fsp = NULL;
 	}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list