Final part of patchset to fix bug #8556 - ACL permissions ignored when SMBsetatr...
authorJeremy Allison <jra@samba.org>
Wed, 16 Nov 2011 01:29:59 +0000 (17:29 -0800)
committerJeremy Allison <jra@samba.org>
Wed, 16 Nov 2011 03:20:04 +0000 (04:20 +0100)
This now plumbs access checks through all setattr calls.

Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Wed Nov 16 04:20:04 CET 2011 on sn-devel-104

source3/smbd/proto.h
source3/smbd/reply.c
source3/smbd/trans2.c

index fe9076647e572844cdaf16b648b61b4a29a6103c..151ae78ec39b31d79c0fcab5af81251764bc12c1 100644 (file)
@@ -1059,6 +1059,10 @@ int sys_statvfs(const char *path, vfs_statvfs_struct *statbuf);
 
 /* The following definitions come from smbd/trans2.c  */
 
+NTSTATUS check_access(connection_struct *conn,
+                               files_struct *fsp,
+                               const struct smb_filename *smb_fname,
+                               uint32_t access_mask);
 uint64_t smb_roundup(connection_struct *conn, uint64_t val);
 uint64_t get_FileIndex(connection_struct *conn, const SMB_STRUCT_STAT *psbuf);
 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
index 18ebca1ce2bb61583e8ab5fb452ef47c35762b44..7dd3260f0b05532a992cc26b447b9070c45835c5 100644 (file)
@@ -1275,6 +1275,13 @@ void reply_setatr(struct smb_request *req)
                else
                        mode &= ~FILE_ATTRIBUTE_DIRECTORY;
 
+               status = check_access(conn, NULL, smb_fname,
+                                       FILE_WRITE_ATTRIBUTES);
+               if (!NT_STATUS_IS_OK(status)) {
+                       reply_nterror(req, status);
+                       goto out;
+               }
+
                if (file_set_dosmode(conn, smb_fname, mode, NULL,
                                     false) != 0) {
                        reply_nterror(req, map_nt_error_from_unix(errno));
index 0e831ecff9cabee2e649897b3034f934b891c964..024979c20097af2b5418ef5ae24a37d1ccb79d76 100644 (file)
@@ -49,6 +49,30 @@ static char *store_file_unix_basic_info2(connection_struct *conn,
                                files_struct *fsp,
                                const SMB_STRUCT_STAT *psbuf);
 
+/********************************************************************
+ The canonical "check access" based on object handle or path function.
+********************************************************************/
+
+NTSTATUS check_access(connection_struct *conn,
+                               files_struct *fsp,
+                               const struct smb_filename *smb_fname,
+                               uint32_t access_mask)
+{
+       if (fsp) {
+               if (!(fsp->access_mask & access_mask)) {
+                       return NT_STATUS_ACCESS_DENIED;
+               }
+       } else {
+               NTSTATUS status = smbd_check_access_rights(conn,
+                                       smb_fname,
+                                       access_mask);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+       return NT_STATUS_OK;
+}
+
 /********************************************************************
  Roundup a value to the nearest allocation roundup size boundary.
  Only do this for Windows clients.
@@ -504,14 +528,16 @@ static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, con
 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
                const struct smb_filename *smb_fname, struct ea_list *ea_list)
 {
+       NTSTATUS status;
        char *fname = NULL;
 
        if (!lp_ea_support(SNUM(conn))) {
                return NT_STATUS_EAS_NOT_SUPPORTED;
        }
 
-       if (fsp && !(fsp->access_mask & FILE_WRITE_EA)) {
-               return NT_STATUS_ACCESS_DENIED;
+       status = check_access(conn, fsp, smb_fname, FILE_WRITE_EA);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
        /* For now setting EAs on streams isn't supported. */
@@ -5540,6 +5566,8 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
 
 /****************************************************************************
  Deal with setting the dosmode from any of the setfilepathinfo functions.
+ NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
+ done before calling this function.
 ****************************************************************************/
 
 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
@@ -5724,10 +5752,6 @@ static NTSTATUS smb_info_set_ea(connection_struct *conn,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (fsp && !(fsp->access_mask & FILE_WRITE_EA)) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        status = set_ea(conn, fsp, smb_fname, ea_list);
 
        return status;
@@ -5771,10 +5795,6 @@ static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (!(fsp->access_mask & FILE_WRITE_EA)) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
 
        DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
@@ -6514,8 +6534,9 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (fsp && !(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) {
-               return NT_STATUS_ACCESS_DENIED;
+       status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
        /* Set the attributes */
@@ -6554,6 +6575,7 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn,
                                        files_struct *fsp,
                                        const struct smb_filename *smb_fname)
 {
+       NTSTATUS status;
        struct smb_file_time ft;
 
        ZERO_STRUCT(ft);
@@ -6572,8 +6594,9 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn,
        DEBUG(10,("smb_set_info_standard: file %s\n",
                smb_fname_str_dbg(smb_fname)));
 
-       if (fsp && !(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) {
-               return NT_STATUS_ACCESS_DENIED;
+       status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
         return smb_set_file_time(conn,
@@ -6946,8 +6969,9 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
        }
 #endif
 
-       if (fsp && !(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) {
-               return NT_STATUS_ACCESS_DENIED;
+       status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
        /*