diff options
Diffstat (limited to 'libfshelp/fetch-root.c')
-rw-r--r-- | libfshelp/fetch-root.c | 151 |
1 files changed, 78 insertions, 73 deletions
diff --git a/libfshelp/fetch-root.c b/libfshelp/fetch-root.c index b38b276d..54d3c0ca 100644 --- a/libfshelp/fetch-root.c +++ b/libfshelp/fetch-root.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1995, 1996 Free Software Foundation, Inc. +/* + Copyright (C) 1995,96,99,2000,02 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -27,19 +27,18 @@ 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, - retry_type *retry, char *retryname, + retry_type *retry, char *retryname, file_t *root) { error_t err; mach_port_t control; int cancel; int i; - + start_over: if (box->active != MACH_PORT_NULL) @@ -48,50 +47,51 @@ fshelp_fetch_root (struct transbox *box, void *cookie, { uid_t uid, gid; char *argz; - int argz_len; + size_t argz_len; error_t err; mach_port_t ports[INIT_PORT_MAX]; int ints[INIT_INT_MAX]; mach_port_t fds[STDERR_FILENO + 1]; auth_t ourauth, newauth; - int uidarray[2], gidarray[2]; - - mach_port_t - reauth (mach_port_t port, mach_msg_type_name_t port_type) - { - mach_port_t rend, ret; - error_t err; - - if (port == MACH_PORT_NULL) - return port; - - if (port_type == MACH_MSG_TYPE_MAKE_SEND) - mach_port_insert_right (mach_task_self (), port, port,port_type); - - rend = mach_reply_port (); - - err = io_reauthenticate (port, rend, - MACH_MSG_TYPE_MAKE_SEND); - if (! err) - err = auth_user_authenticate (newauth, rend, - MACH_MSG_TYPE_MAKE_SEND, &ret); - if (err) - ret = MACH_PORT_NULL; - - mach_port_destroy (mach_task_self (), rend); - if (!err && port_type != MACH_MSG_TYPE_COPY_SEND) - mach_port_deallocate (mach_task_self (), port); - - return ret; - } + + mach_port_t reauth (mach_port_t port) /* Consumes PORT. */ + { + mach_port_t rend, ret; + error_t err; + + if (port == MACH_PORT_NULL) + return port; + + if (ourauth == MACH_PORT_NULL) + /* We have no auth server, so we aren't doing reauthentications. + Just pass on our own ports directly. */ + return port; + + rend = mach_reply_port (); + + /* MAKE_SEND is safe here because we destroy REND ourselves. */ + err = io_reauthenticate (port, rend, + MACH_MSG_TYPE_MAKE_SEND); + mach_port_deallocate (mach_task_self (), port); + if (! err) + err = auth_user_authenticate (newauth, rend, + MACH_MSG_TYPE_MAKE_SEND, &ret); + if (err) + ret = MACH_PORT_NULL; + + mach_port_destroy (mach_task_self (), rend); + + return ret; + } error_t fetch_underlying (int flags, mach_port_t *underlying, - mach_msg_type_name_t *underlying_type) + mach_msg_type_name_t *underlying_type, + task_t task, void *cookie) { return (*callback2) (box->cookie, cookie, flags, underlying, underlying_type); } - + if (box->flags & TRANSBOX_STARTING) { box->flags |= TRANSBOX_WANTED; @@ -102,50 +102,57 @@ fshelp_fetch_root (struct transbox *box, void *cookie, } box->flags |= TRANSBOX_STARTING; mutex_unlock (box->lock); - + err = (*callback1) (box->cookie, cookie, &uid, &gid, &argz, &argz_len); if (err) goto return_error; - + ourauth = getauth (); - uidarray[0] = uidarray[1] = uid; - gidarray[0] = gidarray[1] = gid; - err = auth_makeauth (ourauth, 0, MACH_MSG_TYPE_MAKE_SEND, 0, - uidarray, 1, uidarray, 2, - gidarray, 1, gidarray, 2, &newauth); - if (err) - goto return_error; - + if (ourauth == MACH_PORT_NULL) + newauth = ourauth; + else + { + uid_t uidarray[2] = { uid, uid }; + gid_t gidarray[2] = { gid, gid }; + err = auth_makeauth (ourauth, 0, MACH_MSG_TYPE_COPY_SEND, 0, + uidarray, 1, uidarray, 2, + gidarray, 1, gidarray, 2, &newauth); + if (err) + goto return_error; + } + bzero (ports, INIT_PORT_MAX * sizeof (mach_port_t)); bzero (fds, (STDERR_FILENO + 1) * sizeof (mach_port_t)); bzero (ints, INIT_INT_MAX * sizeof (int)); - - ports[INIT_PORT_CWDIR] = reauth (getcwdir (), MACH_MSG_TYPE_MOVE_SEND); - ports[INIT_PORT_CRDIR] = reauth (getcrdir (), MACH_MSG_TYPE_MOVE_SEND); + + ports[INIT_PORT_CWDIR] = dotdot; + ports[INIT_PORT_CRDIR] = reauth (getcrdir ()); ports[INIT_PORT_AUTH] = newauth; - - fds[STDERR_FILENO] = - reauth (getdport (STDERR_FILENO), MACH_MSG_TYPE_MOVE_SEND); - - err = fshelp_start_translator_long (fetch_underlying, + + fds[STDERR_FILENO] = reauth (getdport (STDERR_FILENO)); + + err = fshelp_start_translator_long (fetch_underlying, NULL, argz, argz, argz_len, fds, MACH_MSG_TYPE_COPY_SEND, STDERR_FILENO + 1, ports, MACH_MSG_TYPE_COPY_SEND, - INIT_PORT_MAX, + INIT_PORT_MAX, ints, INIT_INT_MAX, + uid, 0, &control); for (i = 0; i <= STDERR_FILENO; i++) mach_port_deallocate (mach_task_self (), fds[i]); + for (i = 0; i < INIT_PORT_MAX; i++) - mach_port_deallocate (mach_task_self (), ports[i]); - + if (i != INIT_PORT_CWDIR) + mach_port_deallocate (mach_task_self (), ports[i]); + mutex_lock (box->lock); - + free (argz); return_error: - + box->flags &= ~TRANSBOX_STARTING; if (box->flags & TRANSBOX_WANTED) { @@ -162,19 +169,20 @@ fshelp_fetch_root (struct transbox *box, void *cookie, box->active = control; } - + control = box->active; - mach_port_mod_refs (mach_task_self (), control, + mach_port_mod_refs (mach_task_self (), control, MACH_PORT_RIGHT_SEND, 1); mutex_unlock (box->lock); - + /* 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->num, + user->gids->ids, user->gids->num, + flags, retry, retryname, root); + mutex_lock (box->lock); - + if ((err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) && control == box->active) fshelp_set_active (box, MACH_PORT_NULL, 0); @@ -182,9 +190,6 @@ fshelp_fetch_root (struct transbox *box, void *cookie, if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) goto start_over; - + return err; } - - - |