diff options
author | Michael I. Bushnell <mib@gnu.org> | 1995-06-14 17:36:33 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1995-06-14 17:36:33 +0000 |
commit | 823f76c165f7fc1ef2961a2f47560fb7ca91a286 (patch) | |
tree | 6d866951c8cb91667885bf60c5f7589e34e46b71 | |
parent | 76daf9aec79d81273a499b9e733ee5691a86635d (diff) |
*** empty log message ***
-rw-r--r-- | libfshelp/fetch-root.c | 158 |
1 files changed, 118 insertions, 40 deletions
diff --git a/libfshelp/fetch-root.c b/libfshelp/fetch-root.c index b4a88e12..7a48be42 100644 --- a/libfshelp/fetch-root.c +++ b/libfshelp/fetch-root.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994 Free Software Foundation, Inc. + Copyright (C) 1995 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -19,53 +19,131 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "trans.h" +#include <unistd.h> +#include <assert.h> +#include <string.h> +#include <hurd/fsys.h> -/* Implement fshelp_fetch_root; see <hurd/fshelp.h> for the description. */ error_t -fshelp_fetch_root (struct trans_link *link, mach_port_t *cntl, - int passive, error_t (*passive_fn) (char **, u_int *), - void *dirpt, void *nodept, - mach_port_t (*genpt_fn) (mach_port_t), - struct mutex *unlock, uid_t uid, gid_t gid) +fshelp_fetch_root (struct transbox *box, file_t dotdot, + uid_t *uids, int uids_len, + uid_t *gids, int gids_len, + int flags, fshelp_callback_t callback, + retry_type *retry, char *retryname, + file_t *root) { - mach_port_t cwdirpt, nodept; - char buf[1000]; - char *bufp = buf; - u_int buflen = 1000; + error_t err; + mach_port_t control; + + do + { + if (box->active == MACH_PORT_NULL) + do + { + mach_port_t underlying; + uid_t uid, gid; + char *argz; + int 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_port_t rend, ret; + error_t err; - mutex_lock (&link->lock); + rend = mach_reply_port (); + err = io_reauthenticate (port, rend, + MACH_MSG_TYPE_MAKE_SEND); + assert_perror (err); - if (!passive && link->control == MACH_PORT_NULL) - { - mutex_unlock (&link->lock); - return 0; - } - - cwdirpt = (*genpt_fn)(dirpt); - - if (link->control == MACH_PORT_NULL) - { - /* Start passive translator */ - nodept = (*genpt_fn)(nodept); - error = (*passive_fn) (&bufp, buflen); - - if (error) - { - mutex_unlock (&link->lock); - return error; - } + err = auth_user_authenticate (newauth, port, rend, + MACH_MSG_TYPE_MAKE_SEND, + &ret); + if (err) + ret = MACH_PORT_NULL; + + mach_port_destroy (mach_task_self (), rend); + mach_port_deallocate (mach_task_self (), port); + return ret; + } + + err = (*callback) (box->cookie, &underlying, &uid, + &gid, &argz, &argz_len); + if (err) + return err; - mutex_unlock (unlock); - - error = fshelp_start_translator (link, bufp, buflen, cwdirpt, - nodept, uid, gid); + mutex_lock (&box->innerlock); /* cancellation point XXX */ + mutex_unlock (box->lock); + + ourauth = getauth (); + uidarray[0] = uidarray[1] = uid; + gidarray[0] = gidarray[1] = gid; + err = auth_makeauth (ourauth, MACH_PORT_NULL, 0, + MACH_MSG_TYPE_MAKE_SEND, + uidarray, 1, uidarray, 2, + gidarray, 1, gidarray, 2, &newauth); + assert_perror (err); - if (bufp != buf) - vm_deallocate (mach_task_self (), (vm_address_t) bufp, buflen); + 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)); - if (error) - return error; + ports[INIT_PORT_CWDIR] = reauth (getcwdir ()); + ports[INIT_PORT_CRDIR] = reauth (getcrdir ()); + ports[INIT_PORT_AUTH] = newauth; + + fds[STDERR_FILENO] = reauth (getdport (STDERR_FILENO)); + + err = fshelp_start_translator_long (reauth (underlying), + MACH_MSG_TYPE_MOVE_SEND, + argz, argz, argz_len, + fds, STDERR_FILENO + 1, + MACH_MSG_TYPE_MOVE_SEND, + ports, INIT_PORT_MAX, + MACH_MSG_TYPE_MOVE_SEND, + ints, INIT_INT_MAX, + 0, &box->active); + mutex_unlock (&box->innerlock); + + if (err) + return err; + + mutex_lock (box->lock); + + /* The loop here is because between the interlock unlock and + the reacquire of the node lock, someone might have deallocated + the port we just added. */ + } + while (box->active == MACH_PORT_NULL); + + control = box->active; + 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); + + mutex_lock (box->lock); + + if ((err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) + && control == box->active) + fshelp_set_active (box, MACH_PORT_NULL); + mach_port_deallocate (mach_task_self (), control); } + while (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED); + mach_port_deallocate (mach_task_self (), dotdot); + return err; +} - + + |