r4408: added the remaining access check hooks into pvfs. All calls should now have...
authorAndrew Tridgell <tridge@samba.org>
Thu, 30 Dec 2004 05:50:23 +0000 (05:50 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:07:44 +0000 (13:07 -0500)
and obey the various inheritance rules.
(This used to be commit 5fe51807d6b97e68b65f152c0f405e5c5a025d21)

source4/ntvfs/posix/pvfs_acl.c
source4/ntvfs/posix/pvfs_mkdir.c
source4/ntvfs/posix/pvfs_open.c
source4/ntvfs/posix/pvfs_qfileinfo.c
source4/ntvfs/posix/pvfs_rename.c
source4/ntvfs/posix/pvfs_setfileinfo.c

index c2309b92ea81ce975985510dbcfc7981757a3840..a5cd9ebd79db30b8c358f04c37a48d46dc2f1239 100644 (file)
@@ -371,9 +371,30 @@ NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs,
                                  struct pvfs_filename *name,
                                  uint32_t access_needed)
 {
+       if (access_needed == 0) {
+               return NT_STATUS_OK;
+       }
        return pvfs_access_check(pvfs, req, name, &access_needed);
 }
 
+/*
+  access check for creating a new file/directory
+*/
+NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, 
+                                 struct smbsrv_request *req,
+                                 struct pvfs_filename *name)
+{
+       struct pvfs_filename *parent;
+       NTSTATUS status;
+
+       status = pvfs_resolve_parent(pvfs, req, name, &parent);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       return pvfs_access_check_simple(pvfs, req, name, SEC_DIR_ADD_FILE);
+}
+
 
 /*
   determine if an ACE is inheritable
index 14fffb6a2e4fb736d6833a66a3f996869a697642..d2d431ae79fe0618cd5100ddbb7a020b2de8a5e5 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "includes.h"
 #include "vfs_posix.h"
+#include "librpc/gen_ndr/ndr_security.h"
 
 /*
   create a directory with EAs
@@ -43,6 +44,11 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs,
                return NT_STATUS_OBJECT_NAME_COLLISION;
        }
 
+       status = pvfs_access_check_create(pvfs, req, name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY);
 
        if (mkdir(name->full_name, mode) == -1) {
@@ -108,6 +114,11 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_OBJECT_NAME_COLLISION;
        }
 
+       status = pvfs_access_check_create(pvfs, req, name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY);
 
        if (mkdir(name->full_name, mode) == -1) {
@@ -146,6 +157,11 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
+       status = pvfs_access_check_simple(pvfs, req, name, SEC_STD_DELETE);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        status = pvfs_xattr_unlink_hook(pvfs, name->full_name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
index 1695d8e1d9bb50dd703e13d492922cfc953c9081..3941414cd8fda0476b5de97ab9999fcb0da6ff4a 100644 (file)
@@ -198,10 +198,12 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
        if (name->exists) {
                /* check the security descriptor */
                status = pvfs_access_check(pvfs, req, name, &access_mask);
-               if (!NT_STATUS_IS_OK(status)) {
-                       idr_remove(pvfs->idtree_fnum, fnum);
-                       return status;
-               }
+       } else {
+               status = pvfs_access_check_create(pvfs, req, name);
+       }
+       if (!NT_STATUS_IS_OK(status)) {
+               idr_remove(pvfs->idtree_fnum, fnum);
+               return status;
        }
 
        f->fnum          = fnum;
@@ -450,6 +452,11 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
        mode_t mode;
        uint32_t attrib;
 
