diff options
Diffstat (limited to 'auth')
-rw-r--r-- | auth/ChangeLog | 148 | ||||
-rw-r--r-- | auth/Makefile | 5 | ||||
-rw-r--r-- | auth/auth.c | 302 |
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); } |