summaryrefslogtreecommitdiff
path: root/auth
diff options
context:
space:
mode:
Diffstat (limited to 'auth')
-rw-r--r--auth/ChangeLog184
-rw-r--r--auth/Makefile30
-rw-r--r--auth/auth.c504
-rw-r--r--auth/auth_mig.h5
-rw-r--r--auth/authmutations.h6
5 files changed, 729 insertions, 0 deletions
diff --git a/auth/ChangeLog b/auth/ChangeLog
new file mode 100644
index 00000000..ea7f0fb4
--- /dev/null
+++ b/auth/ChangeLog
@@ -0,0 +1,184 @@
+1999-05-13 Roland McGrath <roland@baalperazim.frob.com>
+
+ * auth.c (S_auth_server_authenticate, S_auth_user_authenticate): If
+ rendezvous port arrives as MACH_PORT_DEAD, fail with EINVAL.
+
+1999-05-02 Roland McGrath <roland@baalperazim.frob.com>
+
+ * auth.c: Include <error.h>.
+
+1999-05-01 Roland McGrath <roland@baalperazim.frob.com>
+
+ * auth.c (main): Give diagnostics for lack of bootstrap port or
+ failure of startup_authinit RPC.
+
+1998-11-27 Mark Kettenis <kettenis@phys.uva.nl>
+
+ * auth.c (main): Call _hurd_proc_init with new args set to zero.
+
+Wed Aug 20 14:01:43 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
+
+ * auth.c (main): New args for
+ ports_manage_port_operations_multithread.
+
+Wed Feb 19 23:04:30 1997 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * auth.c (argp_program_version): Make const.
+
+Thu Sep 12 16:27:31 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
+
+ * Makefile (HURDLIBS): New variable.
+ (auth): Delete special depedencies.
+
+Thu Sep 5 11:05:37 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
+
+ * auth.c (AUTH_VERSION): Delete macro.
+ (argp_program_version): Use STANDARD_HURD_VERSION.
+ (main): Pass empty string as release; HURD_VERSION as version.
+
+Fri Jul 19 00:35:46 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
+
+ * auth.c (S_auth_makeauth): Deallocate initial reference to
+ NEWAUTH after *NEWHANDLE has been set.
+
+Thu Jul 18 19:31:53 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
+
+ * auth.c (S_auth_makeauth): It's fine if a passed in auth port is
+ not one we know about; just make the loops across AUTHS deal
+ properly with null values. Only deallocate the AUTHPTS passed in
+ if we don't encounter any errors. Always deallocate the
+ references in the AUTHS array. ISUID and GROUPMEMBER functions
+ should check both effective and auxiliary members of AUTH.
+ (struct pending): Delete member `passthrough_type'.
+ (S_auth_user_authenticate): Always use MOVE_SEND to send pass
+ through port back to user.
+ (S_auth_server_authenticate): Don't bother initializing
+ U.passthrough_type or S.passthrough_type.
+
+Sat Jul 6 23:16:42 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * auth.c (AUTH_VERSION): New macro.
+ (argp_program_version): New variable.
+ (auth_version): Variable removed.
+ (main): Call argp_parse to get defaults.
+ Use AUTH_VERSION instead of auth_version.
+ <argp.h>: New include.
+ <idvec.h>: Changed from <hurd/idvec.h>.
+
+Wed Jun 26 14:22:51 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * auth.c (S_auth_makeauth): Don't special-case the 0 explicit ids
+ case (it used to merge in all the ids from passed in auth-handles
+ in that case).
+
+Mon May 6 14:22:13 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
+
+ * auth.c (auth_version): Upgrade to 0.0.
+
+Sat May 4 22:40:42 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * auth.c (S_auth_user_authenticate, S_auth_server_authenticate):
+ Use ports_interrupt_self_on_port_death instead of
+ cancel_on_dead_name. Hurd_condition_wait returns a boolean, not
+ an error_t, so supply EINTR ourselves.
+ (cancel_on_dead_name): Function removed.
+
+Fri May 3 17:07:45 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
+
+ * auth.c (S_auth_server_authenticate, S_auth_user_authenticate):
+ Remove IGNORED arg.
+
+Tue Apr 30 21:16:07 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
+
+ * auth.c (S_auth_makeauth): Increment NAUTHS for first elt.
+ (main): Initialize the ihash tables, dammit.
+
+Thu Apr 25 02:57:53 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
+
+ * auth.c: Rewritten.
+ * authmutations.h: New file.
+ * Makefile (LCLHDRS): Add it, remove auth_mig.h.
+ (OBJS): Remove auth_replyUser.o, notifyServer.o.
+ (auth): Depend on libports, libihash, libthreads, libshouldbeinlibc.
+
+ * auth_mig.h: Rewritten.
+ * Makefile (OBJS): Add auth_replyUser.o.
+
+Thu Jul 6 15:29:43 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
+
+ * Makefile: Removed dependencies that are now automatically
+ generated.
+
+Fri Nov 18 07:34:11 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
+
+ * Makefile (OBJS): Add notifyServer.o.
+ (auth.o): Depend on notify_S.h.
+ * auth.c: Include "notify_S.h". Remove _S_ from all
+ do_mach_notify_* server routines.
+
+Wed Sep 7 13:14:41 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
+
+ * auth.c (isuid): Look for TEST in the uid arrays, not the gid arrays.
+
+Tue Sep 6 14:33:02 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
+
+ * auth.c (auth_nosenders): Remove auth struct from allapts
+ list correctly.
+
+Thu Aug 25 13:24:24 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
+
+ * auth.c (struct saved_user): Use second rendezvous port in place
+ of rend_int.
+ (strut saved_server): Likewise.
+ (S_auth_user_authenticate): Replace int arg with secondary
+ rendezvous port. Check it instead of old rend_int for match.
+ Deallocate it (twice) if we are completing the auth transaction
+ here. Store it in U in place of the old int.
+ (S_auth_server_authenticate): Likewise, mutatis mutandis.
+
+Mon Aug 15 11:52:49 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
+
+ * auth.c (main): Make startup_essential_task the last thing we
+ do before processing messages.
+
+Thu Jul 21 18:39:38 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
+
+ * Makefile: Rewritten in accord with new scheme.
+ * auth.c: Include "auth_reply_U.h" instead of "auth_reply.h".
+
+Tue Jul 19 12:32:54 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
+
+ * Makefile (auth): Don't use variable $(link) anymore.
+
+Tue Jul 5 14:18:23 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
+
+ * Makefile (SRCS, TAGSHDRS): New variables.
+
+Mon Jun 20 15:04:42 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
+
+ * Makefile (install): Use $(INSTALL_BIN) instead of cp.
+
+Thu May 19 15:18:52 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
+
+ * auth.c (auth_nosenders): Take auth off of allapts list
+ before destroying it.
+
+Thu May 12 15:28:50 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
+
+ * auth.c (main): Declare args ARGC and ARGV; pass ARGV in call
+ to _hurd_proc_init.
+
+Mon May 9 16:50:09 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
+
+ * auth.c (auth_version): New variable.
+ (main): Call proc_register_version.
+
+Thu May 5 07:42:28 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
+
+ * Makefile: Change uses of $(headers) to $(includedir).
+
+Fri Apr 29 16:50:50 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
+
+ * auth.c (main): Fetch hostpriv arg and provide it to
+ startup_essential_task in accord with interface change to
+ startup.defs.
diff --git a/auth/Makefile b/auth/Makefile
new file mode 100644
index 00000000..da41cdd0
--- /dev/null
+++ b/auth/Makefile
@@ -0,0 +1,30 @@
+# Copyright (C) 1991, 93, 94, 95, 96 Free Software Foundation, Inc.
+# This file is part of the GNU Hurd.
+#
+# The GNU Hurd is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# The GNU Hurd is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with the GNU Hurd; see the file COPYING. If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+dir := auth
+makemode := server
+
+SRCS = auth.c
+OBJS = auth.o authServer.o auth_replyUser.o
+LCLHDRS = authmutations.h auth_mig.h
+target = auth
+HURDLIBS=ports threads ihash shouldbeinlibc
+
+MIGSFLAGS = -imacros $(srcdir)/authmutations.h
+
+include ../Makeconf
+
diff --git a/auth/auth.c b/auth/auth.c
new file mode 100644
index 00000000..dd164934
--- /dev/null
+++ b/auth/auth.c
@@ -0,0 +1,504 @@
+/* Authentication server.
+ Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ Written by Roland McGrath.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <mach.h>
+#include <cthreads.h>
+#include <hurd.h>
+#include <hurd/startup.h>
+#include <hurd/ports.h>
+#include <hurd/ihash.h>
+#include <idvec.h>
+#include <assert.h>
+#include <argp.h>
+#include <error.h>
+#include <version.h>
+#include "auth_S.h"
+#include "auth_reply_U.h"
+
+const char *argp_program_version = STANDARD_HURD_VERSION(auth);
+
+
+/* Auth handles are server ports with sets of ids. */
+struct authhandle
+ {
+ struct port_info pi;
+ struct idvec euids, egids, auids, agids;
+ };
+
+struct port_bucket *auth_bucket;
+struct port_class *authhandle_portclass;
+
+
+/* Create a new auth port. */
+
+static error_t
+create_authhandle (struct authhandle **new)
+{
+ error_t err = ports_create_port (authhandle_portclass, auth_bucket,
+ sizeof **new, new);
+ if (! err)
+ bzero (&(*new)->euids, (void *) &(*new)[1] - (void *) &(*new)->euids);
+ return err;
+}
+
+/* Clean up a dead auth port. */
+
+static void
+destroy_authhandle (void *p)
+{
+ struct authhandle *h = p;
+ idvec_free_contents (&h->euids);
+ idvec_free_contents (&h->egids);
+ idvec_free_contents (&h->auids);
+ idvec_free_contents (&h->agids);
+}
+
+/* Called by server stub functions. */
+
+authhandle_t
+auth_port_to_handle (auth_t auth)
+{
+ return ports_lookup_port (auth_bucket, auth, authhandle_portclass);
+}
+
+/* id management. */
+
+inline void idvec_copyout (struct idvec *idvec, uid_t **ids, uid_t *nids)
+{
+ if (idvec->num > *nids)
+ *ids = idvec->ids;
+ else
+ memcpy (*ids, idvec->ids, idvec->num * sizeof *ids);
+ *nids = idvec->num;
+}
+
+#define C(auth, ids) idvec_copyout (&auth->ids, ids, n##ids)
+#define OUTIDS(auth) (C (auth, euids), C (auth, egids), \
+ C (auth, auids), C (auth, agids))
+
+/* Implement auth_getids as described in <hurd/auth.defs>. */
+kern_return_t
+S_auth_getids (struct authhandle *auth,
+ uid_t **euids,
+ u_int *neuids,
+ uid_t **auids,
+ u_int *nauids,
+ uid_t **egids,
+ u_int *negids,
+ uid_t **agids,
+ u_int *nagids)
+{
+ if (! auth)
+ return EOPNOTSUPP;
+
+ OUTIDS (auth);
+
+ return 0;
+}
+
+/* Implement auth_makeauth as described in <hurd/auth.defs>. */
+kern_return_t
+S_auth_makeauth (struct authhandle *auth,
+ mach_port_t *authpts, u_int nauths,
+ uid_t *euids, u_int neuids,
+ uid_t *auids, u_int nauids,
+ uid_t *egids, u_int negids,
+ uid_t *agids, u_int nagids,
+ mach_port_t *newhandle)
+{
+ struct authhandle *newauth, *auths[1 + nauths];
+ int hasroot = 0;
+ error_t err;
+ u_int i, j;
+
+ if (!auth)
+ return EOPNOTSUPP;
+
+ auths[0] = auth;
+
+ /* Fetch the auth structures for all the ports passed in. */
+ for (i = 0; i < nauths; i++)
+ auths[i + 1] = auth_port_to_handle (authpts[i]);
+
+ ++nauths;
+
+ /* Verify that the union of the handles passed in either contains euid 0
+ (root), or contains all the requested ids. */
+
+#define isuid(uid, auth) \
+ (idvec_contains (&(auth)->euids, uid) \
+ || idvec_contains (&(auth)->auids, uid))
+#define groupmember(gid, auth) \
+ (idvec_contains (&(auth)->egids, gid) \
+ || idvec_contains (&(auth)->agids, gid))
+#define isroot(auth) isuid (0, auth)
+
+ for (i = 0; i < nauths; i++)
+ if (auths[i] && isroot (auths[i]))
+ {
+ hasroot = 1;
+ break;
+ }
+
+ if (!hasroot)
+ {
+ int has_it;
+
+ for (i = 0; i < neuids; i++)
+ {
+ has_it = 0;
+ for (j = 0; j < nauths; j++)
+ if (auths[j] && isuid (euids[i], auths[j]))
+ {
+ has_it = 1;
+ break;
+ }
+ if (!has_it)
+ goto eperm;
+ }
+
+ for (i = 0; i < nauids; i++)
+ {
+ has_it = 0;
+ for (j = 0; j < nauths; j++)
+ if (auths[j] && isuid (auids[i], auths[j]))
+ {
+ has_it = 1;
+ break;
+ }
+ if (!has_it)
+ goto eperm;
+ }
+
+ for (i = 0; i < negids; i++)
+ {
+ has_it = 0;
+ for (j = 0; j < nauths; j++)
+ if (auths[j] && groupmember (egids[i], auths[j]))
+ {
+ has_it = 1;
+ break;
+ }
+ if (!has_it)
+ goto eperm;
+ }
+
+ for (i = 0; i < nagids; i++)
+ {
+ has_it = 0;
+ for (j = 0; j < nauths; j++)
+ if (auths[j] && groupmember (agids[i], auths[j]))
+ {
+ has_it = 1;
+ break;
+ }
+ if (!has_it)
+ goto eperm;
+ }
+ }
+
+ err = create_authhandle (&newauth);
+
+ /* Create a new handle with the specified ids. */
+
+#define MERGE S (euids); S (egids); S (auids); S (agids);
+#define S(uids) if (!err) err = idvec_merge_ids (&newauth->uids, uids, n##uids)
+
+ MERGE;
+
+#undef S
+
+ if (! err)
+ {
+ for (j = 1; j < nauths; ++j)
+ mach_port_deallocate (mach_task_self (), authpts[j - 1]);
+ *newhandle = ports_get_right (newauth);
+ ports_port_deref (newauth);
+ }
+
+ for (j = 1; j < nauths; j++)
+ if (auths[j])
+ ports_port_deref (auths[j]);
+ return err;
+
+ eperm:
+ for (j = 1; j < nauths; j++)
+ if (auths[j])
+ ports_port_deref (auths[j]);
+ return EPERM;
+}
+
+/* Transaction handling. */
+
+/* Table of pending transactions keyed on RENDEZVOUS. */
+struct ihash *pending_users, *pending_servers;
+struct mutex pending_lock = MUTEX_INITIALIZER;
+
+/* A pending transaction. */
+struct pending
+ {
+ void **locp; /* Position in one of the ihash tables. */
+ struct condition wakeup; /* The waiter is blocked on this condition. */
+
+ /* The user's auth handle. */
+ struct authhandle *user;
+
+ /* The port to pass back to the user. */
+ mach_port_t passthrough;
+ };
+
+/* Implement auth_user_authenticate as described in <hurd/auth.defs>. */
+kern_return_t
+S_auth_user_authenticate (struct authhandle *userauth,
+ mach_port_t rendezvous,
+ mach_port_t *newport,
+ mach_msg_type_name_t *newporttype)
+{
+ struct pending *s;
+
+ if (! userauth)
+ return EOPNOTSUPP;
+
+ if (rendezvous == MACH_PORT_DEAD) /* Port died in transit. */
+ return EINVAL;
+
+ mutex_lock (&pending_lock);
+
+ /* Look for this port in the server list. */
+ s = ihash_find (pending_servers, rendezvous);
+ if (s)
+ {
+ /* Found it! Extract the port. */
+ *newport = s->passthrough;
+ *newporttype = MACH_MSG_TYPE_MOVE_SEND;
+
+ /* Remove it from the pending list. */
+ ihash_locp_remove (pending_servers, s->locp);
+
+ /* Give the server the auth port and wake the RPC up.
+ We need to add a ref in case the port dies. */
+ s->user = userauth;
+ ports_port_ref (userauth);
+
+ condition_signal (&s->wakeup);
+ mutex_unlock (&pending_lock);
+
+ mach_port_deallocate (mach_task_self (), rendezvous);
+ return 0;
+ }
+ else
+ {
+ /* No pending server RPC for this port.
+ Create a pending user RPC record. */
+ struct pending u;
+ error_t err;
+
+ err = ihash_add (pending_users, rendezvous, &u, &u.locp);
+ if (! err)
+ {
+ /* Store the user auth port and wait for the server RPC to wake
+ us up. */
+ u.user = userauth;
+ condition_init (&u.wakeup);
+ ports_interrupt_self_on_port_death (userauth, rendezvous);
+ if (hurd_condition_wait (&u.wakeup, &pending_lock))
+ /* We were interrupted; remove our record. */
+ {
+ ihash_locp_remove (pending_users, u.locp);
+ err = EINTR;
+ }
+ }
+ /* The server side has already removed U from the ihash table. */
+ mutex_unlock (&pending_lock);
+
+ if (! err)
+ {
+ /* The server RPC has set the port and signalled U.wakeup. */
+ *newport = u.passthrough;
+ *newporttype = MACH_MSG_TYPE_MOVE_SEND;
+ mach_port_deallocate (mach_task_self (), rendezvous);
+ }
+ return err;
+ }
+}
+
+/* Implement auth_server_authenticate as described in <hurd/auth.defs>. */
+kern_return_t
+S_auth_server_authenticate (struct authhandle *serverauth,
+ mach_port_t reply,
+ mach_msg_type_name_t reply_type,
+ mach_port_t rendezvous,
+ mach_port_t newport,
+ mach_msg_type_name_t newport_type,
+ uid_t **euids,
+ u_int *neuids,
+ uid_t **auids,
+ u_int *nauids,
+ uid_t **egids,
+ u_int *negids,
+ uid_t **agids,
+ u_int *nagids)
+{
+ struct pending *u;
+ struct authhandle *user;
+
+ if (! serverauth)
+ return EOPNOTSUPP;
+
+ if (rendezvous == MACH_PORT_DEAD) /* Port died in transit. */
+ return EINVAL;
+
+ mutex_lock (&pending_lock);
+
+ /* Look for this port in the user list. */
+ u = ihash_find (pending_users, rendezvous);
+ if (u)
+ {
+ /* Remove it from the pending list. */
+ ihash_locp_remove (pending_users, u->locp);
+
+ /* Found it! We must add a ref because the one held by the
+ user RPC might die as soon as we unlock pending_lock. */
+ user = u->user;
+ ports_port_ref (user);
+
+ /* Give the user the new port and wake the RPC up. */
+ u->passthrough = newport;
+
+ condition_signal (&u->wakeup);
+ mutex_unlock (&pending_lock);
+ }
+ else
+ {
+ /* No pending user RPC for this port.
+ Create a pending server RPC record. */
+ struct pending s;
+ error_t err;
+
+ err = ihash_add (pending_servers, rendezvous, &s, &s.locp);
+ if (! err)
+ {
+ /* Store the new port and wait for the user RPC to wake us up. */
+ s.passthrough = newport;
+ condition_init (&s.wakeup);
+ ports_interrupt_self_on_port_death (serverauth, rendezvous);
+ if (hurd_condition_wait (&s.wakeup, &pending_lock))
+ /* We were interrupted; remove our record. */
+ {
+ ihash_locp_remove (pending_servers, s.locp);
+ err = EINTR;
+ }
+ }
+ /* The user side has already removed S from the ihash table. */
+ mutex_unlock (&pending_lock);
+
+ if (err)
+ return err;
+
+ /* The user RPC has set the port (with a ref) and signalled S.wakeup. */
+ user = s.user;
+ }
+
+ /* Extract the ids. We must use a separate reply stub so
+ we can deref the user auth handle after the reply uses its
+ contents. */
+ auth_server_authenticate_reply (reply, reply_type, 0,
+ user->euids.ids, user->euids.num,
+ user->auids.ids, user->auids.num,
+ user->egids.ids, user->egids.num,
+ user->agids.ids, user->agids.num);
+ ports_port_deref (user);
+ mach_port_deallocate (mach_task_self (), rendezvous);
+ return MIG_NO_REPLY;
+}
+
+
+
+static int
+auth_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
+{
+ extern int auth_server (mach_msg_header_t *inp, mach_msg_header_t *outp);
+ return (auth_server (inp, outp) ||
+ ports_interrupt_server (inp, outp) ||
+ ports_notify_server (inp, outp));
+}
+
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ mach_port_t boot;
+ process_t proc;
+ mach_port_t hostpriv, masterdev;
+ struct authhandle *firstauth;
+
+ argp_parse (0, argc, argv, 0, 0, 0);
+
+ auth_bucket = ports_create_bucket ();
+ authhandle_portclass = ports_create_class (&destroy_authhandle, 0);
+
+ /* Create the initial root auth handle. */
+ err = create_authhandle (&firstauth);
+ assert_perror (err);
+ idvec_add (&firstauth->euids, 0);
+ idvec_add (&firstauth->auids, 0);
+ idvec_add (&firstauth->auids, 0);
+ idvec_merge (&firstauth->egids, &firstauth->euids);
+ idvec_merge (&firstauth->agids, &firstauth->auids);
+
+ /* Fetch our bootstrap port and contact the bootstrap filesystem. */
+ err = task_get_bootstrap_port (mach_task_self (), &boot);
+ assert_perror (err);
+ if (boot == MACH_PORT_NULL)
+ error (2, 0, "auth server can only be run by init during boot");
+ err = startup_authinit (boot, ports_get_right (firstauth),
+ MACH_MSG_TYPE_MAKE_SEND, &proc);
+ if (err)
+ error (2, err, "cannot contact init for bootstrap");
+
+ /* Register ourselves with the proc server and then start signals. */
+ proc_getprivports (proc, &hostpriv, &masterdev);
+ proc_register_version (proc, hostpriv, "auth", "", HURD_VERSION);
+ mach_port_deallocate (mach_task_self (), masterdev);
+ _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], proc);
+ _hurd_proc_init (argv, NULL, 0);
+
+ /* Init knows intimately that we will be ready for messages
+ as soon as this returns. */
+ startup_essential_task (boot, mach_task_self (), MACH_PORT_NULL, "auth",
+ hostpriv);
+ mach_port_deallocate (mach_task_self (), boot);
+ mach_port_deallocate (mach_task_self (), hostpriv);
+
+ /* Allocate the hash tables. */
+ err = ihash_create (&pending_users);
+ assert_perror (err);
+ err = ihash_create (&pending_servers);
+ assert_perror (err);
+
+ /* Be a server. */
+ while (1)
+ ports_manage_port_operations_multithread (auth_bucket,
+ auth_demuxer,
+ 30 * 1000, 0, 0);
+}
diff --git a/auth/auth_mig.h b/auth/auth_mig.h
new file mode 100644
index 00000000..d919c1b9
--- /dev/null
+++ b/auth/auth_mig.h
@@ -0,0 +1,5 @@
+typedef struct authhandle *authhandle_t;
+
+authhandle_t auth_port_to_handle (auth_t);
+
+#include <hurd/ports.h>
diff --git a/auth/authmutations.h b/auth/authmutations.h
new file mode 100644
index 00000000..63b2f540
--- /dev/null
+++ b/auth/authmutations.h
@@ -0,0 +1,6 @@
+/* CPP definitions for MiG processing of auth.defs for auth server. */
+
+#define AUTH_INTRAN authhandle_t auth_port_to_handle (auth_t)
+#define AUTH_DESTRUCTOR ports_port_deref (authhandle_t)
+
+#define AUTH_IMPORTS import "auth_mig.h";