+       status = pvfs_access_check_create(pvfs, req, name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) &&
            (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
                return NT_STATUS_CANNOT_DELETE;
@@ -1065,6 +1072,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 
        /* if this was a stream create then create the stream as well */
        if (!name->stream_exists) {
+               if (!(access_mask & SEC_FILE_WRITE_ATTRIBUTE)) {
+                       return NT_STATUS_ACCESS_DENIED;
+               }
                status = pvfs_stream_create(pvfs, f->handle->name, fd);
                if (!NT_STATUS_IS_OK(status)) {
                        talloc_free(lck);
index 75a99094925eec418f9baf9dcec28bf151244b44..dae9ca649cb3a363f79725b52916ba8a2b829047 100644 (file)
 #include "vfs_posix.h"
 #include "librpc/gen_ndr/ndr_xattr.h"
 
+
+/*
+  determine what access bits are needed for a call
+*/
+static uint32_t pvfs_fileinfo_access(enum smb_fileinfo_level level)
+{
+       uint32_t needed;
+
+       switch (level) {
+       case RAW_FILEINFO_EA_LIST:
+       case RAW_FILEINFO_ALL_EAS:
+               needed = SEC_FILE_READ_EA;
+               break;
+
+       case RAW_FILEINFO_IS_NAME_VALID:
+               needed = 0;
+               break;
+
+       default:
+               needed = SEC_FILE_READ_ATTRIBUTE;
+               break;
+       }
+       return needed;  
+}
+
 /*
   reply to a RAW_FILEINFO_EA_LIST call
 */
@@ -269,6 +294,12 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
+       status = pvfs_access_check_simple(pvfs, req, name, 
+                                         pvfs_fileinfo_access(info->generic.level));
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        status = pvfs_map_fileinfo(pvfs, req, name, info, -1);
 
        return status;
@@ -284,6 +315,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs,
        struct pvfs_file *f;
        struct pvfs_file_handle *h;
        NTSTATUS status;
+       uint32_t access_needed;
 
        f = pvfs_find_fd(pvfs, req, info->generic.in.fnum);
        if (!f) {
@@ -291,6 +323,11 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs,
        }
        h = f->handle;
 
+       access_needed = pvfs_fileinfo_access(info->generic.level);
+       if (!(f->access_mask & access_needed)) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
        /* update the file information */
        status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
        if (!NT_STATUS_IS_OK(status)) {
index 0ca05bbc170e4cb5ccd1fb332197b6e0d466c024..9fe92c917389283e3f46b2301f89ce240e78ab01 100644 (file)
@@ -169,6 +169,11 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs,
                }
        }
 
+       status = pvfs_access_check_create(pvfs, req, name2);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        fname2 = talloc_asprintf(mem_ctx, "%s/%s", dir_path, fname2);
        if (fname2 == NULL) {
                return NT_STATUS_NO_MEMORY;
@@ -283,6 +288,11 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs,
                return status;
        }
 
+       status = pvfs_access_check_create(pvfs, req, name2);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        status = pvfs_can_rename(pvfs, name1);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -357,18 +367,30 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
 
        switch (ren->ntrename.in.flags) {
        case RENAME_FLAG_RENAME:
+               status = pvfs_access_check_create(pvfs, req, name2);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
                if (rename(name1->full_name, name2->full_name) == -1) {
                        return pvfs_map_errno(pvfs, errno);
                }
                break;
 
        case RENAME_FLAG_HARD_LINK:
+               status = pvfs_access_check_create(pvfs, req, name2);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
                if (link(name1->full_name, name2->full_name) == -1) {
                        return pvfs_map_errno(pvfs, errno);
                }
                break;
 
        case RENAME_FLAG_COPY:
+               status = pvfs_access_check_create(pvfs, req, name2);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
                return pvfs_copy_file(pvfs, name1, name2);
 
        case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
index 31db6ce630647f85388ba7d839585c2c4164613d..10eb0821838b2f83e9abc3b5b36f44fe3adbd08d 100644 (file)
 #include "librpc/gen_ndr/ndr_xattr.h"
 
 
+/*
+  determine what access bits are needed for a call
+*/
+static uint32_t pvfs_setfileinfo_access(enum smb_setfileinfo_level level)
+{
+       uint32_t needed;
+
+       switch (level) {
+       case RAW_SFILEINFO_EA_SET:
+               needed = SEC_FILE_WRITE_EA;
+               break;
+
+       case RAW_SFILEINFO_DISPOSITION_INFO:
+       case RAW_SFILEINFO_DISPOSITION_INFORMATION:
+               needed = SEC_STD_DELETE;
+               break;
+
+       case RAW_SFILEINFO_END_OF_FILE_INFO:
+               needed = SEC_FILE_WRITE_DATA;
+               break;
+
+       case RAW_SFILEINFO_POSITION_INFORMATION:
+               needed = 0;
+               break;
+
+       default:
+               needed = SEC_FILE_WRITE_ATTRIBUTE;
+               break;
+       }
+       return needed;  
+}
+
 /*
   rename_information level
 */
@@ -100,6 +132,11 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
                }
        }
 
+       status = pvfs_access_check_create(pvfs, req, name2);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (rename(name->full_name, name2->full_name) == -1) {
                return pvfs_map_errno(pvfs, errno);
        }
@@ -202,6 +239,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
        uint32_t create_options;
        struct pvfs_filename newstats;
        NTSTATUS status;
+       uint32_t access_needed;
 
        f = pvfs_find_fd(pvfs, req, info->generic.file.fnum);
        if (!f) {
@@ -210,6 +248,11 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
 
        h = f->handle;
 
+       access_needed = pvfs_setfileinfo_access(info->generic.level);
+       if (!(f->access_mask & access_needed)) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
        /* update the file information */
        status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
        if (!NT_STATUS_IS_OK(status)) {
@@ -272,9 +315,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
 
        case RAW_SFILEINFO_DISPOSITION_INFO:
        case RAW_SFILEINFO_DISPOSITION_INFORMATION:
-               if (!(f->access_mask & SEC_STD_DELETE)) {
-                       return NT_STATUS_ACCESS_DENIED;
-               }
                create_options = h->create_options;
                if (info->disposition_info.in.delete_on_close) {
                        create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
@@ -389,6 +429,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
        struct pvfs_filename newstats;
        NTSTATUS status;
        struct utimbuf unix_times;
+       uint32_t access_needed;
 
        /* resolve the cifs name to a posix name */
        status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, 
@@ -401,6 +442,11 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
+       access_needed = pvfs_setfileinfo_access(info->generic.level);
+       status = pvfs_access_check_simple(pvfs, req, name, access_needed);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
        /* we take a copy of the current file stats, then update
           newstats in each of the elements below. At the end we