summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1995-06-14 17:36:33 +0000
committerMichael I. Bushnell <mib@gnu.org>1995-06-14 17:36:33 +0000
commit823f76c165f7fc1ef2961a2f47560fb7ca91a286 (patch)
tree6d866951c8cb91667885bf60c5f7589e34e46b71
parent76daf9aec79d81273a499b9e733ee5691a86635d (diff)
*** empty log message ***
-rw-r--r--libfshelp/fetch-root.c158
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;
+}
-
+
+