summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2001-04-17 04:33:34 +0000
committerRobert Watson <rwatson@FreeBSD.org>2001-04-17 04:33:34 +0000
commitb114e127e6741a237afd3e3e4546b94bae2c875c (patch)
treedde69e1a5b154f464e9be2a564d7884e43a9e05e /sys
parentabd9053ee4f1a9738e39de88f4b4455b5e6a6bb4 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_acl.c144
-rw-r--r--sys/kern/subr_acl_posix1e.c144
-rw-r--r--sys/kern/vfs_acl.c144
-rw-r--r--sys/sys/vnode.h5
-rw-r--r--sys/ufs/ufs/ufs_acl.c96
-rw-r--r--sys/ufs/ufs/ufs_vnops.c4
6 files changed, 312 insertions, 225 deletions
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",