diff options
author | Thomas Bushnell <thomas@gnu.org> | 1999-04-26 01:40:32 +0000 |
---|---|---|
committer | Thomas Bushnell <thomas@gnu.org> | 1999-04-26 01:40:32 +0000 |
commit | ba43ec407a7377814ae923c6c3d3c358edbd1f35 (patch) | |
tree | 7d401a3ebc13032af111c2918df6700b2627d657 | |
parent | 6ac4feb602d86010c815100e2b02a8ec60d01929 (diff) |
1999-02-20 Mark Kettenis <kettenis@gnu.org>
* password.c: New file.
* Makefile (targets): Add password.
(SRCS): Add password.c.
(OBJS): Add passwordServer.o.
(password-LDLIBS): New variable.
Use dependencies identical to those for crash.
-rw-r--r-- | trans/ChangeLog | 9 | ||||
-rw-r--r-- | trans/Makefile | 10 | ||||
-rw-r--r-- | trans/password.c | 225 |
3 files changed, 240 insertions, 4 deletions
diff --git a/trans/ChangeLog b/trans/ChangeLog index 14dee01f..b363e789 100644 --- a/trans/ChangeLog +++ b/trans/ChangeLog @@ -1,3 +1,12 @@ +1999-02-20 Mark Kettenis <kettenis@gnu.org> + + * password.c: New file. + * Makefile (targets): Add password. + (SRCS): Add password.c. + (OBJS): Add passwordServer.o. + (password-LDLIBS): New variable. + Use dependencies identical to those for crash. + 1998-10-20 Roland McGrath <roland@baalperazim.frob.com> * fifo.c (open_hook: WAIT): Add braces to silence gcc warning. diff --git a/trans/Makefile b/trans/Makefile index e383a29d..e698f7ae 100644 --- a/trans/Makefile +++ b/trans/Makefile @@ -18,19 +18,21 @@ dir := trans makemode := servers -targets = symlink firmlink ifsock magic null fifo new-fifo fwd crash +targets = symlink firmlink ifsock magic null fifo new-fifo fwd crash password SRCS = ifsock.c symlink.c magic.c null.c fifo.c new-fifo.c fwd.c \ - crash.c firmlink.c -OBJS = $(SRCS:.c=.o) fsysServer.o ifsockServer.o + crash.c firmlink.c password.c +OBJS = $(SRCS:.c=.o) fsysServer.o ifsockServer.o passwordServer.o HURDLIBS=ports trivfs threads fshelp pipe ihash shouldbeinlibc +password-LDLIBS = $(LIBCRYPT) include ../Makeconf symlink magic: fsysServer.o ifsock: ifsockServer.o crash: crashServer.o crash_replyUser.o msgServer.o +password: passwordServer.o -crash: ../libports/libports.a ../libtrivfs/libtrivfs.a ../libthreads/libthreads.a ../libfshelp/libfshelp.a +crash password: ../libports/libports.a ../libtrivfs/libtrivfs.a ../libthreads/libthreads.a ../libfshelp/libfshelp.a fifo new-fifo: ../libpipe/libpipe.a fwd new-fifo: ../libfshelp/libfshelp.a ../libports/libports.a null ifsock fifo new-fifo firmlink: ../libtrivfs/libtrivfs.a ../libfshelp/libfshelp.a ../libports/libports.a ../libihash/libihash.a diff --git a/trans/password.c b/trans/password.c new file mode 100644 index 00000000..f7414aab --- /dev/null +++ b/trans/password.c @@ -0,0 +1,225 @@ +/* Hurd standard password server. + Copyright (C) 1999 Free Software Foundation + Written by Mark Kettenis. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include <argp.h> +#include <assert.h> +#include <errno.h> +#include <error.h> +#include <stdlib.h> +#include <string.h> + +#include <hurd.h> +#include <hurd/auth.h> +#include <hurd/ports.h> +#include <hurd/trivfs.h> + +#include <ugids.h> +#include <version.h> + +#include "password_S.h" + + +const char *argp_program_version = STANDARD_HURD_VERSION (password); + +/* Port bucket we service requests on. */ +struct port_bucket *port_bucket; + +/* Trivfs hooks. */ +int trivfs_fstype = FSTYPE_MISC; +int trivfs_fsid = 0; +int trivfs_support_read = 0; +int trivfs_support_write = 0; +int trivfs_support_exec = 0; +int trivfs_allow_open = 0; + +struct port_class *trivfs_protid_portclasses[1]; +struct port_class *trivfs_cntl_portclasses[1]; +int trivfs_protid_nportclasses = 1; +int trivfs_cntl_nportclasses = 1; + + +static int +password_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp) +{ + extern int password_server (mach_msg_header_t *inp, mach_msg_header_t *outp); + return password_server (inp, outp) || trivfs_demuxer (inp, outp); +} + + +int +main (int argc, char *argv[]) +{ + error_t err; + mach_port_t bootstrap; + struct trivfs_control *fsys; + const struct argp argp = { 0, 0, 0, "Hurd standard password server" }; + + argp_parse (&argp, argc, argv, 0, 0, 0); + + task_get_bootstrap_port (mach_task_self (), &bootstrap); + if (bootstrap == MACH_PORT_NULL) + error (1, 0, "must be started as a translator"); + + port_bucket = ports_create_bucket (); + trivfs_cntl_portclasses[0] = ports_create_class (trivfs_clean_cntl, 0); + trivfs_protid_portclasses[0] = ports_create_class (trivfs_clean_protid, 0); + + /* Reply to our parent. */ + err = trivfs_startup (bootstrap, 0, + trivfs_cntl_portclasses[0], port_bucket, + trivfs_protid_portclasses[0], port_bucket, + &fsys); + mach_port_deallocate (mach_task_self (), bootstrap); + if (err) + error (3, err, "Contacting parent"); + + /* Launch. */ + do + ports_manage_port_operations_multithread (port_bucket, password_demuxer, + 2 * 60 * 1000, + 10 * 60 * 1000, + 0); + /* That returns when 10 minutes pass without an RPC. Try shutting down + as if sent fsys_goaway; if we have any users who need us to stay + around, this returns EBUSY and we loop to service more RPCs. */ + while (trivfs_goaway (fsys, 0)); + + return 0; +} + + +void +trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st) +{ + st->st_fstype = FSTYPE_MISC; +} + +error_t +trivfs_goaway (struct trivfs_control *fsys, int flags) +{ + int count; + + /* Stop new requests. */ + ports_inhibit_class_rpcs (trivfs_cntl_portclasses[0]); + ports_inhibit_class_rpcs (trivfs_protid_portclasses[0]); + + /* Are there any extant user ports for the /servers/password file? */ + count = ports_count_class (trivfs_protid_portclasses[0]); + if (count > 0 && !(flags & FSYS_GOAWAY_FORCE)) + { + /* We won't go away, so start things going again... */ + ports_enable_class (trivfs_protid_portclasses[0]); + ports_resume_class_rpcs (trivfs_cntl_portclasses[0]); + ports_resume_class_rpcs (trivfs_protid_portclasses[0]); + + return EBUSY; + } + + exit (0); +} + + +/* Implement password_check_user as described in <hurd/password.defs>. */ +kern_return_t +S_password_check_user (io_t server, uid_t user, char *pw, + mach_port_t *port, mach_msg_type_name_t *port_type) +{ + struct trivfs_protid *cred; + struct ugids ugids = UGIDS_INIT; + auth_t auth; + error_t err; + + char *getpass (const char *prompt, uid_t id, int is_group, + void *pwd_or_group, void *hook) + { + assert (! is_group && id == user); + return strdup (pw); + } + + cred = ports_lookup_port (port_bucket, server, trivfs_protid_portclasses[0]); + if (! cred) + return EOPNOTSUPP; + + /* Verify password. */ + err = ugids_add_user (&ugids, user, 1); + if (!err) + err = ugids_verify (&ugids, 0, 0, getpass, 0, 0, 0); + + if (!err) + { + auth = getauth (); + err = auth_makeauth (auth, 0, MACH_MSG_TYPE_COPY_SEND, 0, + ugids.eff_uids.ids, ugids.eff_uids.num, + ugids.avail_uids.ids, ugids.avail_uids.num, + ugids.eff_gids.ids, ugids.eff_gids.num, + ugids.avail_gids.ids, ugids.avail_gids.num, + port); + mach_port_deallocate (mach_task_self (), auth); + *port_type = MACH_MSG_TYPE_MOVE_SEND; + } + + ugids_fini (&ugids); + + ports_port_deref (cred); + return err; +} + +/* Implement password_check_group as described in <hurd/password.defs>. */ +kern_return_t +S_password_check_group (io_t server, uid_t group, char *pw, + mach_port_t *port, mach_msg_type_name_t *port_type) +{ + struct trivfs_protid *cred; + struct ugids ugids = UGIDS_INIT; + auth_t auth; + error_t err; + + char *getpass (const char *prompt, uid_t id, int is_group, + void *pwd_or_group, void *hook) + { + assert (is_group && id == group); + return strdup (pw); + } + + cred = ports_lookup_port (port_bucket, server, trivfs_protid_portclasses[0]); + if (! cred) + return EOPNOTSUPP; + + /* Verify password. */ + err = ugids_add_gid (&ugids, group, 1); + if (!err) + err = ugids_verify (&ugids, 0, 0, getpass, 0, 0, 0); + + if (!err) + { + auth = getauth (); + err = auth_makeauth (auth, 0, MACH_MSG_TYPE_COPY_SEND, 0, + ugids.eff_uids.ids, ugids.eff_uids.num, + ugids.avail_uids.ids, ugids.avail_uids.num, + ugids.eff_gids.ids, ugids.eff_gids.num, + ugids.avail_gids.ids, ugids.avail_gids.num, + port); + mach_port_deallocate (mach_task_self (), auth); + *port_type = MACH_MSG_TYPE_MOVE_SEND; + } + + ugids_fini (&ugids); + + ports_port_deref (cred); + return err; +} |