- /*
- * Access check is based on only one of owner, group, public.
- * If not owner, then check group. If not a member of the
- * group, then check public access.
- */
- if (cred->cr_uid != ip->i_uid) {
- mode >>= 3;
- gp = cred->cr_groups;
- for (i = 0; i < cred->cr_ngroups; i++, gp++)
- if (ip->i_gid == *gp)
- goto found;
- mode >>= 3;
-found:
- ;
+
+ /* Otherwise, check the owner. */
+ if (cred->cr_uid == ip->i_uid)
+ switch (mode) {
+ case VEXEC:
+ return (ip->i_mode & S_IXUSR ? 0 : EACCES);
+ case VREAD:
+ return (ip->i_mode & S_IRUSR ? 0 : EACCES);
+ case VWRITE:
+ return (ip->i_mode & S_IWUSR ? 0 : EACCES);
+ }
+
+ /* Otherwise, check the groups. */
+ for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
+ if (ip->i_gid == *gp)
+ switch (mode) {
+ case VEXEC:
+ return (ip->i_mode & S_IXGRP ? 0 : EACCES);
+ case VREAD:
+ return (ip->i_mode & S_IRGRP ? 0 : EACCES);
+ case VWRITE:
+ return (ip->i_mode & S_IWGRP ? 0 : EACCES);
+ }
+
+ /* Otherwise, check everyone else. */
+ switch (mode) {
+ case VEXEC:
+ return (ip->i_mode & S_IXOTH ? 0 : EACCES);
+ case VREAD:
+ return (ip->i_mode & S_IROTH ? 0 : EACCES);
+ case VWRITE:
+ return (ip->i_mode & S_IWOTH ? 0 : EACCES);