From ad7da47948a5a3ed2c3fc18392b83c059bec5b6e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2005 02:14:34 +0000 Subject: r4584: fix pvfs backend to pass the new enhanced RAW-ACLS test. Easy once I really the strange behaviour I saw was a w2k3 bug :-) (This used to be commit e729061bcde25d0565a72222e4720ca8074ef23f) --- source4/ntvfs/posix/pvfs_acl.c | 34 ++++++++++++++++++++++++++++++++-- source4/ntvfs/posix/pvfs_mkdir.c | 4 ++-- source4/ntvfs/posix/pvfs_open.c | 15 ++++----------- source4/ntvfs/posix/pvfs_rename.c | 8 ++++---- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- 5 files changed, 43 insertions(+), 20 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 86a9a56ee9..5d8225f8ec 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -392,6 +392,8 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, /* expand the generic access bits to file specific bits */ *access_mask = pvfs_translate_mask(*access_mask); + *access_mask &= ~SEC_FILE_READ_ATTRIBUTE; + /* check the acl against the required access mask */ status = sec_access_check(sd, token, *access_mask, access_mask); @@ -424,7 +426,35 @@ NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, */ NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, struct smbsrv_request *req, - struct pvfs_filename *name) + struct pvfs_filename *name, + uint32_t *access_mask) +{ + struct pvfs_filename *parent; + NTSTATUS status; + + status = pvfs_resolve_parent(pvfs, req, name, &parent); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_access_check(pvfs, req, parent, access_mask); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (! ((*access_mask) & SEC_DIR_ADD_FILE)) { + return pvfs_access_check_simple(pvfs, req, name, SEC_DIR_ADD_FILE); + } + + return status; +} + +/* + access check for creating a new file/directory - no access mask supplied +*/ +NTSTATUS pvfs_access_check_create_nomask(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name) { struct pvfs_filename *parent; NTSTATUS status; @@ -434,7 +464,7 @@ NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, return status; } - return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE); + return pvfs_access_check_simple(pvfs, req, name, SEC_DIR_ADD_FILE); } diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index d2d431ae79..42b5109673 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -44,7 +44,7 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_access_check_create(pvfs, req, name); + status = pvfs_access_check_create_nomask(pvfs, req, name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -114,7 +114,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_access_check_create(pvfs, req, name); + status = pvfs_access_check_create_nomask(pvfs, req, name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index c59f2d22e9..b34d75d24d 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -199,7 +199,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* check the security descriptor */ status = pvfs_access_check(pvfs, req, name, &access_mask); } else { - status = pvfs_access_check_create(pvfs, req, name); + status = pvfs_access_check_create(pvfs, req, name, &access_mask); } if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->idtree_fnum, fnum); @@ -452,23 +452,16 @@ 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; } - if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { - access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE | - SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL; + status = pvfs_access_check_create(pvfs, req, name, &access_mask); + if (!NT_STATUS_IS_OK(status)) { + return status; } - access_mask |= SEC_FILE_READ_ATTRIBUTE; - if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { flags = O_RDWR; } else { diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 3203f7fa86..91ad9aa3d9 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -281,7 +281,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_access_check_create(pvfs, req, name2); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -360,7 +360,7 @@ 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); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -370,7 +370,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, break; case RENAME_FLAG_HARD_LINK: - status = pvfs_access_check_create(pvfs, req, name2); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -380,7 +380,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, break; case RENAME_FLAG_COPY: - status = pvfs_access_check_create(pvfs, req, name2); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 7144f37a14..8c4d016ccc 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -139,7 +139,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } } - status = pvfs_access_check_create(pvfs, req, name2); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit