[PATCH] Prevent the overwriting of global errno in set file info code path.

Surbhi Palande surbhi.palande at canonical.com
Tue Mar 16 02:10:07 MDT 2010


BugLink: http://launchpad.net/bugs/276472

In the code path for setting the file info, the set_unix_posix_default_acl()
calls set_unix_posix_default_acl() for setting the posix acl. The mapping of
the unix errors to NT errors is based on the global error numbers set by the
set_unix_posix_default_acl(). However this error number is overwritten by
a call to SMB_VFS_SYS_ACL_FREE_ACL() before returning from
set_unix_posix_default_acl(). The overwritten value is a -EINVAL. This
translates to the NT_STATUS_ACCESS_DENIED instead of the expected
NT_STATUS_NOT_SUPPORTED error code.

Signed-off-by: Surbhi Palande <surbhi.palande at canonical.com>
---
Patch basic Tested for version: 3.6. More testing will be appreciated.
Please do include me in any replies as I am not on the mailing list.
 source3/modules/vfs_posixacl.c |    8 +++++++-
 source3/smbd/posix_acls.c      |    5 +++++
 2 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/source3/modules/vfs_posixacl.c b/source3/modules/vfs_posixacl.c
index 9dd25a7..fe62c2a 100644
--- a/source3/modules/vfs_posixacl.c
+++ b/source3/modules/vfs_posixacl.c
@@ -82,7 +82,7 @@ int posixacl_sys_acl_set_file(vfs_handle_struct *handle,
 			      SMB_ACL_TYPE_T type,
 			      SMB_ACL_T theacl)
 {
-	int res;
+	int res, set_acl_errno;
 	acl_type_t acl_type;
 	acl_t acl;
 
@@ -105,9 +105,15 @@ int posixacl_sys_acl_set_file(vfs_handle_struct *handle,
 	}
 	res = acl_set_file(name, acl_type, acl);
 	if (res != 0) {
+		set_acl_errno = errno;
 		DEBUG(10, ("acl_set_file failed: %s\n", strerror(errno)));
 	}
+	/* acl_free() could overwrite the errno but
+	 * we are interested in errno set by acl_set_file
+	 */
 	acl_free(acl);
+	if (res < 0)
+		errno = set_acl_errno;
 	return res;
 }
 
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index c00b7bd..0dc84c1 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -4499,9 +4499,14 @@ bool set_unix_posix_default_acl(connection_struct *conn, const char *fname, cons
 	}
 
 	if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT, def_acl) == -1) {
+		int set_acl_errno = errno;
 		DEBUG(5,("set_unix_posix_default_acl: acl_set_file failed on directory %s (%s)\n",
 			fname, strerror(errno) ));
 	        SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+		/* errno could be overwritten by SMB_VFS_SYS_ACL_FREE_ACL
+		 * we are interested in errno of SMB_VFS_SYS_ACL_SET_FILE
+		 */ 
+		errno = set_acl_errno;
 		return False;
 	}
 
-- 
1.6.3.3



More information about the samba-technical mailing list