* Common filesystem object access control check routine. Accepts a * vnode's type, "mode", uid and gid, requested access mode, and credentials. * Returns 0 on success, or an errno on failure. */
| 5231 | * Returns 0 on success, or an errno on failure. |
| 5232 | */ |
| 5233 | int |
| 5234 | vaccess(enum vtype type, mode_t file_mode, uid_t file_uid, gid_t file_gid, |
| 5235 | accmode_t accmode, struct ucred *cred) |
| 5236 | { |
| 5237 | accmode_t dac_granted; |
| 5238 | accmode_t priv_granted; |
| 5239 | |
| 5240 | KASSERT((accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | VAPPEND)) == 0, |
| 5241 | ("invalid bit in accmode")); |
| 5242 | KASSERT((accmode & VAPPEND) == 0 || (accmode & VWRITE), |
| 5243 | ("VAPPEND without VWRITE")); |
| 5244 | |
| 5245 | /* |
| 5246 | * Look for a normal, non-privileged way to access the file/directory |
| 5247 | * as requested. If it exists, go with that. |
| 5248 | */ |
| 5249 | |
| 5250 | dac_granted = 0; |
| 5251 | |
| 5252 | /* Check the owner. */ |
| 5253 | if (cred->cr_uid == file_uid) { |
| 5254 | dac_granted |= VADMIN; |
| 5255 | if (file_mode & S_IXUSR) |
| 5256 | dac_granted |= VEXEC; |
| 5257 | if (file_mode & S_IRUSR) |
| 5258 | dac_granted |= VREAD; |
| 5259 | if (file_mode & S_IWUSR) |
| 5260 | dac_granted |= (VWRITE | VAPPEND); |
| 5261 | |
| 5262 | if ((accmode & dac_granted) == accmode) |
| 5263 | return (0); |
| 5264 | |
| 5265 | goto privcheck; |
| 5266 | } |
| 5267 | |
| 5268 | /* Otherwise, check the groups (first match) */ |
| 5269 | if (groupmember(file_gid, cred)) { |
| 5270 | if (file_mode & S_IXGRP) |
| 5271 | dac_granted |= VEXEC; |
| 5272 | if (file_mode & S_IRGRP) |
| 5273 | dac_granted |= VREAD; |
| 5274 | if (file_mode & S_IWGRP) |
| 5275 | dac_granted |= (VWRITE | VAPPEND); |
| 5276 | |
| 5277 | if ((accmode & dac_granted) == accmode) |
| 5278 | return (0); |
| 5279 | |
| 5280 | goto privcheck; |
| 5281 | } |
| 5282 | |
| 5283 | /* Otherwise, check everyone else. */ |
| 5284 | if (file_mode & S_IXOTH) |
| 5285 | dac_granted |= VEXEC; |
| 5286 | if (file_mode & S_IROTH) |
| 5287 | dac_granted |= VREAD; |
| 5288 | if (file_mode & S_IWOTH) |
| 5289 | dac_granted |= (VWRITE | VAPPEND); |
| 5290 | if ((accmode & dac_granted) == accmode) |
no test coverage detected