diff options
-rw-r--r-- | libdiskfs/ChangeLog | 65 | ||||
-rw-r--r-- | libdiskfs/boot-start.c | 8 | ||||
-rw-r--r-- | libdiskfs/dir-lookup.c | 18 | ||||
-rw-r--r-- | libdiskfs/dir-mkfile.c | 6 | ||||
-rw-r--r-- | libdiskfs/diskfs.h | 102 | ||||
-rw-r--r-- | libdiskfs/file-access.c | 6 | ||||
-rw-r--r-- | libdiskfs/file-chauthor.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-chflags.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-chmod.c | 11 | ||||
-rw-r--r-- | libdiskfs/file-chown.c | 8 | ||||
-rw-r--r-- | libdiskfs/file-exec.c | 10 | ||||
-rw-r--r-- | libdiskfs/file-get-transcntl.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-getcontrol.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-inv-trans.c | 11 | ||||
-rw-r--r-- | libdiskfs/file-set-trans.c | 2 | ||||
-rw-r--r-- | libdiskfs/file-utimes.c | 2 | ||||
-rw-r--r-- | libdiskfs/fsys-getroot.c | 39 | ||||
-rw-r--r-- | libdiskfs/ifsock.c | 2 | ||||
-rw-r--r-- | libdiskfs/io-duplicate.c | 3 | ||||
-rw-r--r-- | libdiskfs/io-reauthenticate.c | 40 | ||||
-rw-r--r-- | libdiskfs/io-restrict-auth.c | 35 | ||||
-rw-r--r-- | libdiskfs/lithp.h | 3 | ||||
-rw-r--r-- | libdiskfs/lookup.c | 6 | ||||
-rw-r--r-- | libdiskfs/node-create.c | 6 | ||||
-rw-r--r-- | libdiskfs/protid-make.c | 44 | ||||
-rw-r--r-- | libdiskfs/protid-rele.c | 1 | ||||
-rw-r--r-- | libdiskfs/trans-callback.c | 13 |
27 files changed, 198 insertions, 251 deletions
diff --git a/libdiskfs/ChangeLog b/libdiskfs/ChangeLog index 099912b6..0baad3b0 100644 --- a/libdiskfs/ChangeLog +++ b/libdiskfs/ChangeLog @@ -3,6 +3,71 @@ Thu Nov 7 14:49:19 1996 Miles Bader <miles@gnu.ai.mit.edu> * io-restrict-auth.c (diskfs_S_io_restrict_auth): If CRED has root, use the requested id sets verbatim. +Thu Nov 7 01:03:11 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * protid-rele.c (diskfs_protid_rele): Free CRED->user. + +Wed Nov 6 17:55:17 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * diskfs.h (diskfs_isuid, diskfs_groupmember, diskfs_isowner, + diskfs_access, diskfs_checkdirmod): Delete functions. + * fsys-getroot.c (diskfs_S_fsys_getroot): Replace PSEUDOCRED with + a real iouser and specify that in the relevant calls. + * io-restrict-auth.c (diskfs_S_io_restrict_auth): Reworked to use + idvecs. + * file-chmod.c (diskfs_S_file_chmod): diskfs_isuid -> + idvec_contains. + * file-chown.c (diskfs_S_file_chown): Likewise. + * file-getcontrol.c (diskfs_S_file_getcontrol): Likewise. + * file-chmod.c (diskfs_S_file_chmod): diskfs_groupmember -> + idvec_contains. + * file-chown.c (diskfs_S_file_chown): Likewise. + * node-create.c (diskfs_create_node): Likewise. + * dir-lookup.c (diskfs_S_dir_lookup): diskfs_isowner -> + fshelp_isowner. + * file-chflags.c (diskfs_S_file_chflags): Likewise. + * file-chmod.c (diskfs_S_file_chmod): Likewise. + * file-chown.c (diskfs_S_file_chown): Likewise. + * file-get-transcntl.c (diskfs_S_file_get_translator_cntl): + Likewise. + * file-set-trans.c (diskfs_S_file_set_translator): Likewise. + * file-utimes.c (diskfs_S_file_utimes): Likewise. + * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise. + * lithp.h (dithkfth_ithowner): Deleted macro. + (fthhelp_ithowner, uther): New macros. + * file-chauthor.c (dithkfth_TH_file_chauthor): dthkfth_ithowner -> + fthhelp_ithowner. + * dir-lookup.c (diskfs_S_dir_lookup): diskfs_access -> + fshelp_access. + * dir-mkfile.c (diskfs_S_dir_mkfile): Likewise. + * file-access.c (diskfs_S_file_check_access): Likewise. + * file-exec.c (diskfs_S_file_exec): Likewise (in dead code). + * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise. + * ifsock.c (diskfs_S_ifsock_getsockaddr): Likewise. + * lookup.c (diskfs_lookup): Likewise. + (diskfs_lookup): diskfs_checkdirmod -> fshelp_checkdirmod. + * dir-lookup.c (diskfs_S_dir_lookup): New arg format for + fshelp_fetch_root. + * fsys-getroot.c (diskfs_S_fsys_getroot): Likewise. + * diskfs.h, protid-make.c (diskfs_create_protid): Delete args + `uids', `gids', `nuids', and `ngids'. Replace with new arg + `user'. All callers changed. + (diskfs_finish_protid): Likewise. + * file-inv-trans.c (diskfs_S_file_invoke_translator): Use + CRED->user instead of old fields. + * io-restrict-auth.c (diskfs_S_io_restrict_auth): Likewise. + * node-create.c (diskfs_create_node): Likewise. + * file-exec.c (diskfs_S_file_exec): Likewise. Use idvec_merge + instead of idvec_merge_ids, now that it's convenient. + * io-reauthenticate.c (diskfs_S_io_reauthenticate): Use new + iohelp_reauthenticate. + +Tue Nov 5 21:10:18 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * diskfs.h: Include <idvec.h>. + (struct protid): Delete members `uids', `gids', `nuids' and + `ngids'. New member `user'. + Thu Oct 24 15:56:30 1996 Miles Bader <miles@gnu.ai.mit.edu> * opts-std-startup.c (store_argp_children, startup_argp_children): diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c index ee44eb9a..4fd34138 100644 --- a/libdiskfs/boot-start.c +++ b/libdiskfs/boot-start.c @@ -98,7 +98,7 @@ diskfs_start_bootstrap () err = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node, O_READ | O_EXEC, MACH_PORT_NULL), - 0,0,0,0, &rootpi); + 0, &rootpi); assert_perror (err); root_pt = ports_get_right (rootpi); @@ -261,7 +261,7 @@ diskfs_S_exec_startup_get_info (mach_port_t port, err = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node, O_READ | O_EXEC, MACH_PORT_NULL), - 0,0,0,0, &rootpi); + 0, &rootpi); assert_perror (err); rootport = ports_get_right (rootpi); ports_port_deref (rootpi); @@ -301,7 +301,7 @@ diskfs_execboot_fsys_startup (mach_port_t port, int flags, err = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node, flags, MACH_PORT_NULL), - 0,0,0,0, &rootpi); + 0, &rootpi); assert_perror (err); rootport = ports_get_right (rootpi); mach_port_insert_right (mach_task_self (), rootport, rootport, @@ -415,7 +415,7 @@ diskfs_S_fsys_init (mach_port_t port, err = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node, O_READ|O_EXEC, MACH_PORT_NULL), - 0,0,0,0, &rootpi); + 0, &rootpi); assert_perror (err); root_pt = ports_get_right (rootpi); ports_port_deref (rootpi); diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c index fb5b768e..c99698b5 100644 --- a/libdiskfs/dir-lookup.c +++ b/libdiskfs/dir-lookup.c @@ -228,7 +228,7 @@ diskfs_S_dir_lookup (struct protid *dircred, error = diskfs_create_protid (diskfs_make_peropen (dnp, 0, dircred->po->dotdotport), - 0, 0, 0, 0, &newpi); + 0, &newpi); if (error) goto out; @@ -240,8 +240,7 @@ diskfs_S_dir_lookup (struct protid *dircred, mutex_unlock (&dnp->lock); error = fshelp_fetch_root (&np->transbox, &dircred->po->dotdotport, - dirport, dircred->uids, dircred->nuids, - dircred->gids, dircred->ngids, + dirport, dircred->user, lastcomp ? flags : 0, (np->istranslated ? _diskfs_translator_callback1 @@ -378,10 +377,10 @@ diskfs_S_dir_lookup (struct protid *dircred, error = EOPNOTSUPP; if (!error && (flags & O_READ)) - error = diskfs_access (np, S_IREAD, dircred); + error = fshelp_access (&np->dn_stat, S_IREAD, dircred->user); if (!error && (flags & O_EXEC)) - error = diskfs_access (np, S_IEXEC, dircred); + error = fshelp_access (&np->dn_stat, S_IEXEC, dircred->user); if (!error && (flags & O_WRITE)) { @@ -390,23 +389,22 @@ diskfs_S_dir_lookup (struct protid *dircred, else if (diskfs_check_readonly ()) error = EROFS; else - error = diskfs_access (np, S_IWRITE, dircred); + error = fshelp_access (&np->dn_stat, S_IWRITE, dircred->user); } if (error) goto out; } - if ((flags & O_NOATIME) && (diskfs_isowner (np, dircred) == EPERM)) + if ((flags & O_NOATIME) + && (fshelp_isowner (&np->dn_stat, dircred->user) == EPERM)) flags &= ~O_NOATIME; error = diskfs_create_protid (diskfs_make_peropen (np, (flags &~OPENONLY_STATE_MODES), dircred->po->dotdotport), - dircred->uids, dircred->nuids, - dircred->gids, dircred->ngids, - &newpi); + dircred->user, &newpi); if (! error) { diff --git a/libdiskfs/dir-mkfile.c b/libdiskfs/dir-mkfile.c index cdfe6e31..a95f9b34 100644 --- a/libdiskfs/dir-mkfile.c +++ b/libdiskfs/dir-mkfile.c @@ -46,7 +46,7 @@ diskfs_S_dir_mkfile (struct protid *cred, mutex_unlock (&dnp->lock); return ENOTDIR; } - err = diskfs_access (dnp, S_IWRITE, cred); + err = fshelp_access (&dnp->dn_stat, S_IWRITE, cred->user); if (err) { mutex_unlock (&dnp->lock); @@ -70,9 +70,7 @@ diskfs_S_dir_mkfile (struct protid *cred, flags &= (O_READ | O_WRITE | O_EXEC); err = diskfs_create_protid (diskfs_make_peropen (np, flags, cred->po->dotdotport), - cred->uids, cred->nuids, - cred->gids, cred->ngids, - &newpi); + cred->user, &newpi); if (! err) { *newnode = ports_get_right (newpi); diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h index e757e44e..70203152 100644 --- a/libdiskfs/diskfs.h +++ b/libdiskfs/diskfs.h @@ -24,6 +24,7 @@ #include <hurd/ports.h> #include <hurd/fshelp.h> #include <hurd/iohelp.h> +#include <idvec.h> #ifndef DISKFS_EI #define DISKFS_EI extern inline @@ -36,8 +37,7 @@ struct protid struct port_info pi; /* libports info block */ /* User identification */ - uid_t *uids, *gids; - int nuids, ngids; + struct iouser *user; /* Object this refers to */ struct peropen *po; @@ -711,90 +711,6 @@ diskfs_nrele_light (struct node *np) spin_unlock (&diskfs_node_refcnt_lock); } -/* Return nonzero iff the user identified by CRED has uid UID. */ -DISKFS_EI int -diskfs_isuid (uid_t uid, struct protid *cred) -{ - int i; - for (i = 0; i < cred->nuids; i++) - if (cred->uids[i] == uid) - return 1; - return 0; -} - -/* Return nonzero iff the user identified by CRED has group GRP. */ -DISKFS_EI int -diskfs_groupmember (uid_t grp, struct protid *cred) -{ - int i; - for (i = 0; i < cred->ngids; i++) - if (cred->gids[i] == grp) - return 1; - return 0; -} - -/* Check to see if the user identified by CRED is permitted to do - owner-only operations on node NP; if so, return 0; if not, return - EPERM. */ -DISKFS_EI error_t -diskfs_isowner (struct node *np, struct protid *cred) -{ - /* Permitted if the user is the owner, superuser, or if the user - is in the group of the file and has the group ID as their user - ID. (This last is colloquially known as `group leader'.) */ - if (diskfs_isuid (np->dn_stat.st_uid, cred) || diskfs_isuid (0, cred) - || (diskfs_groupmember (np->dn_stat.st_gid, cred) - && diskfs_isuid (np->dn_stat.st_gid, cred))) - return 0; - else - return EPERM; -} - -/* Check to see is the user identified by CRED is permitted to do - operation OP on node NP. Op is one of S_IREAD, S_IWRITE, or S_IEXEC. - Return 0 if the operation is permitted and EACCES if not. */ -DISKFS_EI error_t -diskfs_access (struct node *np, int op, struct protid *cred) -{ - int gotit; - if (diskfs_isuid (0, cred)) - gotit = 1; - else if (cred->nuids == 0 && (np->dn_stat.st_mode & S_IUSEUNK)) - gotit = np->dn_stat.st_mode & (op << S_IUNKSHIFT); - else if (!diskfs_isowner (np, cred)) - gotit = np->dn_stat.st_mode & op; - else if (diskfs_groupmember (np->dn_stat.st_gid, cred)) - gotit = np->dn_stat.st_mode & (op >> 3); - else - gotit = np->dn_stat.st_mode & (op >> 6); - return gotit ? 0 : EACCES; -} - -/* Check to see if the user identified by CRED is allowed to modify - directory DP with respect to existing file NP. This is the same - as diskfs_access (dp, S_IWRITE, cred), except when the directory - has the sticky bit set. (If there is no existing file NP, then - 0 can be passed.) */ -DISKFS_EI error_t -diskfs_checkdirmod (struct node *dp, struct node *np, - struct protid *cred) -{ - error_t err; - - /* The user must be able to write the directory, but if the directory - is sticky, then the user must also be either the owner of the directory - or the file. */ - err = diskfs_access (dp, S_IWRITE, cred); - if (err) - return err; - - if ((dp->dn_stat.st_mode & S_ISVTX) && np && !diskfs_isuid (0, cred) - && diskfs_isowner (dp, cred) && diskfs_isowner (np, cred)) - return EACCES; - - return 0; -} - /* Reading and writing of files. this is called by other filesystem routines and handles extension of files automatically. NP is the node to be read or written, and must be locked. DATA will be @@ -923,20 +839,18 @@ diskfs_create_node (struct node *dir, char *name, mode_t mode, struct node **newnode, struct protid *cred, struct dirstat *ds); -/* Create and return a protid for an existing peropen PO in CRED. The uid - set is UID (length NUIDS); the gid set is GID (length NGIDS). The node - PO->np must be locked. */ -error_t diskfs_create_protid (struct peropen *po, uid_t *uids, int nuids, - uid_t *gids, int ngids, struct protid **cred); +/* Create and return a protid for an existing peropen PO in CRED, + referring to user USER. The node PO->np must be locked. */ +error_t diskfs_create_protid (struct peropen *po, struct iouser *user, + struct protid **cred); /* Build and return in CRED a protid which has no user identification, for peropen PO. The node PO->np must be locked. */ error_t diskfs_start_protid (struct peropen *po, struct protid **cred); /* Finish building protid CRED started with diskfs_start_protid; - the uid set is UID (length NUIDS); the gid set is GID (length NGIDS). */ -void diskfs_finish_protid (struct protid *cred, uid_t *uids, int nuids, - gid_t *gids, int nguds); + the user to install is USER. *q +void diskfs_finish_protid (struct protid *cred, struct iouser *user); /* Create and return a new peropen structure on node NP with open flags FLAGS. */ diff --git a/libdiskfs/file-access.c b/libdiskfs/file-access.c index 7553ffda..4a5eb17d 100644 --- a/libdiskfs/file-access.c +++ b/libdiskfs/file-access.c @@ -31,11 +31,11 @@ diskfs_S_file_check_access (struct protid *cred, np = cred->po->np; mutex_lock (&np->lock); *type = 0; - if (diskfs_access (np, S_IREAD, cred) == 0) + if (fshelp_access (&np->dn_stat, S_IREAD, cred->user) == 0) *type |= O_READ; - if (diskfs_access (np, S_IWRITE, cred) == 0) + if (fshelp_access (&np->dn_stat, S_IWRITE, cred->user) == 0) *type |= O_WRITE; - if (diskfs_access (np, S_IEXEC, cred) == 0) + if (fshelp_access (&np->dn_stat, S_IEXEC, cred->user) == 0) *type |= O_EXEC; mutex_unlock (&np->lock); diff --git a/libdiskfs/file-chauthor.c b/libdiskfs/file-chauthor.c index 25f4c4ec..87070a65 100644 --- a/libdiskfs/file-chauthor.c +++ b/libdiskfs/file-chauthor.c @@ -27,7 +27,7 @@ dithkfth_TH_file_chauthor (struct protid *cred, { CHANGE_NODE_FIELD (cred, ({ - err = dithkfth_ithowner (np, cred); + err = fthhelp_ithowner (np->dn_thtat, cred->uther); if (!err) err = dithkfth_validate_author_change (np, author); if (!err) diff --git a/libdiskfs/file-chflags.c b/libdiskfs/file-chflags.c index e1403f25..d70cc712 100644 --- a/libdiskfs/file-chflags.c +++ b/libdiskfs/file-chflags.c @@ -25,7 +25,7 @@ diskfs_S_file_chflags (struct protid *cred, { CHANGE_NODE_FIELD (cred, ({ - err = diskfs_isowner (np, cred); + err = fshelp_isowner (&np->dn_stat, cred->user); if (!err) err = diskfs_validate_flags_change (np, flags); if (!err) diff --git a/libdiskfs/file-chmod.c b/libdiskfs/file-chmod.c index 545b810f..c27b5854 100644 --- a/libdiskfs/file-chmod.c +++ b/libdiskfs/file-chmod.c @@ -26,16 +26,17 @@ diskfs_S_file_chmod (struct protid *cred, CHANGE_NODE_FIELD (cred, ({ - if (!(err = diskfs_isowner (np, cred))) + if (!(err = fshelp_isowner (&np->dn_stat, cred->user))) { - if (!diskfs_isuid (0, cred)) + if (!idvec_contains (cred->user->uids, 0)) { if (!S_ISDIR (np->dn_stat.st_mode)) mode &= ~S_ISVTX; - if (!diskfs_groupmember (np->dn_stat.st_gid, - cred)) + if (!idvec_contains (cred->user->gids, + np->dn_stat.st_gid)) mode &= ~S_ISGID; - if (!diskfs_isuid (np->dn_stat.st_uid, cred)) + if (!idvec_contains (cred->user->uids, + np->dn_stat.st_uid)) mode &= ~S_ISUID; } mode |= (np->dn_stat.st_mode & (S_IFMT | S_ISPARE)); diff --git a/libdiskfs/file-chown.c b/libdiskfs/file-chown.c index a0c4f225..04546bf0 100644 --- a/libdiskfs/file-chown.c +++ b/libdiskfs/file-chown.c @@ -26,11 +26,11 @@ diskfs_S_file_chown (struct protid *cred, { CHANGE_NODE_FIELD (cred, ({ - err = diskfs_isowner (np, cred); + err = fshelp_isowner (&np->dn_stat, cred->user); if (err - || ((!diskfs_isuid (uid, cred) - || !diskfs_groupmember (gid, cred)) - && !diskfs_isuid (0, cred))) + || ((!idvec_contains (cred->user->uids, cred) + || !idvec_contains (cred->user->gids, gid)) + && !idvec_contains (cred->user->uids, 0))) err = EPERM; else { diff --git a/libdiskfs/file-exec.c b/libdiskfs/file-exec.c index c21f12e1..801a0ab4 100644 --- a/libdiskfs/file-exec.c +++ b/libdiskfs/file-exec.c @@ -88,9 +88,9 @@ diskfs_S_file_exec (struct protid *cred, int secure = 0; error_t get_file_ids (struct idvec *uids, struct idvec *gids) { - error_t err = idvec_merge_ids (uids, cred->uids, cred->nuids); + error_t err = idvec_merge (uids, cred->user->uids); if (! err) - err = idvec_merge_ids (gids, cred->gids, cred->ngids); + err = idvec_merge (gids, cred->user->gids); return err; } err = @@ -107,16 +107,14 @@ diskfs_S_file_exec (struct protid *cred, to the user. Too many things depend on that that it can't be changed. So this vague attempt isn't even worth trying. */ #if 0 - if (diskfs_access (np, S_IREAD, cred)) + if (fshelp_access (&np->dn_stat, S_IREAD, cred->user)) flags |= EXEC_NEWTASK; #endif if (! err) err = diskfs_create_protid (diskfs_make_peropen (np, O_READ, cred->po->dotdotport), - cred->uids, cred->nuids, - cred->gids, cred->ngids, - &newpi); + cred->user, &newpi); if (! err) { diff --git a/libdiskfs/file-get-transcntl.c b/libdiskfs/file-get-transcntl.c index adda4477..4eb78992 100644 --- a/libdiskfs/file-get-transcntl.c +++ b/libdiskfs/file-get-transcntl.c @@ -33,7 +33,7 @@ diskfs_S_file_get_translator_cntl (struct protid *cred, np = cred->po->np; mutex_lock (&np->lock); - error = diskfs_isowner (np, cred); + error = fshelp_isowner (&np->dn_stat, cred->user); if (!error) error = fshelp_fetch_control (&np->transbox, ctl); if (ctl == MACH_PORT_NULL) diff --git a/libdiskfs/file-getcontrol.c b/libdiskfs/file-getcontrol.c index e510a271..4f1ae23a 100644 --- a/libdiskfs/file-getcontrol.c +++ b/libdiskfs/file-getcontrol.c @@ -30,7 +30,7 @@ diskfs_S_file_getcontrol (struct protid *cred, if (!cred) return EOPNOTSUPP; - if (!diskfs_isuid (0, cred)) + if (!idvec_contains (cred->user->uids, 0)) error = EPERM; else { diff --git a/libdiskfs/file-inv-trans.c b/libdiskfs/file-inv-trans.c index bbdac6ff..d0a0082b 100644 --- a/libdiskfs/file-inv-trans.c +++ b/libdiskfs/file-inv-trans.c @@ -72,9 +72,10 @@ diskfs_S_file_invoke_translator (struct protid *cred __attribute__ ((unused)), mach_port_mod_refs (mach_task_self (), control, MACH_PORT_RIGHT_SEND, 1); mutex_unlock (&np->lock); - error = fsys_getroot (control, cred->uids, cred->nuids, - cred->gids, cred->ngids, flags, retry, - retry_name, retrypt); + error = fsys_getroot (control, + cred->user->uids->ids, cred->user->uids->num, + cred->user->gids->ids, cred->user->gids->num, + flags, retry, retry_name, retrypt); if (error == MACH_SEND_INVALID_DEST) { mutex_lock (&np->lock); @@ -139,9 +140,7 @@ diskfs_S_file_invoke_translator (struct protid *cred __attribute__ ((unused)), error = diskfs_create_protid (diskfs_make_peropen (np, flags, _diskfs_dotdot_file), - cred->uids, cred->nuids, - cred->gids, cred->ngids, - &newpi); + cred->user, &newpi); if (! error) { *retry = FS_RETRY_NONE; diff --git a/libdiskfs/file-set-trans.c b/libdiskfs/file-set-trans.c index 1143ef4a..07f365a5 100644 --- a/libdiskfs/file-set-trans.c +++ b/libdiskfs/file-set-trans.c @@ -53,7 +53,7 @@ diskfs_S_file_set_translator (struct protid *cred, mutex_lock (&np->lock); - error = diskfs_isowner (np, cred); + error = fshelp_isowner (&np->dn_stat, cred->user); if (error) { mutex_unlock (&np->lock); diff --git a/libdiskfs/file-utimes.c b/libdiskfs/file-utimes.c index a79d91bd..6f4f53c5 100644 --- a/libdiskfs/file-utimes.c +++ b/libdiskfs/file-utimes.c @@ -26,7 +26,7 @@ diskfs_S_file_utimes (struct protid *cred, { CHANGE_NODE_FIELD (cred, ({ - if (!(err = diskfs_isowner (np, cred))) + if (!(err = fshelp_isowner (&np->dn_stat, cred->user))) { np->dn_stat.st_atime = atime.seconds; np->dn_stat.st_mtime = mtime.seconds; diff --git a/libdiskfs/fsys-getroot.c b/libdiskfs/fsys-getroot.c index 9db349c9..62cf0b1a 100644 --- a/libdiskfs/fsys-getroot.c +++ b/libdiskfs/fsys-getroot.c @@ -46,12 +46,19 @@ diskfs_S_fsys_getroot (fsys_t controlport, mode_t type; struct protid pseudocred; struct protid *newpi; + struct iouser user; if (!pt) return EOPNOTSUPP; flags &= O_HURD; + user.uids = make_idvec (); + user.gids = make_idvec (); + idvec_set_ids (user.uids, uids, nuids); + idvec_set_ids (uesr.gids, gids, ngids); +#define drop_idvec() idvec_free (user.gids); idvec_free (user.uids) + rwlock_reader_lock (&diskfs_fsys_lock); mutex_lock (&diskfs_root_node->lock); @@ -66,8 +73,7 @@ diskfs_S_fsys_getroot (fsys_t controlport, && !(flags & O_NOTRANS)) { error = fshelp_fetch_root (&diskfs_root_node->transbox, - &dotdot, dotdot, uids, nuids, - gids, ngids, flags, + &dotdot, dotdot, &user, flags, _diskfs_translator_callback1, _diskfs_translator_callback2, retry, retryname, returned_port); @@ -75,6 +81,7 @@ diskfs_S_fsys_getroot (fsys_t controlport, { mutex_unlock (&diskfs_root_node->lock); rwlock_reader_unlock (&diskfs_fsys_lock); + drop_idvec (); if (!error) *returned_port_poly = MACH_MSG_TYPE_MOVE_SEND; return error; @@ -101,7 +108,10 @@ diskfs_S_fsys_getroot (fsys_t controlport, mutex_unlock (&diskfs_root_node->lock); rwlock_reader_unlock (&diskfs_fsys_lock); if (error) - return error; + { + drop_idvec (); + return error; + } if (pathbuf[0] == '/') { @@ -110,6 +120,7 @@ diskfs_S_fsys_getroot (fsys_t controlport, *returned_port_poly = MACH_MSG_TYPE_COPY_SEND; strcpy (retryname, pathbuf); mach_port_deallocate (mach_task_self (), dotdot); + drop_idvec (); return 0; } else @@ -118,6 +129,7 @@ diskfs_S_fsys_getroot (fsys_t controlport, *returned_port = dotdot; *returned_port_poly = MACH_MSG_TYPE_MOVE_SEND; strcpy (retryname, pathbuf); + drop_idvec (); return 0; } } @@ -127,17 +139,11 @@ diskfs_S_fsys_getroot (fsys_t controlport, && (flags & (O_READ|O_WRITE|O_EXEC))) error = EOPNOTSUPP; - /* diskfs_access requires a cred; so we give it one. */ - pseudocred.uids = uids; - pseudocred.gids = gids; - pseudocred.nuids = nuids; - pseudocred.ngids = ngids; - if (!error && (flags & O_READ)) - error = diskfs_access (diskfs_root_node, S_IREAD, &pseudocred); + error = fshelp_access (&diskfs_root_node->dn_stat, S_IREAD, &user); if (!error && (flags & O_EXEC)) - error = diskfs_access (diskfs_root_node, S_IEXEC, &pseudocred); + error = fshelp_access (&diskfs_root_node->dn_stat, S_IEXEC, &user); if (!error && (flags & (O_WRITE))) { @@ -146,25 +152,28 @@ diskfs_S_fsys_getroot (fsys_t controlport, else if (diskfs_check_readonly ()) error = EROFS; else - error = diskfs_access (diskfs_root_node, S_IWRITE, &pseudocred); + error = fshelp_access (&diskfs_root_node->dn_stat, + S_IWRITE, &pseudocred.user); } if (error) { mutex_unlock (&diskfs_root_node->lock); rwlock_reader_unlock (&diskfs_fsys_lock); + drop_idvec (); return error; } if ((flags & O_NOATIME) - && (diskfs_isowner (diskfs_root_node, &pseudocred) == EPERM)) + && (fshelp_isowner (&diskfs_root_node->dn_stat, &user) + == EPERM)) flags &= ~O_NOATIME; flags &= ~OPENONLY_STATE_MODES; error = diskfs_create_protid (diskfs_make_peropen (diskfs_root_node, flags, dotdot), - uids, nuids, gids, ngids, &newpi); + &user, &newpi); mach_port_deallocate (mach_task_self (), dotdot); if (! error) { @@ -180,5 +189,7 @@ diskfs_S_fsys_getroot (fsys_t controlport, ports_port_deref (pt); + drop_idvec (); + return error; } diff --git a/libdiskfs/ifsock.c b/libdiskfs/ifsock.c index cffda289..3e9b8325 100644 --- a/libdiskfs/ifsock.c +++ b/libdiskfs/ifsock.c @@ -45,7 +45,7 @@ diskfs_S_ifsock_getsockaddr (struct protid *cred, mutex_unlock (&np->lock); return EOPNOTSUPP; } - err = diskfs_access (np, S_IWRITE, cred); + err = fshelp_access (&np->dn_stat, S_IWRITE, cred->user); if (err) { mutex_unlock (&np->lock); diff --git a/libdiskfs/io-duplicate.c b/libdiskfs/io-duplicate.c index addefc48..3cbf8f7b 100644 --- a/libdiskfs/io-duplicate.c +++ b/libdiskfs/io-duplicate.c @@ -32,8 +32,7 @@ diskfs_S_io_duplicate (struct protid *cred, mutex_lock (&cred->po->np->lock); - err = diskfs_create_protid (cred->po, cred->uids, cred->nuids, - cred->gids, cred->ngids, &newpi); + err = diskfs_create_protid (cred->po, cred->user, &newpi); if (! err) { *port = ports_get_right (newpi); diff --git a/libdiskfs/io-reauthenticate.c b/libdiskfs/io-reauthenticate.c index 9b065a3b..3fc780d2 100644 --- a/libdiskfs/io-reauthenticate.c +++ b/libdiskfs/io-reauthenticate.c @@ -24,21 +24,12 @@ diskfs_S_io_reauthenticate (struct protid *cred, mach_port_t rend_port) { struct protid *newcred; - uid_t gubuf[20], ggbuf[20], aubuf[20], agbuf[20]; - uid_t *gen_uids, *gen_gids, *aux_uids, *aux_gids; - u_int genuidlen, gengidlen, auxuidlen, auxgidlen; error_t err; mach_port_t newright; if (cred == 0) return EOPNOTSUPP; - genuidlen = gengidlen = auxuidlen = auxgidlen = 20; - gen_uids = gubuf; - gen_gids = ggbuf; - aux_uids = aubuf; - aux_gids = agbuf; - /* This routine must carefully ignore EINTR because we are a simpleroutine, so callers won't know to restart. */ @@ -56,40 +47,15 @@ diskfs_S_io_reauthenticate (struct protid *cred, err = mach_port_insert_right (mach_task_self (), newright, newright, MACH_MSG_TYPE_MAKE_SEND); assert_perror (err); - do - err = auth_server_authenticate (diskfs_auth_server_port, - rend_port, - MACH_MSG_TYPE_COPY_SEND, - newright, - MACH_MSG_TYPE_COPY_SEND, - &gen_uids, &genuidlen, - &aux_uids, &auxuidlen, - &gen_gids, &gengidlen, - &aux_gids, &auxgidlen); - while (err == EINTR); + + diskfs_finish_protid (newcred, iohelp_reauth (diskfs_auth_server_port, + rend_port, newright, 1)); mach_port_deallocate (mach_task_self (), rend_port); mach_port_deallocate (mach_task_self (), newright); - if (err) - diskfs_finish_protid (newcred, 0, 0, 0, 0); - else - diskfs_finish_protid (newcred, gen_uids, genuidlen, gen_gids, gengidlen); mutex_unlock (&cred->po->np->lock); ports_port_deref (newcred); - if (gubuf != gen_uids) - vm_deallocate (mach_task_self (), (u_int) gen_uids, - genuidlen * sizeof (uid_t)); - if (ggbuf != gen_gids) - vm_deallocate (mach_task_self (), (u_int) gen_gids, - gengidlen * sizeof (uid_t)); - if (aubuf != aux_uids) - vm_deallocate (mach_task_self (), (u_int) aux_uids, - auxuidlen * sizeof (uid_t)); - if (agbuf != aux_gids) - vm_deallocate (mach_task_self (), (u_int) aux_gids, - auxgidlen * sizeof (uid_t)); - return 0; } diff --git a/libdiskfs/io-restrict-auth.c b/libdiskfs/io-restrict-auth.c index 30ecf91b..76e15dfa 100644 --- a/libdiskfs/io-restrict-auth.c +++ b/libdiskfs/io-restrict-auth.c @@ -40,37 +40,34 @@ diskfs_S_io_restrict_auth (struct protid *cred, u_int ngids) { error_t err; - uid_t *newuids, *newgids; - int i, newnuids, newngids; + struct idvec *uvec, *gvec; struct protid *newpi; if (!cred) return EOPNOTSUPP; + + uvec = make_idvec (); + gvec = make_idvec (); - if (diskfs_isuid (0, cred)) - /* CRED has root access, and so may use any ids. */ + if (idvec_contains (cred->user->uids, 0)) { - newuids = uids; - newnuids = nuids; - newgids = gids; - newngids = ngids; + /* CRED has root access, and so may use any ids. */ + idvec_set_ids (uvec, uids, nuids); + idvec_set_ids (gvec, gids, ngids); } else - /* Otherwise, use any of the requested ids that CRED already has. */ { - newuids = alloca (sizeof (uid_t) * cred->nuids); - newgids = alloca (sizeof (uid_t) * cred->ngids); - - for (i = newnuids = 0; i < cred->nuids; i++) - if (listmember (uids, cred->uids[i], nuids)) - newuids[newnuids++] = cred->uids[i]; - for (i = newngids = 0; i < cred->ngids; i++) - if (listmember (gids, cred->gids[i], ngids)) - newgids[newngids++] = cred->gids[i]; + /* Otherwise, use any of the requested ids that CRED already has. */ + for (i = 0; i < cred->user->uids->num; i++) + if (listmember (uids, cred->user->uids->ids[i], nuids)) + idvec_add (uvec, cred->user->uids->ids[i]); + for (i = 0; i < cred->user->gids->num; i++) + if (listmember (gids, cred->user->gids->ids[i], ngids)) + idvec_add (gvec, cred->user->gids->ids[i]) } mutex_lock (&cred->po->np->lock); - err = diskfs_create_protid (cred->po, newuids, newnuids, newgids, newngids, + err = diskfs_create_protid (cred->po, iohelp_create_iouser (uvec, gvec), &newpi); if (! err) { diff --git a/libdiskfs/lithp.h b/libdiskfs/lithp.h index fa312fd2..be56377d 100644 --- a/libdiskfs/lithp.h +++ b/libdiskfs/lithp.h @@ -22,9 +22,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Hmm. */ #define dithkfth_TH_file_chauthor diskfs_S_file_chauthor -#define dithkfth_ithowner diskfs_isowner +#define fthhelp_ithowner fshelp_isowner #define dithkfth_validate_author_change diskfs_validate_author_change #define dn_thtat dn_stat #define tht_author st_author #define dn_thet_theetime dn_set_ctime #define fth_TH_dot_h "fs_S.h" +#define uther user diff --git a/libdiskfs/lookup.c b/libdiskfs/lookup.c index 282d829f..96cce94e 100644 --- a/libdiskfs/lookup.c +++ b/libdiskfs/lookup.c @@ -92,7 +92,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, diskfs_null_dirstat (ds); return ENOTDIR; } - err = diskfs_access (dp, S_IEXEC, cred); + err = fshelp_access (&dp->dn_stat, S_IEXEC, cred->user); if (err) { if (ds) @@ -157,7 +157,9 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, || (type == CREATE && err == ENOENT) || (type == REMOVE && err != ENOENT)) { - error_t err2 = diskfs_checkdirmod (dp, (err || !np) ? 0 : *np, cred); + error_t err2 = fshelp_checkdirmod (&dp->dn_stat, + (err || !np) ? 0 : &(*np)->dn_stat, + cred->user); if (err2) { if (np && !err) diff --git a/libdiskfs/node-create.c b/libdiskfs/node-create.c index 11f5b0fe..1ff8ac2b 100644 --- a/libdiskfs/node-create.c +++ b/libdiskfs/node-create.c @@ -52,8 +52,8 @@ diskfs_create_node (struct node *dir, np = *newnode; /* Initialize the on-disk fields. */ - if (cred->nuids) - newuid = cred->uids[0]; + if (cred->user->uids->num) + newuid = cred->user->uids->ids[0]; else { newuid = dir->dn_stat.st_uid; @@ -65,7 +65,7 @@ diskfs_create_node (struct node *dir, np->dn_stat.st_uid = newuid; newgid = dir->dn_stat.st_gid; - if (!diskfs_groupmember (newgid, cred)) + if (!idvec_contains (cred->user->gids, newgid)) mode &= ~S_ISGID; err = diskfs_validate_group_change (np, newgid); if (err) diff --git a/libdiskfs/protid-make.c b/libdiskfs/protid-make.c index c67bd41b..b61f9d95 100644 --- a/libdiskfs/protid-make.c +++ b/libdiskfs/protid-make.c @@ -37,45 +37,35 @@ diskfs_start_protid (struct peropen *po, struct protid **cred) } /* Finish building protid CRED started with diskfs_start_protid; - the uid set is UID (length NUIDS); the gid set is GID (length NGIDS). */ + the user to install is USER. */ void -diskfs_finish_protid (struct protid *cred, uid_t *uids, int nuids, - gid_t *gids, int ngids) +diskfs_finish_protid (struct protid *cred, struct iouser *user) { - if (!uids) - nuids = 1; - if (!gids) - ngids = 1; - - cred->uids = malloc (nuids * sizeof (uid_t)); - cred->gids = malloc (ngids * sizeof (uid_t)); - cred->nuids = nuids; - cred->ngids = ngids; - - if (uids) - bcopy (uids, cred->uids, nuids * sizeof (uid_t)); - else - *cred->uids = 0; - - if (gids) - bcopy (gids, cred->gids, ngids * sizeof (uid_t)); + if (!user) + { + uid_t zero = 0; + /* Create one for root */ + user = iohelp_create_iouser (make_idvec (), make_idvec ()); + idvec_set_ids (user->uids, &zero, 1); + idvec_set_ids (user->gids, &zero, 1); + cred->user = user; + } else - *cred->gids = 0; + cred->user = iohelp_dup_user (user); mach_port_move_member (mach_task_self (), cred->pi.port_right, diskfs_port_bucket->portset); } -/* Create and return a protid for an existing peropen PO in CRED. The uid - set is UID (length NUIDS); the gid set is GID (length NGIDS). The node - PO->np must be locked. */ +/* Create and return a protid for an existing peropen PO in CRED for USER. + The node PO->np must be locked. */ error_t -diskfs_create_protid (struct peropen *po, uid_t *uids, int nuids, - uid_t *gids, int ngids, struct protid **cred) +diskfs_create_protid (struct peropen *po, struct iouser *user, + struct protid **cred) { error_t err = diskfs_start_protid (po, cred); if (! err) - diskfs_finish_protid (*cred, uids, nuids, gids, ngids); + diskfs_finish_protid (*cred, user); return err; } diff --git a/libdiskfs/protid-rele.c b/libdiskfs/protid-rele.c index 0c5d40ed..10ff6890 100644 --- a/libdiskfs/protid-rele.c +++ b/libdiskfs/protid-rele.c @@ -26,6 +26,7 @@ diskfs_protid_rele (void *arg) { struct protid *cred = arg; + iohelp_free_iouser (cred->user); if (cred->shared_object) mach_port_deallocate (mach_task_self (), cred->shared_object); if (cred->mapped) diff --git a/libdiskfs/trans-callback.c b/libdiskfs/trans-callback.c index 7701199b..6ad6f1e7 100644 --- a/libdiskfs/trans-callback.c +++ b/libdiskfs/trans-callback.c @@ -55,10 +55,17 @@ _diskfs_translator_callback2_fn (void *cookie1, void *cookie2, struct node *np = cookie1; mach_port_t *dotdot = cookie2; struct protid *cred; - error_t err = + error_t err; + struct idvec *uids, *gids; + + uids = make_idvec (); + gids = make_idvec (); + idvec_set_ids (uids, &np->dn_stat.st_uid, 1); + idvec_set_ids (gids, &np->dn_stat.st_gid, 1); + + err = diskfs_create_protid (diskfs_make_peropen (np, flags, *dotdot), - &np->dn_stat.st_uid, 1, &np->dn_stat.st_gid, 1, - &cred); + iohelp_create_iouser (uids, gids), &cred); if (! err) { *underlying = ports_get_right (cred); |