aboutsummaryrefslogtreecommitdiff
path: root/auth
diff options
context:
space:
mode:
Diffstat (limited to 'auth')
-rw-r--r--auth/ChangeLog148
-rw-r--r--auth/Makefile5
-rw-r--r--auth/auth.c302
3 files changed, 168 insertions, 287 deletions
diff --git a/auth/ChangeLog b/auth/ChangeLog
deleted file mode 100644
index 2f82a470..00000000
--- a/auth/ChangeLog
+++ /dev/null
@@ -1,148 +0,0 @@
-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
index 74eb135d..da7f8e23 100644
--- a/auth/Makefile
+++ b/auth/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991, 93, 94, 95, 96 Free Software Foundation, Inc.
+# Copyright (C) 1991, 93, 94, 95, 96, 2000 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
@@ -22,10 +22,9 @@ SRCS = auth.c
OBJS = auth.o authServer.o auth_replyUser.o
LCLHDRS = authmutations.h auth_mig.h
target = auth
+HURDLIBS = threads ports ihash shouldbeinlibc
MIGSFLAGS = -imacros $(srcdir)/authmutations.h
include ../Makeconf
-auth: ../libports/libports.so ../libthreads/libthreads.so \
- ../libihash/libihash.so ../libshouldbeinlibc/libshouldbeinlibc.so
diff --git a/auth/auth.c b/auth/auth.c
index d77c484e..11db0f8f 100644
--- a/auth/auth.c
+++ b/auth/auth.c
@@ -1,5 +1,5 @@
/* Authentication server.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996,97,98,99,2002 Free Software Foundation, Inc.
Written by Roland McGrath.
This file is part of the GNU Hurd.
@@ -18,6 +18,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <mach.h>
@@ -29,12 +30,13 @@
#include <idvec.h>
#include <assert.h>
#include <argp.h>
+#include <error.h>
+#include <version.h>
#include "auth_S.h"
#include "auth_reply_U.h"
-#define AUTH_VERSION "0.0"
+const char *argp_program_version = STANDARD_HURD_VERSION(auth);
-char *argp_program_version = "auth " AUTH_VERSION " (GNU " HURD_RELEASE ")";
/* Auth handles are server ports with sets of ids. */
struct authhandle
@@ -81,7 +83,8 @@ auth_port_to_handle (auth_t auth)
/* id management. */
-inline void idvec_copyout (struct idvec *idvec, uid_t **ids, uid_t *nids)
+static inline void
+idvec_copyout (struct idvec *idvec, uid_t **ids, size_t *nids)
{
if (idvec->num > *nids)
*ids = idvec->ids;
@@ -98,13 +101,13 @@ inline void idvec_copyout (struct idvec *idvec, uid_t **ids, uid_t *nids)
kern_return_t
S_auth_getids (struct authhandle *auth,
uid_t **euids,
- u_int *neuids,
+ size_t *neuids,
uid_t **auids,
- u_int *nauids,
+ size_t *nauids,
uid_t **egids,
- u_int *negids,
+ size_t *negids,
uid_t **agids,
- u_int *nagids)
+ size_t *nagids)
{
if (! auth)
return EOPNOTSUPP;
@@ -117,17 +120,17 @@ S_auth_getids (struct authhandle *auth,
/* 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 *authpts, size_t nauths,
+ uid_t *euids, size_t neuids,
+ uid_t *auids, size_t nauids,
+ uid_t *egids, size_t negids,
+ uid_t *agids, size_t nagids,
mach_port_t *newhandle)
{
struct authhandle *newauth, *auths[1 + nauths];
int hasroot = 0;
error_t err;
- u_int i, j;
+ size_t i, j;
if (!auth)
return EOPNOTSUPP;
@@ -137,7 +140,7 @@ S_auth_makeauth (struct authhandle *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
@@ -248,15 +251,22 @@ S_auth_makeauth (struct authhandle *auth,
/* 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
+/* Since the user is responsible for freeing the rendezvous port, it has to
+ * wait for the server to have finished transmitting uids.
+ *
+ * The server thus waits for the user to give it uids (unless it was already
+ * there), transmits them and provides the passthrough port.
+ *
+ * The user gives the uids and waits for the passthrough port from the server.
+ *
+ * If the user is early, it has to tell the server it arrived.
+ */
+
+/* A pending user. */
+struct pending_user
{
- void **locp; /* Position in one of the ihash tables. */
- struct condition wakeup; /* The waiter is blocked on this condition. */
+ hurd_ihash_locp_t locp; /* Position in the pending_users ihash table. */
+ struct condition wakeup; /* The reader is blocked on this condition. */
/* The user's auth handle. */
struct authhandle *user;
@@ -265,76 +275,87 @@ struct pending
mach_port_t passthrough;
};
+/* A pending server. */
+struct pending_server
+ {
+ hurd_ihash_locp_t locp; /* Position in the pending_servers ihash table. */
+ struct condition wakeup; /* The server is blocked on this condition. */
+ };
+
+/* Table of pending transactions keyed on RENDEZVOUS. */
+struct hurd_ihash pending_users
+ = HURD_IHASH_INITIALIZER (offsetof (struct pending_user, locp));
+struct hurd_ihash pending_servers
+ = HURD_IHASH_INITIALIZER (offsetof (struct pending_server, locp));
+struct mutex pending_lock = MUTEX_INITIALIZER;
+
/* Implement auth_user_authenticate as described in <hurd/auth.defs>. */
kern_return_t
S_auth_user_authenticate (struct authhandle *userauth,
+ mach_port_t reply,
+ mach_msg_type_name_t reply_type,
mach_port_t rendezvous,
mach_port_t *newport,
mach_msg_type_name_t *newporttype)
{
- struct pending *s;
+ struct pending_server *s;
+ struct pending_user u;
+ error_t err;
if (! userauth)
return EOPNOTSUPP;
- mutex_lock (&pending_lock);
+ if (rendezvous == MACH_PORT_DEAD) /* Port died in transit. */
+ return EINVAL;
- /* 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;
+ u.user = userauth;
+ condition_init (&u.wakeup);
- /* Remove it from the pending list. */
- ihash_locp_remove (pending_servers, s->locp);
+ mutex_lock (&pending_lock);
- /* 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);
+ err = hurd_ihash_add (&pending_users, rendezvous, &u);
+ if (err) {
+ mutex_unlock (&pending_lock);
+ return err;
+ }
+
+ /* Give the server the auth port.
+ We need to add a ref in case the port dies. */
+ ports_port_ref (userauth);
+
+ /* Look for this rendezvous in the server list. */
+ s = hurd_ihash_find (&pending_servers, rendezvous);
+ if (s) {
+ /* Found it! */
+
+ /* Remove it from the pending list. */
+ hurd_ihash_locp_remove (&pending_servers, s->locp);
+
+ /* Tell it we eventually arrived. */
+ condition_signal (&s->wakeup);
+ }
+
+ ports_interrupt_self_on_port_death (userauth, rendezvous);
+ /* Wait for server answer. */
+ if (hurd_condition_wait (&u.wakeup, &pending_lock) &&
+ hurd_ihash_find (&pending_users, rendezvous))
+ /* We were interrupted; remove our record. */
+ {
+ hurd_ihash_locp_remove (&pending_users, u.locp);
+ err = EINTR;
+ }
- condition_signal (&s->wakeup);
- mutex_unlock (&pending_lock);
+ mutex_unlock (&pending_lock);
+ if (! err)
+ {
+ /* Extract the port. */
+ *newport = u.passthrough;
+ *newporttype = MACH_MSG_TYPE_MOVE_SEND;
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;
- }
+ return err;
}
/* Implement auth_server_authenticate as described in <hurd/auth.defs>. */
@@ -346,79 +367,89 @@ S_auth_server_authenticate (struct authhandle *serverauth,
mach_port_t newport,
mach_msg_type_name_t newport_type,
uid_t **euids,
- u_int *neuids,
+ size_t *neuids,
uid_t **auids,
- u_int *nauids,
+ size_t *nauids,
uid_t **egids,
- u_int *negids,
+ size_t *negids,
uid_t **agids,
- u_int *nagids)
+ size_t *nagids)
{
- struct pending *u;
+ struct pending_user *u;
struct authhandle *user;
+ error_t err;
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);
+ /* Look for this rendezvous in the user list. */
+ u = hurd_ihash_find (&pending_users, rendezvous);
+ if (! u)
+ {
+ /* User not here yet, have to wait for it. */
+ struct pending_server s;
+ condition_init (&s.wakeup);
+ err = hurd_ihash_add (&pending_servers, rendezvous, &s);
+ if (! err)
+ {
+ ports_interrupt_self_on_port_death (serverauth, rendezvous);
+ if (hurd_condition_wait (&s.wakeup, &pending_lock) &&
+ hurd_ihash_find (&pending_servers, rendezvous))
+ /* We were interrupted; remove our record. */
+ {
+ hurd_ihash_locp_remove (&pending_servers, s.locp);
+ err = EINTR;
+ }
+ else
+ {
+ u = hurd_ihash_find (&pending_users, rendezvous);
+ if (! u)
+ /* User still not here, odd! */
+ err = EINTR;
+ }
+ }
+ }
+
if (u)
{
+ error_t err2;
+
/* Remove it from the pending list. */
- ihash_locp_remove (pending_users, u->locp);
+ hurd_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. */
+ /* Found it! */
user = u->user;
- ports_port_ref (user);
+
+ mutex_unlock (&pending_lock);
+
+ /* Tell third party. */
+ err2 = 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);
+
+ if (err2)
+ mach_port_deallocate (mach_task_self (), reply);
+
+ mutex_lock (&pending_lock);
/* 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;
+ mutex_unlock (&pending_lock);
- /* The user RPC has set the port (with a ref) and signalled S.wakeup. */
- user = s.user;
- }
+ if (err)
+ return err;
- /* 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;
@@ -444,8 +475,9 @@ main (int argc, char **argv)
process_t proc;
mach_port_t hostpriv, masterdev;
struct authhandle *firstauth;
+ struct argp argp = { 0, 0, 0, "Hurd standard authentication server." };
- argp_parse (0, argc, argv, 0, 0, 0);
+ argp_parse (&argp, argc, argv, 0, 0, 0);
auth_bucket = ports_create_bucket ();
authhandle_portclass = ports_create_class (&destroy_authhandle, 0);
@@ -460,16 +492,21 @@ main (int argc, char **argv)
idvec_merge (&firstauth->agids, &firstauth->auids);
/* Fetch our bootstrap port and contact the bootstrap filesystem. */
- task_get_bootstrap_port (mach_task_self (), &boot);
- startup_authinit (boot, ports_get_right (firstauth),
- MACH_MSG_TYPE_MAKE_SEND, &proc);
+ 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_RELEASE, AUTH_VERSION);
+ 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);
+ _hurd_proc_init (argv, NULL, 0);
/* Init knows intimately that we will be ready for messages
as soon as this returns. */
@@ -478,16 +515,9 @@ main (int argc, char **argv)
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, MACH_PORT_NULL);
+ 30 * 1000, 0, 0);
}