vfs_export.c (4fe6d4372946b6abea6b5b87b92eff57f77b5db7) vfs_export.c (012c643d3e9b5ac9afb4ccc46b716e57775b6762)
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 2972 unchanged lines hidden (view full) ---

2981 if (!(flags & NDF_NO_STARTDIR_RELE) &&
2982 (ndp->ni_cnd.cn_flags & SAVESTART)) {
2983 vrele(ndp->ni_startdir);
2984 ndp->ni_startdir = NULL;
2985 }
2986}
2987
2988int
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 2972 unchanged lines hidden (view full) ---

2981 if (!(flags & NDF_NO_STARTDIR_RELE) &&
2982 (ndp->ni_cnd.cn_flags & SAVESTART)) {
2983 vrele(ndp->ni_startdir);
2984 ndp->ni_startdir = NULL;
2985 }
2986}
2987
2988int
2989vaccess(type, file_mode, uid, gid, acc_mode, cred)
2989vaccess(type, file_mode, file_uid, file_gid, acc_mode, cred, privused)
2990 enum vtype type;
2991 mode_t file_mode;
2990 enum vtype type;
2991 mode_t file_mode;
2992 uid_t uid;
2993 gid_t gid;
2992 uid_t file_uid;
2993 gid_t file_gid;
2994 mode_t acc_mode;
2995 struct ucred *cred;
2994 mode_t acc_mode;
2995 struct ucred *cred;
2996 int *privused;
2996{
2997{
2997 mode_t mask;
2998 mode_t dac_granted;
2999#ifdef CAPABILITIES
3000 mode_t cap_granted;
3001#endif
2998
2999 /*
3002
3003 /*
3000 * At this point, uid == 0 can do anything.
3001 * XXX: should use suser() ?
3002 * XXX: Should only check root-ness after other checks fail.
3004 * Look for a normal, non-privileged way to access the file/directory
3005 * as requested. If it exists, go with that.
3003 */
3006 */
3004 if (cred->cr_uid == 0)
3007
3008 if (privused != NULL)
3009 *privused = 0;
3010
3011 dac_granted = 0;
3012
3013 /* Check the owner. */
3014 if (cred->cr_uid == file_uid) {
3015 if (file_mode & S_IXUSR)
3016 dac_granted |= VEXEC;
3017 if (file_mode & S_IRUSR)
3018 dac_granted |= VREAD;
3019 if (file_mode & S_IWUSR)
3020 dac_granted |= VWRITE;
3021
3022 if ((acc_mode & dac_granted) == acc_mode)
3023 return (0);
3024
3025 goto privcheck;
3026 }
3027
3028 /* Otherwise, check the groups (first match) */
3029 if (groupmember(file_gid, cred)) {
3030 if (file_mode & S_IXGRP)
3031 dac_granted |= VEXEC;
3032 if (file_mode & S_IRGRP)
3033 dac_granted |= VREAD;
3034 if (file_mode & S_IWGRP)
3035 dac_granted |= VWRITE;
3036
3037 if ((acc_mode & dac_granted) == acc_mode)
3038 return (0);
3039
3040 goto privcheck;
3041 }
3042
3043 /* Otherwise, check everyone else. */
3044 if (file_mode & S_IXOTH)
3045 dac_granted |= VEXEC;
3046 if (file_mode & S_IROTH)
3047 dac_granted |= VREAD;
3048 if (file_mode & S_IWOTH)
3049 dac_granted |= VWRITE;
3050 if ((acc_mode & dac_granted) == acc_mode)
3005 return (0);
3006
3051 return (0);
3052
3007 mask = 0;
3053privcheck:
3054 if (!suser_xxx(cred, NULL, PRISON_ROOT)) {
3055 /* XXX audit: privilege used */
3056 if (privused != NULL)
3057 *privused = 1;
3058 return (0);
3059 }
3008
3060
3009 /* Otherwise, check the owner. */
3010 if (cred->cr_uid == uid) {
3011 if (acc_mode & VEXEC)
3012 mask |= S_IXUSR;
3013 if (acc_mode & VREAD)
3014 mask |= S_IRUSR;
3015 if (acc_mode & VWRITE)
3016 mask |= S_IWUSR;
3017 return ((file_mode & mask) == mask ? 0 : EACCES);
3018 }
3061#ifdef CAPABILITIES
3062 /*
3063 * Build a capability mask to determine if the set of capabilities
3064 * satisfies the requirements when combined with the granted mask
3065 * from above.
3066 * For each capability, if the capability is required, bitwise
3067 * or the request type onto the cap_granted mask.
3068 */
3069 cap_granted = 0;
3070 if ((acc_mode & VEXEC) && ((dac_granted & VEXEC) == 0) &&
3071 !cap_check_xxx(cred, p, CAP_DAC_EXECUTE, PRISON_ROOT))
3072 cap_granted |= VEXEC;
3019
3073
3020 /* Otherwise, check for all groups. */
3021 if (groupmember(gid, cred)) {
3022 if (acc_mode & VEXEC)
3023 mask |= S_IXGRP;
3024 if (acc_mode & VREAD)
3025 mask |= S_IRGRP;
3026 if (acc_mode & VWRITE)
3027 mask |= S_IWGRP;
3028 return ((file_mode & mask) == mask ? 0 : EACCES);
3074 if ((acc_mode & VREAD) && ((dac_granted & VREAD) == 0) &&
3075 !cap_check_xxx(cred, p, CAP_DAC_READ_SEARCH, PRISON_ROOT))
3076 cap_granted |= VREAD;
3077
3078 if ((acc_mode & VWRITE) && ((dac_granted & VWRITE) == 0) &&
3079 !cap_check_xxx(cred, p, CAP_DAC_WRITE, PRISON_ROOT))
3080 cap_granted |= VWRITE;
3081
3082 if ((acc_mode & (cap_granted | dac_granted)) == mode) {
3083 /* XXX audit: privilege used */
3084 if (privused != NULL)
3085 *privused = 1;
3086 return (0);
3029 }
3087 }
3088#endif
3030
3089
3031 /* Otherwise, check everyone else. */
3032 if (acc_mode & VEXEC)
3033 mask |= S_IXOTH;
3034 if (acc_mode & VREAD)
3035 mask |= S_IROTH;
3036 if (acc_mode & VWRITE)
3037 mask |= S_IWOTH;
3038 return ((file_mode & mask) == mask ? 0 : EACCES);
3090 return (EACCES);
3039}
3091}