summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_acl.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-12-31 08:56:32 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:07:51 -0500
commit291b02a639aa6551ac1f59e47a78d5590d2b7f6e (patch)
treedcba74eba6867928205402457385ed7d1c9f8f04 /source4/ntvfs/posix/pvfs_acl.c
parent90a322f6d7fc2d9a12daea8bd752d549eb874814 (diff)
downloadsamba-291b02a639aa6551ac1f59e47a78d5590d2b7f6e.tar.gz
samba-291b02a639aa6551ac1f59e47a78d5590d2b7f6e.tar.bz2
samba-291b02a639aa6551ac1f59e47a78d5590d2b7f6e.zip
r4448: - fixed access_mask checking on acl set
- honor the change ownership requests of acl set, changing the underlying unix owner/group - fix the access mask on file create with SEC_FLAG_MAXIMUM_ALLOWED (This used to be commit 5761fa35ab727b51ef1b52459911bafbdd788755)
Diffstat (limited to 'source4/ntvfs/posix/pvfs_acl.c')
-rw-r--r--source4/ntvfs/posix/pvfs_acl.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c
index 4cc22b0918..ce5f3a248b 100644
--- a/source4/ntvfs/posix/pvfs_acl.c
+++ b/source4/ntvfs/posix/pvfs_acl.c
@@ -185,12 +185,15 @@ static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_
NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
struct smbsrv_request *req,
struct pvfs_filename *name, int fd,
+ uint32_t access_mask,
union smb_setfileinfo *info)
{
struct xattr_NTACL *acl;
uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
struct security_descriptor *new_sd, *sd;
NTSTATUS status;
+ uid_t uid = -1;
+ gid_t gid = -1;
acl = talloc_p(req, struct xattr_NTACL);
if (acl == NULL) {
@@ -215,12 +218,28 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
new_sd = info->set_secdesc.in.sd;
+ uid = name->st.st_uid;
+ gid = name->st.st_gid;
+
/* only set the elements that have been specified */
- if (secinfo_flags & SECINFO_OWNER) {
+ if ((secinfo_flags & SECINFO_OWNER) &&
+ !dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) {
+ if (!(access_mask & SEC_STD_WRITE_OWNER)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
sd->owner_sid = new_sd->owner_sid;
+ status = sidmap_sid_to_unixuid(pvfs->sidmap, sd->owner_sid, &uid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
- if (secinfo_flags & SECINFO_GROUP) {
+ if ((secinfo_flags & SECINFO_GROUP) &&
+ !dom_sid_equal(sd->group_sid, new_sd->group_sid)) {
sd->group_sid = new_sd->group_sid;
+ status = sidmap_sid_to_unixgid(pvfs->sidmap, sd->owner_sid, &gid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
if (secinfo_flags & SECINFO_DACL) {
sd->dacl = new_sd->dacl;
@@ -228,9 +247,24 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs,
}
if (secinfo_flags & SECINFO_SACL) {
sd->sacl = new_sd->sacl;
+ if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
pvfs_translate_generic_bits(sd->sacl);
}
+ if (uid != -1 || gid != -1) {
+ int ret;
+ if (fd == -1) {
+ ret = chown(name->full_name, uid, gid);
+ } else {
+ ret = fchown(fd, uid, gid);
+ }
+ if (ret == -1) {
+ return pvfs_map_errno(pvfs, errno);
+ }
+ }
+
status = pvfs_acl_save(pvfs, name, fd, acl);
return status;