s4-ntvfs: added allow_override check based on use of NT ACL
authorAndrew Tridgell <tridge@samba.org>
Thu, 1 Dec 2011 02:40:49 +0000 (13:40 +1100)
committerAndrew Tridgell <tridge@samba.org>
Thu, 1 Dec 2011 04:14:49 +0000 (05:14 +0100)
This disables the posix permission override if the calculated
permissions did not come from a NT ACL.

Autobuild-User: Andrew Tridgell <tridge@samba.org>
Autobuild-Date: Thu Dec  1 05:14:49 CET 2011 on sn-devel-104

source4/ntvfs/posix/pvfs_acl.c
source4/ntvfs/posix/pvfs_mkdir.c
source4/ntvfs/posix/pvfs_open.c
source4/ntvfs/posix/pvfs_rename.c
source4/ntvfs/posix/pvfs_resolve.c
source4/ntvfs/posix/pvfs_setfileinfo.c
source4/ntvfs/posix/pvfs_sys.c
source4/ntvfs/posix/pvfs_unlink.c
source4/ntvfs/posix/pvfs_util.c
source4/ntvfs/posix/vfs_posix.h

index 664196ab3e44dbb79467998c580f9bb163493baa..810dcddbd30d84cb21cfd1a68b975a1979f6aac4 100644 (file)
@@ -643,6 +643,14 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
        /* check the acl against the required access mask */
        status = se_access_check(sd, token, *access_mask, access_mask);
        talloc_free(acl);
+
+       /* if we used a NT acl, then allow access override if the
+          share allows for posix permission override
+       */
+       if (NT_STATUS_IS_OK(status)) {
+               name->allow_override = (pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) != 0;
+       }
+
 done:
        if (pvfs->ntvfs->ctx->protocol < PROTOCOL_SMB2_02) {
                /* on SMB, this bit is always granted, even if not
@@ -771,7 +779,11 @@ NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs,
                return status;
        }
 
-       return pvfs_access_check_simple(pvfs, req, parent, access_mask);
+       status = pvfs_access_check_simple(pvfs, req, parent, access_mask);
+       if (NT_STATUS_IS_OK(status) && parent->allow_override) {
+               name->allow_override = true;
+       }
+       return status;
 }
 
 
index 10de1d6d5c122d6f940c2d104adbf0c23e41eac2..2cf43ab1e1d9c0eb81b18715de746b039f67a22f 100644 (file)
@@ -51,7 +51,7 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs,
 
        mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY);
 
-       if (pvfs_sys_mkdir(pvfs, name->full_name, mode) == -1) {
+       if (pvfs_sys_mkdir(pvfs, name->full_name, mode, name->allow_override) == -1) {
                return pvfs_map_errno(pvfs, errno);
        }
 
@@ -69,7 +69,7 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs,
        /* setup an inherited acl from the parent */
        status = pvfs_acl_inherit(pvfs, req, name, -1);
        if (!NT_STATUS_IS_OK(status)) {
-               pvfs_sys_rmdir(pvfs, name->full_name);
+               pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override);
                return status;
        }
 
@@ -78,7 +78,7 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs,
                                         md->t2mkdir.in.num_eas,
                                         md->t2mkdir.in.eas);
        if (!NT_STATUS_IS_OK(status)) {
-               pvfs_sys_rmdir(pvfs, name->full_name);
+               pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override);
                return status;
        }
 
@@ -127,7 +127,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs,
 
        mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY);
 
-       if (pvfs_sys_mkdir(pvfs, name->full_name, mode) == -1) {
+       if (pvfs_sys_mkdir(pvfs, name->full_name, mode, name->allow_override) == -1) {
                return pvfs_map_errno(pvfs, errno);
        }
 
@@ -136,7 +136,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs,
        /* setup an inherited acl from the parent */
        status = pvfs_acl_inherit(pvfs, req, name, -1);
        if (!NT_STATUS_IS_OK(status)) {
-               pvfs_sys_rmdir(pvfs, name->full_name);
+               pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override);
                return status;
        }
 
@@ -179,7 +179,7 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs,
                return status;
        }
 
-       if (pvfs_sys_rmdir(pvfs, name->full_name) == -1) {
+       if (pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override) == -1) {
                /* some olders systems don't return ENOTEMPTY to rmdir() */
                if (errno == EEXIST) {
                        return NT_STATUS_DIRECTORY_NOT_EMPTY;
index c0f55e8e73ceda6d59a87844e9f9f6cdc83277d8..a095f746331adca236e69caae9d1d8afe06d471e 100644 (file)
@@ -73,7 +73,7 @@ static int pvfs_dir_handle_destructor(struct pvfs_file_handle *h)
                                DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n",
                                         delete_path, nt_errstr(status)));
                        }
-                       if (pvfs_sys_rmdir(h->pvfs, delete_path) != 0) {
+                       if (pvfs_sys_rmdir(h->pvfs, delete_path, h->name->allow_override) != 0) {
                                DEBUG(0,("pvfs_dir_handle_destructor: failed to rmdir '%s' - %s\n",
                                         delete_path, strerror(errno)));
                        }
@@ -344,7 +344,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
                uint32_t attrib = io->generic.in.file_attr | FILE_ATTRIBUTE_DIRECTORY;
                mode_t mode = pvfs_fileperms(pvfs, attrib);
 
-               if (pvfs_sys_mkdir(pvfs, name->full_name, mode) == -1) {
+               if (pvfs_sys_mkdir(pvfs, name->full_name, mode, name->allow_override) == -1) {
                        return pvfs_map_errno(pvfs,errno);
                }
 
@@ -432,7 +432,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
        return NT_STATUS_OK;
 
 cleanup_delete:
-       pvfs_sys_rmdir(pvfs, name->full_name);
+       pvfs_sys_rmdir(pvfs, name->full_name, name->allow_override);
        return status;
 }
 
@@ -514,7 +514,7 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h)
                                DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n",
                                         delete_path, nt_errstr(status)));
                        }
-                       if (pvfs_sys_unlink(h->pvfs, delete_path) != 0) {
+                       if (pvfs_sys_unlink(h->pvfs, delete_path, h->name->allow_override) != 0) {
                                DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n",
                                         delete_path, strerror(errno)));
                        } else {
@@ -677,7 +677,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
        mode = pvfs_fileperms(pvfs, attrib);
 
        /* create the file */
-       fd = pvfs_sys_open(pvfs, name->full_name, flags | O_CREAT | O_EXCL| O_NONBLOCK, mode);
+       fd = pvfs_sys_open(pvfs, name->full_name, flags | O_CREAT | O_EXCL| O_NONBLOCK, mode, name->allow_override);
        if (fd == -1) {
                return pvfs_map_errno(pvfs, errno);
        }
@@ -856,7 +856,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
 
 cleanup_delete:
        close(fd);
-       pvfs_sys_unlink(pvfs, name->full_name);
+       pvfs_sys_unlink(pvfs, name->full_name, name->allow_override);
        return status;
 }
 
@@ -1549,7 +1549,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
        }
 
        /* do the actual open */
