[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

DACLs patch for linux with XFS filesystem (EXPERIMENTAL)



Hi,

I want DACLs to be honoured by samba.
So my idea is, if we create directory or file in directory which has 
default ACLs (DACLs), to let system set permissions on them.
If somebody wants to test it on another platform, he should fill a 
function in /lib/sysacls.c for it.
Function is:
BOOL sys_acl_has_dacl(const char *path);
This function takes as parameter parent directory of created object.
By now, for other platforms it always returns False, so there is no impact 
for them at all.
Also, if you don't have DACLs on your directories, samba will behave in 
old way.

If it works as you want, I'll add parameter for smb.conf (per share). Oh, 
I have to find how, first ;)

Side effects:
The hidden,system,archive mapping will be probably affected.

I think, that the only right resolution for this, is to put them in EA, on 
filesystems which support EA.

I mould like Jeremy Allison to look at it, and tell if it is OK.
And if it is, I would like to add an option eg.
honour dacls = yes/no
to smb.conf
And to have it in 2.2.4 :)

Regards,

Olaf Fraczyk

diff -r -c samba-2.2.3a/source/include/proto.h samba-2.2.3a-dacl/source/include/proto.h
*** samba-2.2.3a/source/include/proto.h	Sun Feb  3 01:46:40 2002
--- samba-2.2.3a-dacl/source/include/proto.h	Sat Feb 23 17:27:03 2002
***************
*** 937,942 ****
--- 937,943 ----
  int sys_acl_delete_def_file(const char *name);
  int sys_acl_free_acl(SMB_ACL_T the_acl) ;
  int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+ BOOL sys_acl_has_dacl(const char *path);
  
  /*The following definitions come from  lib/system.c  */
  
diff -r -c samba-2.2.3a/source/lib/sysacls.c samba-2.2.3a-dacl/source/lib/sysacls.c
*** samba-2.2.3a/source/lib/sysacls.c	Sun Feb  3 01:46:42 2002
--- samba-2.2.3a-dacl/source/lib/sysacls.c	Sat Feb 23 17:34:20 2002
***************
*** 189,194 ****
--- 189,209 ----
  	return acl_free(qual);
  }
  
+ BOOL sys_acl_has_dacl(const char *path)
+ {
+ 	struct acl *test_acl;
+ 	test_acl=acl_get_file(path,ACL_TYPE_DEFAULT);
+ 	if(!test_acl) {
+ 		return False;
+ 	}
+ 	if(test_acl->acl_cnt>0) {
+ 		acl_free(test_acl);
+ 		return True;
+ 	}
+ 	acl_free(test_acl);
+ 	return False;
+ }
+ 
  #elif defined(HAVE_TRU64_ACLS)
  /*
   * The interface to DEC/Compaq Tru64 UNIX ACLs
***************
*** 345,350 ****
--- 360,371 ----
  	return acl_free_qualifier(qual, tagtype);
  }
  
+ BOOL sys_acl_has_dacl(const char *path)
+ {
+ 	errno = ENOSYS;
+ 	return False;
+ }
+ 
  #elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
  
  /*
***************
*** 977,982 ****
--- 998,1009 ----
  	return 0;
  }
  
+ BOOL sys_acl_has_dacl(const char *path)
+ {
+ 	errno = ENOSYS;
+ 	return False;
+ }
+ 
  #elif defined(HAVE_HPUX_ACLS)
  #include <dl.h>
  
***************
*** 1932,1937 ****
--- 1959,1970 ----
  	return 0;
  }
  
+ BOOL sys_acl_has_dacl(const char *path)
+ {
+ 	errno = ENOSYS;
+ 	return False;
+ }
+ 
  #elif defined(HAVE_IRIX_ACLS)
  
  int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
***************
*** 2187,2192 ****
--- 2220,2237 ----
  	return 0;
  }
  
+ BOOL sys_acl_has_dacl(const char *path)
+ {
+ 	errno = ENOSYS;
+ 	return False;
+ }
+ 
+ BOOL sys_acl_has_dacl(const char *path)
+ {
+ 	errno = ENOSYS;
+ 	return False;
+ }
+ 
  #elif defined(HAVE_AIX_ACLS)
  
  /* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
***************
*** 3206,3209 ****
--- 3251,3260 ----
  	return -1;
  }
  
+ BOOL sys_acl_has_dacl(const char *path)
+ {
+ 	errno = ENOSYS;
+ 	return False;
+ }
+ 
  #endif /* No ACLs. */
