diff --git a/sys/kern/kern_acl.c b/sys/kern/kern_acl.c index d2c878a5b930..2ae39e06932d 100644 --- a/sys/kern/kern_acl.c +++ b/sys/kern/kern_acl.c @@ -51,8 +51,8 @@ static int vacl_set_acl(struct proc *p, struct vnode *vp, acl_type_t type, struct acl *aclp); static int vacl_get_acl(struct proc *p, struct vnode *vp, acl_type_t type, struct acl *aclp); -static int vacl_aclcheck(struct proc *p, struct vnode *vp, acl_type_t type, - struct acl *aclp); +static int vacl_aclcheck(struct proc *p, struct vnode *vp, + acl_type_t type, struct acl *aclp); /* * Implement a version of vaccess() that understands POSIX.1e ACL semantics. @@ -60,8 +60,8 @@ static int vacl_aclcheck(struct proc *p, struct vnode *vp, acl_type_t type, * vaccess() eventually. */ int -vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, - struct ucred *cred, int *privused) +vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid, + struct acl *acl, mode_t acc_mode, struct ucred *cred, int *privused) { struct acl_entry *acl_other, *acl_mask; mode_t dac_granted; @@ -123,7 +123,7 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { case ACL_USER_OBJ: - if (acl->acl_entry[i].ae_id != cred->cr_uid) + if (file_uid != cred->cr_uid) break; dac_granted = 0; dac_granted |= VADMIN; @@ -209,13 +209,13 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, dac_granted &= acl_mask_granted; if ((acc_mode & dac_granted) == acc_mode) return (0); - if ((acc_mode & (dac_granted | cap_granted)) == - acc_mode) { - if (privused != NULL) - *privused = 1; - return (0); - } - goto error; + if ((acc_mode & (dac_granted | cap_granted)) != + acc_mode) + goto error; + + if (privused != NULL) + *privused = 1; + return (0); } } @@ -229,22 +229,41 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { case ACL_GROUP_OBJ: + if (file_gid != cred->cr_groups[0]) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) + dac_granted |= VEXEC; + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; + + if ((acc_mode & dac_granted) == acc_mode) + return (0); + + group_matched = 1; + break; + case ACL_GROUP: - if (groupmember(acl->acl_entry[i].ae_id, cred)) { - dac_granted = 0; - if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) - dac_granted |= VEXEC; - if (acl->acl_entry[i].ae_perm & ACL_READ) - dac_granted |= VREAD; - if (acl->acl_entry[i].ae_perm & ACL_WRITE) - dac_granted |= VWRITE; - dac_granted &= acl_mask_granted; + if (!groupmember(acl->acl_entry[i].ae_id, cred)) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) + dac_granted |= VEXEC; + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; - if ((acc_mode & dac_granted) == acc_mode) - return (0); + if ((acc_mode & dac_granted) == acc_mode) + return (0); + + group_matched = 1; + break; - group_matched = 1; - } default: } } @@ -257,27 +276,46 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { case ACL_GROUP_OBJ: - case ACL_GROUP: - if (groupmember(acl->acl_entry[i].ae_id, - cred)) { - dac_granted = 0; - if (acl->acl_entry[i].ae_perm & - ACL_EXECUTE) + if (file_gid != cred->cr_groups[0]) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) dac_granted |= VEXEC; - if (acl->acl_entry[i].ae_perm & - ACL_READ) - dac_granted |= VREAD; - if (acl->acl_entry[i].ae_perm & - ACL_WRITE) - dac_granted |= VWRITE; - dac_granted &= acl_mask_granted; - if ((acc_mode & (dac_granted | - cap_granted)) == acc_mode) { - if (privused != NULL) - *privused = 1; - return (0); - } - } + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; + + if ((acc_mode & (dac_granted | cap_granted)) != + acc_mode) + break; + + if (privused != NULL) + *privused = 1; + return (0); + + case ACL_GROUP: + if (!groupmember(acl->acl_entry[i].ae_id, + cred)) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) + dac_granted |= VEXEC; + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; + + if ((acc_mode & (dac_granted | cap_granted)) != + acc_mode) + break; + + if (privused != NULL) + *privused = 1; + return (0); + default: } } @@ -454,21 +492,37 @@ acl_posix1e_check(struct acl *acl) */ switch(acl->acl_entry[i].ae_tag) { case ACL_USER_OBJ: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_user_obj++; break; case ACL_GROUP_OBJ: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_group_obj++; break; case ACL_USER: + if (acl->acl_entry[i].ae_id == ACL_UNDEFINED_ID) + return (EINVAL); num_acl_user++; break; case ACL_GROUP: + if (acl->acl_entry[i].ae_id == ACL_UNDEFINED_ID) + return (EINVAL); num_acl_group++; break; case ACL_OTHER: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_other++; break; case ACL_MASK: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_mask++; break; default: diff --git a/sys/kern/subr_acl_posix1e.c b/sys/kern/subr_acl_posix1e.c index d2c878a5b930..2ae39e06932d 100644 --- a/sys/kern/subr_acl_posix1e.c +++ b/sys/kern/subr_acl_posix1e.c @@ -51,8 +51,8 @@ static int vacl_set_acl(struct proc *p, struct vnode *vp, acl_type_t type, struct acl *aclp); static int vacl_get_acl(struct proc *p, struct vnode *vp, acl_type_t type, struct acl *aclp); -static int vacl_aclcheck(struct proc *p, struct vnode *vp, acl_type_t type, - struct acl *aclp); +static int vacl_aclcheck(struct proc *p, struct vnode *vp, + acl_type_t type, struct acl *aclp); /* * Implement a version of vaccess() that understands POSIX.1e ACL semantics. @@ -60,8 +60,8 @@ static int vacl_aclcheck(struct proc *p, struct vnode *vp, acl_type_t type, * vaccess() eventually. */ int -vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, - struct ucred *cred, int *privused) +vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid, + struct acl *acl, mode_t acc_mode, struct ucred *cred, int *privused) { struct acl_entry *acl_other, *acl_mask; mode_t dac_granted; @@ -123,7 +123,7 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { case ACL_USER_OBJ: - if (acl->acl_entry[i].ae_id != cred->cr_uid) + if (file_uid != cred->cr_uid) break; dac_granted = 0; dac_granted |= VADMIN; @@ -209,13 +209,13 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, dac_granted &= acl_mask_granted; if ((acc_mode & dac_granted) == acc_mode) return (0); - if ((acc_mode & (dac_granted | cap_granted)) == - acc_mode) { - if (privused != NULL) - *privused = 1; - return (0); - } - goto error; + if ((acc_mode & (dac_granted | cap_granted)) != + acc_mode) + goto error; + + if (privused != NULL) + *privused = 1; + return (0); } } @@ -229,22 +229,41 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { case ACL_GROUP_OBJ: + if (file_gid != cred->cr_groups[0]) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) + dac_granted |= VEXEC; + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; + + if ((acc_mode & dac_granted) == acc_mode) + return (0); + + group_matched = 1; + break; + case ACL_GROUP: - if (groupmember(acl->acl_entry[i].ae_id, cred)) { - dac_granted = 0; - if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) - dac_granted |= VEXEC; - if (acl->acl_entry[i].ae_perm & ACL_READ) - dac_granted |= VREAD; - if (acl->acl_entry[i].ae_perm & ACL_WRITE) - dac_granted |= VWRITE; - dac_granted &= acl_mask_granted; + if (!groupmember(acl->acl_entry[i].ae_id, cred)) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) + dac_granted |= VEXEC; + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; - if ((acc_mode & dac_granted) == acc_mode) - return (0); + if ((acc_mode & dac_granted) == acc_mode) + return (0); + + group_matched = 1; + break; - group_matched = 1; - } default: } } @@ -257,27 +276,46 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { case ACL_GROUP_OBJ: - case ACL_GROUP: - if (groupmember(acl->acl_entry[i].ae_id, - cred)) { - dac_granted = 0; - if (acl->acl_entry[i].ae_perm & - ACL_EXECUTE) + if (file_gid != cred->cr_groups[0]) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) dac_granted |= VEXEC; - if (acl->acl_entry[i].ae_perm & - ACL_READ) - dac_granted |= VREAD; - if (acl->acl_entry[i].ae_perm & - ACL_WRITE) - dac_granted |= VWRITE; - dac_granted &= acl_mask_granted; - if ((acc_mode & (dac_granted | - cap_granted)) == acc_mode) { - if (privused != NULL) - *privused = 1; - return (0); - } - } + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; + + if ((acc_mode & (dac_granted | cap_granted)) != + acc_mode) + break; + + if (privused != NULL) + *privused = 1; + return (0); + + case ACL_GROUP: + if (!groupmember(acl->acl_entry[i].ae_id, + cred)) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) + dac_granted |= VEXEC; + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; + + if ((acc_mode & (dac_granted | cap_granted)) != + acc_mode) + break; + + if (privused != NULL) + *privused = 1; + return (0); + default: } } @@ -454,21 +492,37 @@ acl_posix1e_check(struct acl *acl) */ switch(acl->acl_entry[i].ae_tag) { case ACL_USER_OBJ: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_user_obj++; break; case ACL_GROUP_OBJ: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_group_obj++; break; case ACL_USER: + if (acl->acl_entry[i].ae_id == ACL_UNDEFINED_ID) + return (EINVAL); num_acl_user++; break; case ACL_GROUP: + if (acl->acl_entry[i].ae_id == ACL_UNDEFINED_ID) + return (EINVAL); num_acl_group++; break; case ACL_OTHER: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_other++; break; case ACL_MASK: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_mask++; break; default: diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c index d2c878a5b930..2ae39e06932d 100644 --- a/sys/kern/vfs_acl.c +++ b/sys/kern/vfs_acl.c @@ -51,8 +51,8 @@ static int vacl_set_acl(struct proc *p, struct vnode *vp, acl_type_t type, struct acl *aclp); static int vacl_get_acl(struct proc *p, struct vnode *vp, acl_type_t type, struct acl *aclp); -static int vacl_aclcheck(struct proc *p, struct vnode *vp, acl_type_t type, - struct acl *aclp); +static int vacl_aclcheck(struct proc *p, struct vnode *vp, + acl_type_t type, struct acl *aclp); /* * Implement a version of vaccess() that understands POSIX.1e ACL semantics. @@ -60,8 +60,8 @@ static int vacl_aclcheck(struct proc *p, struct vnode *vp, acl_type_t type, * vaccess() eventually. */ int -vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, - struct ucred *cred, int *privused) +vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid, + struct acl *acl, mode_t acc_mode, struct ucred *cred, int *privused) { struct acl_entry *acl_other, *acl_mask; mode_t dac_granted; @@ -123,7 +123,7 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { case ACL_USER_OBJ: - if (acl->acl_entry[i].ae_id != cred->cr_uid) + if (file_uid != cred->cr_uid) break; dac_granted = 0; dac_granted |= VADMIN; @@ -209,13 +209,13 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, dac_granted &= acl_mask_granted; if ((acc_mode & dac_granted) == acc_mode) return (0); - if ((acc_mode & (dac_granted | cap_granted)) == - acc_mode) { - if (privused != NULL) - *privused = 1; - return (0); - } - goto error; + if ((acc_mode & (dac_granted | cap_granted)) != + acc_mode) + goto error; + + if (privused != NULL) + *privused = 1; + return (0); } } @@ -229,22 +229,41 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { case ACL_GROUP_OBJ: + if (file_gid != cred->cr_groups[0]) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) + dac_granted |= VEXEC; + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; + + if ((acc_mode & dac_granted) == acc_mode) + return (0); + + group_matched = 1; + break; + case ACL_GROUP: - if (groupmember(acl->acl_entry[i].ae_id, cred)) { - dac_granted = 0; - if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) - dac_granted |= VEXEC; - if (acl->acl_entry[i].ae_perm & ACL_READ) - dac_granted |= VREAD; - if (acl->acl_entry[i].ae_perm & ACL_WRITE) - dac_granted |= VWRITE; - dac_granted &= acl_mask_granted; + if (!groupmember(acl->acl_entry[i].ae_id, cred)) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) + dac_granted |= VEXEC; + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; - if ((acc_mode & dac_granted) == acc_mode) - return (0); + if ((acc_mode & dac_granted) == acc_mode) + return (0); + + group_matched = 1; + break; - group_matched = 1; - } default: } } @@ -257,27 +276,46 @@ vaccess_acl_posix1e(enum vtype type, struct acl *acl, mode_t acc_mode, for (i = 0; i < acl->acl_cnt; i++) { switch (acl->acl_entry[i].ae_tag) { case ACL_GROUP_OBJ: - case ACL_GROUP: - if (groupmember(acl->acl_entry[i].ae_id, - cred)) { - dac_granted = 0; - if (acl->acl_entry[i].ae_perm & - ACL_EXECUTE) + if (file_gid != cred->cr_groups[0]) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) dac_granted |= VEXEC; - if (acl->acl_entry[i].ae_perm & - ACL_READ) - dac_granted |= VREAD; - if (acl->acl_entry[i].ae_perm & - ACL_WRITE) - dac_granted |= VWRITE; - dac_granted &= acl_mask_granted; - if ((acc_mode & (dac_granted | - cap_granted)) == acc_mode) { - if (privused != NULL) - *privused = 1; - return (0); - } - } + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; + + if ((acc_mode & (dac_granted | cap_granted)) != + acc_mode) + break; + + if (privused != NULL) + *privused = 1; + return (0); + + case ACL_GROUP: + if (!groupmember(acl->acl_entry[i].ae_id, + cred)) + break; + dac_granted = 0; + if (acl->acl_entry[i].ae_perm & ACL_EXECUTE) + dac_granted |= VEXEC; + if (acl->acl_entry[i].ae_perm & ACL_READ) + dac_granted |= VREAD; + if (acl->acl_entry[i].ae_perm & ACL_WRITE) + dac_granted |= VWRITE; + dac_granted &= acl_mask_granted; + + if ((acc_mode & (dac_granted | cap_granted)) != + acc_mode) + break; + + if (privused != NULL) + *privused = 1; + return (0); + default: } } @@ -454,21 +492,37 @@ acl_posix1e_check(struct acl *acl) */ switch(acl->acl_entry[i].ae_tag) { case ACL_USER_OBJ: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_user_obj++; break; case ACL_GROUP_OBJ: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_group_obj++; break; case ACL_USER: + if (acl->acl_entry[i].ae_id == ACL_UNDEFINED_ID) + return (EINVAL); num_acl_user++; break; case ACL_GROUP: + if (acl->acl_entry[i].ae_id == ACL_UNDEFINED_ID) + return (EINVAL); num_acl_group++; break; case ACL_OTHER: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_other++; break; case ACL_MASK: + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; /* XXX */ + if (acl->acl_entry[i].ae_id != ACL_UNDEFINED_ID) + return (EINVAL); num_acl_mask++; break; default: diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index f8193485bc67..4f1ca3f4d872 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -563,8 +563,9 @@ int speedup_syncer __P((void)); int textvp_fullpath __P((struct proc *p, char **retbuf, char **retfreebuf)); int vaccess __P((enum vtype type, mode_t file_mode, uid_t uid, gid_t gid, mode_t acc_mode, struct ucred *cred, int *privused)); -int vaccess_acl_posix1e __P((enum vtype type, struct acl *acl, - mode_t acc_mode, struct ucred *cred, int *privused)); +int vaccess_acl_posix1e __P((enum vtype type, uid_t file_uid, + gid_t file_gid, struct acl *acl, mode_t acc_mode, + struct ucred *cred, int *privused)); void vattr_null __P((struct vattr *vap)); int vcount __P((struct vnode *vp)); void vdrop __P((struct vnode *)); diff --git a/sys/ufs/ufs/ufs_acl.c b/sys/ufs/ufs/ufs_acl.c index 042136c4affd..c78b0a473eea 100644 --- a/sys/ufs/ufs/ufs_acl.c +++ b/sys/ufs/ufs/ufs_acl.c @@ -79,23 +79,23 @@ ufs_sync_acl_from_inode(struct inode *ip, struct acl *acl) case ACL_USER_OBJ: acl->acl_entry[i].ae_perm = acl_posix1e_mode_to_perm( ACL_USER_OBJ, ip->i_mode); - acl->acl_entry[i].ae_id = ip->i_uid; + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; break; case ACL_GROUP_OBJ: acl_group_obj = &acl->acl_entry[i]; - acl->acl_entry[i].ae_id = ip->i_gid; + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; break; case ACL_OTHER: acl->acl_entry[i].ae_perm = acl_posix1e_mode_to_perm( ACL_OTHER, ip->i_mode); - acl->acl_entry[i].ae_id = 0; + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; break; case ACL_MASK: acl_mask = &acl->acl_entry[i]; - acl->acl_entry[i].ae_id = 0; + acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID; break; case ACL_USER: @@ -159,12 +159,10 @@ ufs_sync_inode_from_acl(struct acl *acl, struct inode *ip, switch (acl->acl_entry[i].ae_tag) { case ACL_USER_OBJ: acl_user_obj = &acl->acl_entry[i]; - ip->i_uid = acl->acl_entry[i].ae_id; break; case ACL_GROUP_OBJ: acl_group_obj = &acl->acl_entry[i]; - ip->i_gid = acl->acl_entry[i].ae_id; break; case ACL_OTHER: @@ -191,14 +189,14 @@ ufs_sync_inode_from_acl(struct acl *acl, struct inode *ip, /* * There is no ACL_MASK, so use the ACL_GROUP_OBJ entry. */ - ip->i_mode &= ~ALLPERMS; + ip->i_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); ip->i_mode |= acl_posix1e_perms_to_mode(acl_user_obj, acl_group_obj, acl_other); } else { /* * Use the ACL_MASK entry. */ - ip->i_mode &= ~ALLPERMS; + ip->i_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); ip->i_mode |= acl_posix1e_perms_to_mode(acl_user_obj, acl_mask, acl_other); } @@ -257,13 +255,13 @@ ufs_getacl(ap) */ ap->a_aclp->acl_cnt = 3; ap->a_aclp->acl_entry[0].ae_tag = ACL_USER_OBJ; - ap->a_aclp->acl_entry[0].ae_id = 0; + ap->a_aclp->acl_entry[0].ae_id = ACL_UNDEFINED_ID; ap->a_aclp->acl_entry[0].ae_perm = 0; ap->a_aclp->acl_entry[1].ae_tag = ACL_GROUP_OBJ; - ap->a_aclp->acl_entry[1].ae_id = 0; + ap->a_aclp->acl_entry[1].ae_id = ACL_UNDEFINED_ID; ap->a_aclp->acl_entry[1].ae_perm = 0; ap->a_aclp->acl_entry[2].ae_tag = ACL_OTHER; - ap->a_aclp->acl_entry[2].ae_id = 0; + ap->a_aclp->acl_entry[2].ae_id = ACL_UNDEFINED_ID; ap->a_aclp->acl_entry[2].ae_perm = 0; ufs_sync_acl_from_inode(ip, ap->a_aclp); error = 0; @@ -359,11 +357,8 @@ ufs_setacl(ap) } */ *ap; { struct inode *ip = VTOI(ap->a_vp); - struct acl_entry *acl_user_obj, *acl_group_obj, *acl_other; mode_t old_mode, preserve_mask; - uid_t old_uid, new_uid = 0; - gid_t old_gid, new_gid = 0; - int error, i; + int error; /* * If this is a set operation rather than a delete operation, @@ -405,64 +400,6 @@ ufs_setacl(ap) if ((error = VOP_ACCESS(ap->a_vp, VADMIN, ap->a_cred, ap->a_p))) return (error); - /* - * ACL_TYPE_ACCESS may involve the changing of ownership, sticky - * bit, setugid bits on the file or directory. As such, it requires - * special handling to identify these changes, and to authorize - * them. - * ACL_TYPE_DEFAULT does not require this, and ap->a_aclp should - * not be dereferenced without a NULL check, as it may be a delete - * operation. - */ - switch(ap->a_type) { - case ACL_TYPE_ACCESS: - /* - * Identify ACL_USER_OBJ, ACL_GROUP_OBJ, and determine if - * they have changed. If so, authorize in the style of - * ufs_chown(). While we're at it, identify ACL_OTHER. - */ - acl_user_obj = acl_group_obj = acl_other = NULL; - for (i = 0; i < ap->a_aclp->acl_cnt; i++) - switch(ap->a_aclp->acl_entry[i].ae_tag) { - case ACL_USER_OBJ: - acl_user_obj = &ap->a_aclp->acl_entry[i]; - new_uid = acl_user_obj->ae_id; - break; - case ACL_GROUP_OBJ: - acl_group_obj = &ap->a_aclp->acl_entry[i]; - new_gid = acl_group_obj->ae_id; - break; - case ACL_OTHER: - acl_other = &ap->a_aclp->acl_entry[i]; - break; - default: - } - old_uid = ip->i_uid; - old_gid = ip->i_gid; - - /* - * Authorize changes to base object ownership in the style - * of ufs_chown(). - */ - if (new_uid != old_uid && (error = suser_xxx(ap->a_cred, - ap->a_p, PRISON_ROOT))) - return (error); - if (new_gid != old_gid && !groupmember(new_gid, ap->a_cred) && - (error = suser_xxx(ap->a_cred, ap->a_p, PRISON_ROOT))) - return (error); - - case ACL_TYPE_DEFAULT: - /* - * ACL_TYPE_DEFAULT can literally be written straight into - * the EA unhindered, as it has gone through sanity checking - * already. - */ - break; - - default: - panic("ufs_setacl(): unknown acl type\n"); - } - switch(ap->a_type) { case ACL_TYPE_ACCESS: error = vn_extattr_set(ap->a_vp, IO_NODELOCKED, @@ -509,22 +446,9 @@ ufs_setacl(ap) * Now that the EA is successfully updated, update the * inode and mark it as changed. */ - old_uid = ip->i_uid; - old_gid = ip->i_gid; old_mode = ip->i_mode; preserve_mask = ISVTX | ISGID | ISUID; ufs_sync_inode_from_acl(ap->a_aclp, ip, preserve_mask); - - /* - * Clear the ISGID and ISUID bits if the ownership has - * changed, or appropriate privilege is not available. - * XXX: This should probably be a check for broadening - * availability of the bits, but it's not clear from the - * spec. - */ - if (suser_xxx(ap->a_cred, NULL, PRISON_ROOT) && - (ip->i_gid != old_gid || ip->i_uid != old_uid)) - ip->i_mode &= ~(ISUID | ISGID); ip->i_flag |= IN_CHANGE; } diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 9db19e292a18..0b65496d88aa 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -353,8 +353,8 @@ ufs_access(ap) ap->a_mode, ap->a_cred, NULL); break; case 0: - error = vaccess_acl_posix1e(vp->v_type, acl, ap->a_mode, - ap->a_cred, NULL); + error = vaccess_acl_posix1e(vp->v_type, ip->i_uid, ip->i_gid, + acl, ap->a_mode, ap->a_cred, NULL); break; default: printf("ufs_access(): Error retrieving ACL on object (%d).\n",