From e881d19bded1191cf1157b212e1007ba80892e26 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Wed, 13 Nov 1996 00:20:59 +0000 Subject: Wed Nov 6 17:49:33 1996 Thomas Bushnell, n/BSG * fshelp.h (fshelp_fetch_root): Delete args `uids', `gids', `uids_len', and `gids_len'. New arg `user'. * fetch-root.c (fshelp_fetch_root): Ditto. * fshelp.h: Include . (fshelp_access, fshelp_isowner, fshelp_checkdirmod): New functions. --- libfshelp/ChangeLog | 10 ++++++ libfshelp/fetch-root.c | 8 ++--- libfshelp/fshelp.h | 82 ++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 87 insertions(+), 13 deletions(-) (limited to 'libfshelp') diff --git a/libfshelp/ChangeLog b/libfshelp/ChangeLog index 6903bca8..f653a3b8 100644 --- a/libfshelp/ChangeLog +++ b/libfshelp/ChangeLog @@ -1,3 +1,13 @@ +Wed Nov 6 17:49:33 1996 Thomas Bushnell, n/BSG + + * fshelp.h (fshelp_fetch_root): Delete args `uids', `gids', + `uids_len', and `gids_len'. New arg `user'. + * fetch-root.c (fshelp_fetch_root): Ditto. + + * fshelp.h: Include . + (fshelp_access, fshelp_isowner, fshelp_checkdirmod): New + functions. + Mon Oct 21 21:55:21 1996 Thomas Bushnell, n/BSG * fshelp.h: Add extern inline protection. diff --git a/libfshelp/fetch-root.c b/libfshelp/fetch-root.c index b38b276d..c0d30489 100644 --- a/libfshelp/fetch-root.c +++ b/libfshelp/fetch-root.c @@ -27,8 +27,7 @@ error_t fshelp_fetch_root (struct transbox *box, void *cookie, file_t dotdot, - uid_t *uids, int uids_len, - uid_t *gids, int gids_len, + struct iouser *user, int flags, fshelp_fetch_root_callback1_t callback1, fshelp_fetch_root_callback2_t callback2, @@ -170,8 +169,9 @@ fshelp_fetch_root (struct transbox *box, void *cookie, /* Cancellation point XXX */ err = fsys_getroot (control, dotdot, MACH_MSG_TYPE_COPY_SEND, - uids, uids_len, gids, gids_len, flags, - retry, retryname, root); + user->uids->ids, user->uids->len, + user->gids->ids, user->gids->len, + flags, retry, retryname, root); mutex_lock (box->lock); diff --git a/libfshelp/fshelp.h b/libfshelp/fshelp.h index dced0610..93ebd11f 100644 --- a/libfshelp/fshelp.h +++ b/libfshelp/fshelp.h @@ -27,6 +27,7 @@ #include #include #include +#include #ifndef FSHELP_EI #define FSHELP_EI extern inline @@ -117,18 +118,16 @@ typedef error_t (*fshelp_fetch_root_callback2_t) (void *cookie1, void *cookie2, *underlying_type); /* Fetch the root from TRANSBOX. DOTDOT is an unauthenticated port - for the directory in which we are looking; UIDS (length UIDS_LEN) - and GIDS (length GIDS_LEN) are the ids of the user responsible for - the call. FLAGS are as for dir_pathtrans (but O_CREAT and O_EXCL - are not meaningful and are ignored). The trasnbox lock (as - set by fshelp_transbox_init) must be held before the call, and will - be held upon return, but may be released during the operation of - the call. */ + for the directory in which we are looking; USER specifies the ids + of the user responsible for the call. FLAGS are as for + dir_pathtrans (but O_CREAT and O_EXCL are not meaningful and are + ignored). The trasnbox lock (as set by fshelp_transbox_init) must + be held before the call, and will be held upon return, but may be + released during the operation of the call. */ error_t fshelp_fetch_root (struct transbox *transbox, void *cookie, file_t dotdot, - uid_t *uids, int uids_len, - uid_t *gids, int gids_len, + struct iouser *user, int flags, fshelp_fetch_root_callback1_t callback1, fshelp_fetch_root_callback2_t callback2, @@ -240,4 +239,69 @@ error_t fshelp_return_malloced_buffer (char *buf, size_t len, char **rbuf, mach_msg_type_number_t *rlen); + + +/* Standardized filesystem permission checking */ + +/* Check to see whether USER should be considered the owner of the + file identified by ST. If so, return zero; otherwise return an + appropriate error code. */ +FSHELP_EI error_t +fshelp_isowner (struct stat *st, struct iouser *user) +{ + /* Permitted if the user has the owner UID, the superuser UID, or if + the user is in the group of the file and has the group ID as + their user ID. */ + if (idvec_contains (user->uids, st->st_uid) + || idvec_contains (user->uids, 0) + || (idvec_contains (user->gids, st->st_gid) + && idvec_contains (user->uids, st->st_gid))) + return 0; + else + return EPERM; +} + + +/* Check to see whether the user USER can operate on a file identified + by ST. OP is one of S_IREAD, S_IWRITE, and S_IEXEC. If the access + is permitted, return zero; otherwise return an appropriate error + code. */ +FSHELP_EI error_t +fshelp_access (struct stat *st, int op, struct iouser *user) +{ + if (idvec_contains (user->uids, 0)) + gotit = 1; + else if (user->uids->num == 0 && (st->st_mode & S_IUSEUNK)) + gotit = st->st_mode & (op << S_IUSEUNKSHIFT); + else if (!fshelp_isowner (st, user)) + gotit = st->st_mode & op; + else if (idvec_contains (user->gids, st->st_gid)) + gotit = st->st_mode & (op >> 3); + else + gotit = st->st_mode & (op >> 6); + return gotit ? 0 : EACCES; +} + +/* Check to see whether USER is allowed to modify DIR with respect to + existing file ST. (If there is no existing file, pass 0 for ST.) + If the access is permissable return 0; otherwise return an + appropriate error code. */ +FSHELP_EI error_t +fshelp_checkdirmod (struct stat *dir, struct stat *st, struct iouser *user) +{ + error_t err; + + /* The user must be able to write the directory. */ + err = fshelp_access (dir, S_IWRITE, user); + if (err) + return err; + + /* If the directory is sticky, the user must own either it or the file. */ + if ((dir->st_mode & S_ISVTX) && st + && fshelp_isowner (dir, user) && fshelp_isowner (st, user)) + return EACCES; + + return 0; +} + #endif -- cgit v1.2.3