diff -r -c samba-2.2.3a/source/smbd/open.c samba-2.2.3a-dacl/source/smbd/open.c
*** samba-2.2.3a/source/smbd/open.c	Sun Feb  3 01:46:56 2002
--- samba-2.2.3a-dacl/source/smbd/open.c	Sat Feb 23 18:24:48 2002
***************
*** 34,45 ****
--- 34,54 ----
  		   int flags, mode_t mode)
  {
  	int fd;
+ 	int saved_errno;
+ 	BOOL has_dacl;
  
  #ifdef O_NOFOLLOW
  	if (!lp_symlinks(SNUM(conn)))
  		flags |= O_NOFOLLOW;
  #endif
  
+ 	saved_errno=errno; /* We may get ENOSYS here */
+ 	has_dacl=sys_acl_has_dacl(parent_dirname(fname));
+ 	errno=saved_errno;
+ 	if(has_dacl) {
+ 	    mode=0777;
+ 	}
+ 
  	fd = conn->vfs_ops.open(conn,dos_to_unix(fname,False),flags,mode);
  
  	/* Fix for files ending in '.' */
***************
*** 633,638 ****
--- 642,649 ----
  	files_struct *fsp = NULL;
  	int open_mode=0;
  	uint16 port = 0;
+ 	int saved_errno;
+ 	BOOL has_dacl;
  
  	if (conn->printer) {
  		/* printers are handled completely differently. Most
***************
*** 925,932 ****
  	 * Take care of inherited ACLs on created files. JRA.
  	 */
  
! 	if (!file_existed && (conn->vfs_ops.fchmod_acl != NULL)) {
! 		int saved_errno = errno; /* We might get ENOSYS in the next call.. */
  		if (conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
  			errno = saved_errno; /* Ignore ENOSYS */
  	}
--- 936,947 ----
  	 * Take care of inherited ACLs on created files. JRA.
  	 */
  
! 	saved_errno = errno; /* We might get ENOSYS in the next call.. */
! 	has_dacl = sys_acl_has_dacl(parent_dirname(fname));
! 	errno=saved_errno;
! 
! 	if (!file_existed && (conn->vfs_ops.fchmod_acl != NULL) && !has_dacl) {
! 		saved_errno = errno; /* We might get ENOSYS in the next call.. */
  		if (conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
  			errno = saved_errno; /* Ignore ENOSYS */
  	}
diff -r -c samba-2.2.3a/source/smbd/vfs-wrap.c samba-2.2.3a-dacl/source/smbd/vfs-wrap.c
*** samba-2.2.3a/source/smbd/vfs-wrap.c	Sun Feb  3 01:46:57 2002
--- samba-2.2.3a-dacl/source/smbd/vfs-wrap.c	Sat Feb 23 17:41:35 2002
***************
*** 96,101 ****
--- 96,103 ----
  int vfswrap_mkdir(connection_struct *conn, char *path, mode_t mode)
  {
      int result;
+     BOOL have_dacl;
+     int saved_errno;
  
      START_PROFILE(syscall_mkdir);
  
***************
*** 104,124 ****
  	smb_panic("NULL pointer passed to vfswrap_mkdir()\n");
      }
  #endif
! 
!     result = mkdir(path, mode);
! 
! 	if (result == 0) {
! 		/*
! 		 * We need to do this as the default behavior of POSIX ACLs	
! 		 * is to set the mask to be the requested group permission
! 		 * bits, not the group permission bits to be the requested
! 		 * group permission bits. This is not what we want, as it will
! 		 * mess up any inherited ACL bits that were set. JRA.
! 		 */
! 		int saved_errno = errno; /* We may get ENOSYS */
! 		if (conn->vfs_ops.chmod_acl != NULL) {
! 			if ((conn->vfs_ops.chmod_acl(conn, path, mode) == -1) && (errno == ENOSYS))
! 				errno = saved_errno;
  		}
  	}
  
--- 106,132 ----
  	smb_panic("NULL pointer passed to vfswrap_mkdir()\n");
      }
  #endif
! 	saved_errno = errno; /* We may get ENOSYS */
! 	have_dacl = sys_acl_has_dacl(parent_dirname(path));
! 	errno = saved_errno;
! 	if(have_dacl) {
! 		result = mkdir(path,0777);
! 	}
! 	else {
! 		result = mkdir(path, mode);
! 		if (result == 0) {
! 			/*
! 		 	* We need to do this as the default behavior of POSIX ACLs	
! 		 	* is to set the mask to be the requested group permission
! 		 	* bits, not the group permission bits to be the requested
! 		 	* group permission bits. This is not what we want, as it will
! 		 	* mess up any inherited ACL bits that were set. JRA.
! 		 	*/
! 			saved_errno = errno; /* We may get ENOSYS */
! 			if (conn->vfs_ops.chmod_acl != NULL) {
! 				if ((conn->vfs_ops.chmod_acl(conn, path, mode) == -1) && (errno == ENOSYS))
! 					errno = saved_errno;
! 			}
  		}
  	}