diff options
-rw-r--r-- | source3/param/loadparm.c | 4 | ||||
-rw-r--r-- | source3/smbd/open.c | 14 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 13 | ||||
-rw-r--r-- | source3/smbd/vfs-wrap.c | 18 |
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 |