summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/posix_acls.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index e92a263ca0..427cfc9a0d 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2362,20 +2362,32 @@ static bool current_user_in_group(gid_t gid)
}
/****************************************************************************
- Should we override a deny ? Check deprecated 'acl group control'
- and 'dos filemode'
+ Should we override a deny ? Check 'acl group control' and 'dos filemode'.
****************************************************************************/
-static bool acl_group_override(connection_struct *conn, gid_t prim_gid)
+static bool acl_group_override(connection_struct *conn,
+ gid_t prim_gid,
+ const char *fname)
{
- if ( (errno == EACCES || errno == EPERM)
- && (lp_acl_group_control(SNUM(conn)) || lp_dos_filemode(SNUM(conn)))
- && current_user_in_group(prim_gid))
- {
- return True;
- }
+ SMB_STRUCT_STAT sbuf;
- return False;
+ if ((errno != EPERM) && (errno != EACCES)) {
+ return false;
+ }
+
+ /* file primary group == user primary or supplementary group */
+ if (lp_acl_group_control(SNUM(conn)) &&
+ current_user_in_group(prim_gid)) {
+ return true;
+ }
+
+ /* user has writeable permission */
+ if (lp_dos_filemode(SNUM(conn)) &&
+ can_write_to_file(conn, fname, &sbuf)) {
+ return true;
+ }
+
+ return false;
}
/****************************************************************************
@@ -2561,7 +2573,7 @@ static bool set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, bool defau
*pacl_set_support = False;
}
- if (acl_group_override(conn, prim_gid)) {
+ if (acl_group_override(conn, prim_gid, fsp->fsp_name)) {
int sret;
DEBUG(5,("set_canon_ace_list: acl group control on and current user in file %s primary group.\n",
@@ -2592,7 +2604,7 @@ static bool set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, bool defau
*pacl_set_support = False;
}
- if (acl_group_override(conn, prim_gid)) {
+ if (acl_group_override(conn, prim_gid, fsp->fsp_name)) {
int sret;
DEBUG(5,("set_canon_ace_list: acl group control on and current user in file %s primary group.\n",
@@ -3570,7 +3582,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name) == -1) {
int sret = -1;
- if (acl_group_override(conn, sbuf.st_gid)) {
+ if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
DEBUG(5,("set_nt_acl: acl group control on and "
"current user in file %s primary group. Override delete_def_acl\n",
fsp->fsp_name ));
@@ -3617,7 +3629,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
if(SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms) == -1) {
int sret = -1;
- if (acl_group_override(conn, sbuf.st_gid)) {
+ if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
DEBUG(5,("set_nt_acl: acl group control on and "
"current user in file %s primary group. Override chmod\n",
fsp->fsp_name ));