summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/smbd/open.c14
-rw-r--r--source3/smbd/posix_acls.c13
-rw-r--r--source3/smbd/vfs-wrap.c18
4 files changed, 40 insertions, 9 deletions
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index ea3894c236..ec7d768023 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -387,6 +387,7 @@ typedef struct
BOOL bFakeDirCreateTimes;
BOOL bBlockingLocks;
BOOL bInheritPerms;
+ BOOL bInheritACLS;
BOOL bMSDfsRoot;
BOOL bUseClientDriver;
BOOL bDefaultDevmode;
@@ -502,6 +503,7 @@ static service sDefault = {
False, /* bFakeDirCreateTimes */
True, /* bBlockingLocks */
False, /* bInheritPerms */
+ False, /* bInheritACLS */
False, /* bMSDfsRoot */
False, /* bUseClientDriver */
False, /* bDefaultDevmode */
@@ -752,6 +754,7 @@ static struct parm_struct parm_table[] = {
{"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
{"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
{"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
+ {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_SHARE},
{"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
{"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
@@ -1737,6 +1740,7 @@ FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
+FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 03646c5019..b284175302 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -646,6 +646,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
BOOL file_existed = VALID_STAT(*psbuf);
BOOL fcbopen = False;
+ BOOL def_acl = False;
SMB_DEV_T dev = 0;
SMB_INO_T inode = 0;
int num_share_modes = 0;
@@ -800,6 +801,14 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
*/
}
+ /*
+ * Ensure we pay attention to default ACLs on directories if required.
+ */
+
+ if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
+ (def_acl = directory_has_default_acl(parent_dirname(fname))))
+ mode = 0777;
+
DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
flags,flags2,(int)mode));
@@ -951,10 +960,11 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
}
/*
- * Take care of inherited ACLs on created files. JRA.
+ * Take care of inherited ACLs on created files - if default ACL not
+ * selected.
*/
- if (!file_existed && (conn->vfs_ops.fchmod_acl != NULL)) {
+ if (!file_existed && !def_acl && (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 */
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index ee1935a41f..34f0b77002 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2294,3 +2294,16 @@ int fchmod_acl(int fd, mode_t mode)
sys_acl_free_acl(posix_acl);
return ret;
}
+
+BOOL directory_has_default_acl(const char *fname)
+{
+ SMB_ACL_T dir_acl = sys_acl_get_file( fname, SMB_ACL_TYPE_DEFAULT);
+ BOOL has_acl = False;
+ SMB_ACL_ENTRY_T entry;
+
+ if (dir_acl != NULL && (sys_acl_get_entry(dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1))
+ has_acl = True;
+
+ sys_acl_free_acl(dir_acl);
+ return has_acl;
+}
diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c
index bb7d497274..78c6fb3905 100644
--- a/source3/smbd/vfs-wrap.c
+++ b/source3/smbd/vfs-wrap.c
@@ -94,19 +94,23 @@ struct dirent *vfswrap_readdir(connection_struct *conn, DIR *dirp)
int vfswrap_mkdir(connection_struct *conn, const char *path, mode_t mode)
{
- int result;
+ int result;
+ BOOL has_dacl = False;
- START_PROFILE(syscall_mkdir);
+ START_PROFILE(syscall_mkdir);
#ifdef VFS_CHECK_NULL
- if (path == NULL) {
- smb_panic("NULL pointer passed to vfswrap_mkdir()\n");
- }
+ if (path == NULL) {
+ smb_panic("NULL pointer passed to vfswrap_mkdir()\n");
+ }
#endif
- result = mkdir(path, mode);
+ if (lp_inherit_acls(SNUM(conn)) && (has_dacl = directory_has_default_acl(parent_dirname(path))))
+ mode = 0777;
+
+ result = mkdir(path, mode);
- if (result == 0) {
+ if (result == 0 && !has_dacl) {
/*
* We need to do this as the default behavior of POSIX ACLs
* is to set the mask to be the requested group permission