-       fd = pvfs_sys_open(pvfs, f->handle->name->full_name, flags | O_NONBLOCK, 0);
+       fd = pvfs_sys_open(pvfs, f->handle->name->full_name, flags | O_NONBLOCK, 0, name->allow_override);
        if (fd == -1) {
                status = pvfs_map_errno(f->pvfs, errno);
 
@@ -1635,7 +1635,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
                mode_t mode = pvfs_fileperms(pvfs, attrib);
                if (f->handle->name->st.st_mode != mode &&
                    f->handle->name->dos.attrib != attrib &&
-                   pvfs_sys_fchmod(pvfs, fd, mode) == -1) {
+                   pvfs_sys_fchmod(pvfs, fd, mode, name->allow_override) == -1) {
                        talloc_free(lck);
                        return pvfs_map_errno(pvfs, errno);
                }
index 5296811f022934583af7a2f0feed4a3a8a73e06c..432716130c6c3ab4101097ca5de22512782dbe91 100644 (file)
@@ -37,7 +37,8 @@ NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs,
        uint32_t mask;
        NTSTATUS status;
 
-       if (pvfs_sys_rename(pvfs, name1->full_name, name2) == -1) {
+       if (pvfs_sys_rename(pvfs, name1->full_name, name2,
+                           name1->allow_override) == -1) {
                return pvfs_map_errno(pvfs, errno);
        }
 
@@ -624,7 +625,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
        case RENAME_FLAG_COPY:
                status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE);
                NT_STATUS_NOT_OK_RETURN(status);
-               return pvfs_copy_file(pvfs, name1, name2);
+               return pvfs_copy_file(pvfs, name1, name2, name1->allow_override && name2->allow_override);
 
        case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
                DEBUG(3,(__location__ ": Invalid rename cluster for %s\n",
index 255728382ebbb7637763822c65bf2e2010ee4bc2..837ea174d6237f8f26aeb38f00dc72d289c3ced5 100644 (file)
@@ -518,6 +518,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs,
 
        (*name)->exists = false;
        (*name)->stream_exists = false;
+       (*name)->allow_override = false;
 
        if (!(pvfs->fs_attribs & FS_ATTR_NAMED_STREAMS)) {
                flags &= ~PVFS_RESOLVE_STREAMS;
@@ -630,6 +631,7 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
        (*name)->original_name = talloc_strdup(*name, fname);
        (*name)->stream_name = NULL;
        (*name)->stream_id = 0;
+       (*name)->allow_override = false;
 
        status = pvfs_fill_dos_info(pvfs, *name, flags, -1);
 
@@ -815,6 +817,7 @@ NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
        }
        (*name)->stream_name = NULL;
        (*name)->stream_id = 0;
+       (*name)->allow_override = false;
 
        status = pvfs_fill_dos_info(pvfs, *name, PVFS_RESOLVE_NO_OPENDB, -1);
 
index cbb5c7853cbcf4fe96aa481ae4bbaa632384e492..3c9b18d91ce5f7f8dc995afd9e9f2a400bd3b87f 100644 (file)
@@ -534,7 +534,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
                }
                mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
                if (!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
-                       if (pvfs_sys_fchmod(pvfs, h->fd, mode) == -1) {
+                       if (pvfs_sys_fchmod(pvfs, h->fd, mode, h->name->allow_override) == -1) {
                                return pvfs_map_errno(pvfs, errno);
                        }
                }
@@ -859,7 +859,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
        newstats.dos.attrib |= (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY);
        if (newstats.dos.attrib != name->dos.attrib) {
                mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib);
-               if (pvfs_sys_chmod(pvfs, name->full_name, mode) == -1) {
+               if (pvfs_sys_chmod(pvfs, name->full_name, mode, name->allow_override) == -1) {
                        return pvfs_map_errno(pvfs, errno);
                }
                change_mask |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
index f110590153953dcb6a5643e6fcdf0c4fa16470b5..9112848bfef32380091ab3dbef88e542da6f7846 100644 (file)
@@ -256,7 +256,7 @@ static int pvfs_sys_chown(struct pvfs_state *pvfs, struct pvfs_sys_ctx *ctx, con
 /*
   wrap open for system override
 */
-int pvfs_sys_open(struct pvfs_state *pvfs, const char *filename, int flags, mode_t mode)
+int pvfs_sys_open(struct pvfs_state *pvfs, const char *filename, int flags, mode_t mode, bool allow_override)
 {
        int fd, ret;
        struct pvfs_sys_ctx *ctx;
@@ -267,7 +267,7 @@ int pvfs_sys_open(struct pvfs_state *pvfs, const char *filename, int flags, mode
 
        fd = open(filename, flags, mode);
        if (fd != -1 ||
-           !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+           !allow_override ||
            errno != EACCES) {
                return fd;
        }
@@ -366,7 +366,7 @@ int pvfs_sys_open(struct pvfs_state *pvfs, const char *filename, int flags, mode
 /*
   wrap unlink for system override
 */
-int pvfs_sys_unlink(struct pvfs_state *pvfs, const char *filename)
+int pvfs_sys_unlink(struct pvfs_state *pvfs, const char *filename, bool allow_override)
 {
        int ret;
        struct pvfs_sys_ctx *ctx;
@@ -376,7 +376,7 @@ int pvfs_sys_unlink(struct pvfs_state *pvfs, const char *filename)
 
        ret = unlink(filename);
        if (ret != -1 ||
-           !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+           !allow_override ||
            errno != EACCES) {
                return ret;
        }
@@ -415,7 +415,7 @@ static bool contains_symlink(const char *path)
 /*
   wrap rename for system override
 */
-int pvfs_sys_rename(struct pvfs_state *pvfs, const char *name1, const char *name2)
+int pvfs_sys_rename(struct pvfs_state *pvfs, const char *name1, const char *name2, bool allow_override)
 {
        int ret;
        struct pvfs_sys_ctx *ctx;
@@ -425,7 +425,7 @@ int pvfs_sys_rename(struct pvfs_state *pvfs, const char *name1, const char *name
 
        ret = rename(name1, name2);
        if (ret != -1 ||
-           !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+           !allow_override ||
            errno != EACCES) {
                return ret;
        }
@@ -480,7 +480,7 @@ int pvfs_sys_rename(struct pvfs_state *pvfs, const char *name1, const char *name
 /*
   wrap mkdir for system override
 */
-int pvfs_sys_mkdir(struct pvfs_state *pvfs, const char *dirname, mode_t mode)
+int pvfs_sys_mkdir(struct pvfs_state *pvfs, const char *dirname, mode_t mode, bool allow_override)
 {
        int ret;
        struct pvfs_sys_ctx *ctx;
@@ -490,7 +490,7 @@ int pvfs_sys_mkdir(struct pvfs_state *pvfs, const char *dirname, mode_t mode)
 
        ret = mkdir(dirname, mode);
        if (ret != -1 ||
-           !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+           !allow_override ||
            errno != EACCES) {
                return ret;
        }
@@ -525,7 +525,7 @@ int pvfs_sys_mkdir(struct pvfs_state *pvfs, const char *dirname, mode_t mode)
 /*
   wrap rmdir for system override
 */
-int pvfs_sys_rmdir(struct pvfs_state *pvfs, const char *dirname)
+int pvfs_sys_rmdir(struct pvfs_state *pvfs, const char *dirname, bool allow_override)
 {
        int ret;
        struct pvfs_sys_ctx *ctx;
@@ -535,7 +535,7 @@ int pvfs_sys_rmdir(struct pvfs_state *pvfs, const char *dirname)
 
        ret = rmdir(dirname);
        if (ret != -1 ||
-           !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+           !allow_override ||
            errno != EACCES) {
                return ret;
        }
@@ -563,7 +563,7 @@ int pvfs_sys_rmdir(struct pvfs_state *pvfs, const char *dirname)
 /*
   wrap fchmod for system override
 */
-int pvfs_sys_fchmod(struct pvfs_state *pvfs, int fd, mode_t mode)
+int pvfs_sys_fchmod(struct pvfs_state *pvfs, int fd, mode_t mode, bool allow_override)
 {
        int ret;
        struct pvfs_sys_ctx *ctx;
@@ -573,7 +573,7 @@ int pvfs_sys_fchmod(struct pvfs_state *pvfs, int fd, mode_t mode)
 
        ret = fchmod(fd, mode);
        if (ret != -1 ||
-           !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+           !allow_override ||
            errno != EACCES) {
                return ret;
        }
@@ -602,7 +602,7 @@ int pvfs_sys_fchmod(struct pvfs_state *pvfs, int fd, mode_t mode)
 /*
   wrap chmod for system override
 */
-int pvfs_sys_chmod(struct pvfs_state *pvfs, const char *filename, mode_t mode)
+int pvfs_sys_chmod(struct pvfs_state *pvfs, const char *filename, mode_t mode, bool allow_override)
 {
        int ret;
        struct pvfs_sys_ctx *ctx;
@@ -612,7 +612,7 @@ int pvfs_sys_chmod(struct pvfs_state *pvfs, const char *filename, mode_t mode)
 
        ret = chmod(filename, mode);
        if (ret != -1 ||
-           !(pvfs->flags & PVFS_FLAG_PERM_OVERRIDE) ||
+           !allow_override ||
            errno != EACCES) {
                return ret;
        }
index be2ba531488c8eaccc7251941dbcefbc3a9a263b..a4b51d1d7d3e446ce593e0cb4d249fa1f5a14507 100644 (file)
@@ -123,7 +123,7 @@ static NTSTATUS pvfs_unlink_file(struct pvfs_state *pvfs,
        }
 
        /* finally try the actual unlink */
-       if (pvfs_sys_unlink(pvfs, name->full_name) == -1) {
+       if (pvfs_sys_unlink(pvfs, name->full_name, name->allow_override) == -1) {
                status = pvfs_map_errno(pvfs, errno);
        }
 
index c6c6eaa13c8590c4fec0a31e9720509bb80f1409..6afb928d73c5a125477ef367d25c308d860b4647 100644 (file)
@@ -90,7 +90,8 @@ uint32_t pvfs_attrib_normalise(uint32_t attrib, mode_t mode)
 */
 NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs,
                        struct pvfs_filename *name1, 
-                       struct pvfs_filename *name2)
+                       struct pvfs_filename *name2,
+                       bool allow_override)
 {
        int fd1, fd2;
        mode_t mode;
@@ -102,13 +103,13 @@ NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs,
                return NT_STATUS_NO_MEMORY;
        }
 
-       fd1 = pvfs_sys_open(pvfs, name1->full_name, O_RDONLY, 0);
+       fd1 = pvfs_sys_open(pvfs, name1->full_name, O_RDONLY, 0, allow_override);
        if (fd1 == -1) {
                talloc_free(buf);
                return pvfs_map_errno(pvfs, errno);
        }
 
-       fd2 = pvfs_sys_open(pvfs, name2->full_name, O_CREAT|O_EXCL|O_WRONLY, 0);
+       fd2 = pvfs_sys_open(pvfs, name2->full_name, O_CREAT|O_EXCL|O_WRONLY, 0, allow_override);
        if (fd2 == -1) {
                close(fd1);
                talloc_free(buf);
@@ -133,7 +134,7 @@ NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs,
                        close(fd1);
                        close(fd2);
                        talloc_free(buf);
-                       pvfs_sys_unlink(pvfs, name2->full_name);
+                       pvfs_sys_unlink(pvfs, name2->full_name, allow_override);
                        if (ret2 == -1) {
                                return pvfs_map_errno(pvfs, errno);
                        }
@@ -145,10 +146,10 @@ NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs,
        close(fd1);
 
        mode = pvfs_fileperms(pvfs, name1->dos.attrib);
-       if (pvfs_sys_fchmod(pvfs, fd2, mode) == -1) {
+       if (pvfs_sys_fchmod(pvfs, fd2, mode, allow_override) == -1) {
                status = pvfs_map_errno(pvfs, errno);
                close(fd2);
-               pvfs_sys_unlink(pvfs, name2->full_name);
+               pvfs_sys_unlink(pvfs, name2->full_name, allow_override);
                return status;
        }
 
@@ -158,7 +159,7 @@ NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs,
        status = pvfs_dosattrib_save(pvfs, name2, fd2);
        if (!NT_STATUS_IS_OK(status)) {
                close(fd2);
-               pvfs_sys_unlink(pvfs, name2->full_name);
+               pvfs_sys_unlink(pvfs, name2->full_name, allow_override);
                return status;
        }
 
index e1593a38cf578c583960510c506226e360966bb1..9a03658040fbf6336654fae1c42d2634fe5fd86c 100644 (file)
@@ -131,6 +131,7 @@ struct pvfs_filename {
        bool has_wildcard;
        bool exists;          /* true if the base filename exists */
        bool stream_exists;   /* true if the stream exists */
+       bool allow_override;
        struct stat st;
        struct pvfs_dos_fileinfo dos;
 };