summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/addauth.c392
-rw-r--r--utils/su.c483
2 files changed, 52 insertions, 823 deletions
diff --git a/utils/addauth.c b/utils/addauth.c
index fe5b5263..4cf221cf 100644
--- a/utils/addauth.c
+++ b/utils/addauth.c
@@ -1,4 +1,4 @@
-/* Add a user to some process(es)
+/* Add authentication to selected processes
Copyright (C) 1997 Free Software Foundation, Inc.
@@ -18,379 +18,87 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* XXX NOTE: This program is a real hack job, with large chunks of code cut
- out of ps and login; the code should be shared in some fashion instead. */
-
-#include <hurd.h>
#include <stdio.h>
#include <stdlib.h>
-#include <assert.h>
#include <string.h>
-#include <ctype.h>
#include <unistd.h>
#include <argp.h>
-#include <pwd.h>
-#include <grp.h>
#include <idvec.h>
-#include <ps.h>
+#include <ugids.h>
#include <error.h>
+#include <hurd.h>
#include <version.h>
-#include "parse.h"
+#include "frobauth.h"
-const char *argp_program_version = STANDARD_HURD_VERSION (ps);
-
-#define OA OPTION_ARG_OPTIONAL
-
-static const struct argp_option options[] =
-{
- {0,0,0,0, "Which ids to add:"},
- {"user", 'u', "USER", 0, "Add USER to the effective uids"},
- {"avail-user",'U', "USER", 0, "Add USER to the available uids"},
- {"group", 'g', "GROUP", 0, "Add GROUP to the effective groups"},
- {"avail-group",'G',"GROUP", 0, "Add GROUP to the available groups"},
+const char *argp_program_version = STANDARD_HURD_VERSION (addauth);
- {0,0,0,0, "Whic processes to add to:"},
- {"login", 'L', "LID", OA, "Processes from the login"
- " collection LID (which defaults that of"
- " the current process)"},
- {"lid", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
- {"pid", 'p', "PID", 0, "The process PID"},
- {"pgrp", 'P', "PGRP", 0, "Processes in process group PGRP"},
- {"session", 'S', "SID", OA, "Processes from the session SID"
- " (which defaults to the sid of the"
- " current process)"},
- {"sid", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
- {0, 0}
-};
-
-char *args_doc = "USER...";
-char *doc =
-"Add USER to the userids of the selected processes"
-"\vBy default, all processes in the current login collection are selected";
-
-static process_t proc_server;
-
-/* Returns our session id. */
-static pid_t
-current_sid()
-{
- pid_t sid;
- error_t err = proc_getsid(proc_server, getpid(), &sid);
- if (err)
- error(2, err, "Couldn't get current session id");
- return sid;
-}
+static struct argp_child child_argps[] = {{ &frobauth_ea_argp }, { 0 }};
-/* Returns our login collection id. */
-static pid_t
-current_lid()
-{
- pid_t lid;
- error_t err = proc_getloginid(proc_server, getpid(), &lid);
- if (err)
- error(2, err, "Couldn't get current login collection") ;
- return lid;
-}
+static char doc[] =
+ "Add new user/group ids to the authentication of selected processes";
-/* Returns the UID for the user called NAME. */
-static int
-lookup_user(const char *name)
-{
- struct passwd *pw = getpwnam(name);
- if (pw == NULL)
- error(2, 0, "%s: Unknown user", name);
- return pw->pw_uid;
-}
+extern error_t
+get_nonsugid_ids (struct idvec *uids, struct idvec *gids);
void
main (int argc, char *argv[])
{
-int i;
+ int i;
error_t err;
- struct proc_stat_list *procset;
- struct ps_context *context;
- struct idvec *eff_uids = make_idvec (); /* The UIDs of the new shell. */
- struct idvec *eff_gids = make_idvec (); /* The EFF_GIDs. */
- struct idvec *avail_uids = make_idvec (); /* The aux UIDs of the new shell. */
- struct idvec *avail_gids = make_idvec (); /* The aux EFF_GIDs. */
- struct idvec *parent_uids = make_idvec (); /* Parent uids, -SETUID. */
- struct idvec *parent_gids = make_idvec (); /* Parent gids, -SETGID. */
- auth_t auth, parent_auth = getauth ();
-
- /* Add a specific process to be printed out. */
- void add_pid (unsigned pid)
- {
- struct proc_stat *ps;
-
- err = proc_stat_list_add_pid (procset, pid, &ps);
- if (err)
- error (2, err, "%d: Cannot add process", pid);
-
- /* See if this process actually exists. */
- proc_stat_set_flags (ps, PSTAT_PROC_INFO);
- if (! proc_stat_has (ps, PSTAT_PROC_INFO))
- error (99, 0, "%d: Unknown process", pid);
- }
- /* Print out all process from the given session. */
- void add_sid(unsigned sid)
- {
- err = proc_stat_list_add_session (procset, sid, 0, 0);
- if (err)
- error(2, err, "%u: Cannot add session", sid);
- }
- /* Print out all process from the given login collection. */
- void add_lid(unsigned lid)
- {
- error_t err = proc_stat_list_add_login_coll (procset, lid, 0, 0);
- if (err)
- error(2, err, "%u: Cannot add login collection", lid);
- }
- /* Print out all process from the given process group. */
- void add_pgrp(unsigned pgrp)
- {
- error_t err = proc_stat_list_add_pgrp (procset, pgrp, 0, 0);
- if (err)
- error(2, err, "%u: Cannot add process group", pgrp);
- }
-
- /* Make sure that the parent_[ug]ids are filled in. To make them useful
- for su'ing, each is the avail ids with all effective ids but the first
- appended; this gets rid of the effect of login being suid, and is useful
- as the new process's avail id list (e.g., the real id is right). */
- void need_parent_ids ()
- {
- if (parent_uids->num == 0 && parent_gids->num == 0)
- {
- struct idvec *p_eff_uids = make_idvec ();
- struct idvec *p_eff_gids = make_idvec ();
- if (!p_eff_uids || !p_eff_gids)
- err = ENOMEM;
- if (! err)
- err = idvec_merge_auth (p_eff_uids, parent_uids,
- p_eff_gids, parent_gids,
- parent_auth);
- if (! err)
- {
- idvec_delete (p_eff_uids, 0); /* Counteract setuid. */
- idvec_delete (p_eff_gids, 0);
- err = idvec_merge (parent_uids, p_eff_uids);
- if (! err)
- err = idvec_merge (parent_gids, p_eff_gids);
- }
- if (err)
- error (39, err, "Cannot get uids");
- }
- }
-
- /* Returns true if the *caller* of this login program has UID. */
- int parent_has_uid (uid_t uid)
- {
- need_parent_ids ();
- return idvec_contains (parent_uids, uid);
- }
- /* Returns true if the *caller* of this login program has GID. */
- int parent_has_gid (gid_t gid)
- {
- need_parent_ids ();
- return idvec_contains (parent_gids, gid);
- }
- /* Returns the number of parent uids. */
- int count_parent_uids ()
- {
- need_parent_ids ();
- return parent_uids->num;
- }
- /* Returns the number of parent gids. */
- int count_parent_gids ()
- {
- need_parent_ids ();
- return parent_gids->num;
- }
-
- /* Make sure the user should be allowed to do this. */
- void verify_passwd (const char *name, const char *password,
- uid_t id, int is_group)
- {
- extern char *crypt (const char *string, const char salt[2]);
-#ifndef HAVE_CRYPT
-#pragma weak crypt
-#endif
- char *prompt, *unencrypted, *encrypted;
-
- if (!password || !*password
- || idvec_contains (is_group ? eff_gids : eff_uids, id)
- || idvec_contains (is_group ? avail_gids : avail_uids, id)
- || parent_has_uid (0)
- || (is_group ? parent_has_uid (id) : parent_has_gid (id)))
- return; /* Already got this one. */
+ auth_t auth;
+ char *ids_rep = 0;
+ process_t proc_server = getproc();
+ struct frobauth frobauth = FROBAUTH_INIT;
+ struct idvec have_uids = IDVEC_INIT, have_gids = IDVEC_INIT;
+ struct argp argp = { 0, 0, 0, doc, child_argps };
- if (name)
- asprintf (&prompt, "Password for %s%s:",
- is_group ? "group " : "", name);
- else
- prompt = "Password:";
-
- unencrypted = getpass (prompt);
- if (name)
- free (prompt);
-
- if (crypt)
- {
- encrypted = crypt (unencrypted, password);
- if (! encrypted)
- /* Something went wrong. */
- {
- /* Paranoia may destroya. */
- memset (unencrypted, 0, strlen (unencrypted));
- error (51, errno, "Password encryption failed");
- }
- }
- else
- encrypted = unencrypted;
+ frobauth.require_ids = 1;
- if (strcmp (encrypted, password) == 0)
- {
- memset (unencrypted, 0, strlen (unencrypted));
- return; /* password O.K. */
- }
+ /* Parse our command line. This shouldn't ever return an error. */
+ argp_parse (&argp, argc, argv, 0, 0, &frobauth);
- if (id == 0 && !is_group && parent_has_gid (0)
- && (parent_uids->num == 0 || parent_uids->ids[0] != 0))
- /* Special hack: a user attempting to gain root access can use
- their own password (instead of root's) if they're in group 0. */
- {
- struct passwd *pw = getpwuid (parent_uids->ids[0]);
+ /* See what the invoking user is authorized to do. */
+ err = get_nonsugid_ids (&have_uids, &have_gids);
+ if (err)
+ error (52, err, "Cannot get invoking authentication");
- encrypted = crypt (unencrypted, pw->pw_passwd);
- memset (unencrypted, 0, strlen (unencrypted));
+ /* Check passwords. */
+ err = ugids_verify (&frobauth.ugids, &have_uids, &have_gids, 0);
+ if (err == EINVAL)
+ error (15, 0, "Invalid password");
+ else if (err)
+ error (16, err, "Cannot verify authentication");
- if (pw && strcmp (encrypted, pw->pw_passwd) == 0)
- return;
- }
+ /* Make an auth port with the new ids. */
+ err = ugids_make_auth (&frobauth.ugids, MACH_PORT_NULL, &auth);
+ if (err)
+ error (3, err, "Authentication failure");
- memset (unencrypted, 0, strlen (unencrypted));
- error (50, 0, "Incorrect password");
- }
+ if (frobauth.verbose)
+ /* A string showing which ids we will add. */
+ ids_rep = ugids_rep (&frobauth.ugids, 1, 1, 0, 0, 0);
- error_t parse_opt (int key, char *arg, struct argp_state *state)
+ /* Add the new authentication to each process. */
+ for (i = 0; i < frobauth.num_pids; i++)
{
- switch (key)
- {
- case 'p':
- parse_numlist(arg, add_pid, NULL, NULL, "process id");
- break;
- case 'S':
- parse_numlist(arg, add_sid, current_sid, NULL, "session id");
- break;
- case 'L':
- parse_numlist(arg, add_lid, current_lid, NULL, "login collection");
- break;
- case 'P':
- parse_numlist(arg, add_pgrp, NULL, NULL, "process group");
- break;
+ mach_port_t msgport;
+ pid_t pid = frobauth.pids[i];
+ error_t err = proc_getmsgport (proc_server, pid, &msgport);
- case 'u':
- case 'U':
- case ARGP_KEY_ARG:
- {
- struct passwd *pw =
- isdigit (*arg) ? getpwuid (atoi (arg)) : getpwnam (arg);
- /* True if this is the user arg and there were no user options. */
- int only_user =
- (key == ARGP_KEY_ARG
- && eff_uids->num == 0 && avail_uids->num <= count_parent_uids ()
- && eff_gids->num == 0 && avail_gids->num <= count_parent_gids ());
-
- if (! pw)
- argp_failure (state, 10, 0, "%s: Unknown user", arg);
-
- /* If it's not nobody, make sure we're authorized. */
- verify_passwd (only_user ? 0 : pw->pw_name, pw->pw_passwd,
- pw->pw_uid, 0);
-
- if (key == 'U')
- /* Add available ids instead of effective ones. */
- idvec_add_new (avail_uids, pw->pw_uid);
- else
- idvec_add_new (eff_uids, pw->pw_uid);
- }
- break;
-
- case 'g':
- case 'G':
- {
- struct group *gr =
- isdigit (*arg) ? getgrgid (atoi (arg)) : getgrnam (arg);
- if (! gr)
- argp_failure (state, 11, 0, "%s: Unknown group", arg);
- verify_passwd (gr->gr_name, gr->gr_passwd, gr->gr_gid, 1);
- idvec_add_new (key == 'g' ? eff_gids : avail_gids, gr->gr_gid);
- }
- break;
-
- default:
- return ARGP_ERR_UNKNOWN;
- }
- return 0;
- }
- error_t frob_proc (struct proc_stat *ps)
- {
- printf ("Frobbing pid %d\n", ps->pid);
- if (! (ps->flags & PSTAT_MSGPORT))
- error (0, 0, "%d: Cannot get message port", ps->pid);
+ if (err)
+ error (0, err, "%d: Cannot get message port", pid);
else
{
- error_t err = msg_add_auth (ps->msgport, auth);
+ if (! frobauth.dry_run)
+ err = msg_add_auth (msgport, auth);
if (err)
- error (0, err, "%d: Cannot add authentication", ps->pid);
+ error (0, err, "%d: Cannot add authentication", pid);
+ else if (frobauth.verbose)
+ printf ("%d: Added %s\n", pid, ids_rep);
+ mach_port_deallocate (mach_task_self (), msgport);
}
- return 0;
}
- struct argp argp = { options, parse_opt, args_doc, doc};
-
- proc_server = getproc();
-
- err = ps_context_create (proc_server, &context);
- if (err)
- error(1, err, "ps_context_create");
-
- err = proc_stat_list_create(context, &procset);
- if (err)
- error(1, err, "proc_stat_list_create");
-
- /* Parse our command line. This shouldn't ever return an error. */
- argp_parse (&argp, argc, argv, 0, 0, 0);
-
- if (procset->num_procs == 0)
- /* By default, do the current login collection. */
- add_lid (current_lid ());
-
- printf ("Adding euids:");
- for (i = 0; i < eff_uids->num; i++) printf (" %d", eff_uids->ids[i]);
- putchar ('\n');
- printf ("Adding egids:");
- for (i = 0; i < eff_gids->num; i++) printf (" %d", eff_gids->ids[i]);
- putchar ('\n');
- printf ("Adding auids:");
- for (i = 0; i < avail_uids->num; i++) printf (" %d", avail_uids->ids[i]);
- putchar ('\n');
- printf ("Adding agids:");
- for (i = 0; i < avail_gids->num; i++) printf (" %d", avail_gids->ids[i]);
- putchar ('\n');
- err =
- auth_makeauth (getauth (), 0, MACH_MSG_TYPE_COPY_SEND, 0,
- eff_uids->ids, eff_uids->num,
- avail_uids->ids, avail_uids->num,
- eff_gids->ids, eff_gids->num,
- avail_gids->ids, avail_gids->num,
- &auth);
- if (err)
- error (3, err, "Authentication failure");
-
- proc_stat_list_set_flags (procset, PSTAT_TASK | PSTAT_MSGPORT);
- proc_stat_list_for_each (procset, frob_proc);
-
exit (0);
}
diff --git a/utils/su.c b/utils/su.c
index de12917e..53563fa3 100644
--- a/utils/su.c
+++ b/utils/su.c
@@ -1,481 +1,2 @@
-/* `su' for GNU Hurd.
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
- 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 the GNU Hurd; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Unlike Unix su, this program does not spawn a subshell. Instead, it
- adds or removes (with the -r flag) auth rights to all the processes in
- the current login. Note that the addition and removal of rights to a
- particular process is voluntary; the process doesn't get them unless
- it's listening for the right rpc (which the C library normally does),
- and it doesn't have to release any of the rights it has when requested
- (though the C library does this automatically in most programs).
-
- The -r flag allows you to easily be authorized or not authorized for any
- number of users (uids and gid sets). This program is not intelligent,
- however. The -r flag always removes whatever gids the specified user
- has. If some other user you have obtained authorization for has some of
- the same gids, it will remove them. The C library could be intelligent
- enough to look up the groups of all the uids it has, and make sure it
- has at least those. */
-
-#include <stdlib.h>
-#include <hurd.h>
-#include <pwd.h>
-#include <grp.h>
-#include <termios.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <getopt.h>
-#include <hurd/msg.h>
-#include <assert.h>
-
-process_t proc; /* Our proc server port. */
-
-/* Command line flags. */
-int remove_ids = 0; /* -r: Remove ids instead of adding them. */
-
-const struct option longopts[] =
- {
- { "remove", 0, 0, 'r' },
- { "uid", 0, 0, 'u' },
- { "gid", 0, 0, 'g' },
- { "loginuser", 0, 0, 'l' },
- { "pid", 0, 0, 'p' },
- { "pgrp", 0, 0, 'G' },
- { "loginid", 0, 0, 'i' },
- { 0, }
- };
-
-struct auth
- {
- unsigned int *ids;
- auth_t authport;
- };
-
-/* These functions return a malloc'd array of ids that can be passed to
- make_auth_handle or used in del_auth messages. They check authorization
- and return NULL on failure. */
-unsigned int *get_uid (const char *user); /* From a named user or UID. */
-unsigned int *get_gid (const char *user); /* From a named group or GID. */
-unsigned int *get_user (const char *user); /* All ids for a named user. */
-
-int apply_auth (struct auth *auth, pid_t, int);
-int apply_auth_to_pids (struct auth *auth, unsigned int, pid_t *, int);
-int apply_auth_to_pgrp (struct auth *auth, pid_t);
-int apply_auth_to_loginid (struct auth *auth, int);
-
-int check_password (const char *name, const char *password);
-
-
-int
-main (int argc, char **argv)
-{
- int c;
- int status;
- enum { user, group, loginuser, loginid, pid, pgrp } mode = loginuser;
- struct auth auth[argc];
- unsigned int authidx = 0, loginidx = 0, pididx = 0, pgrpidx = 0;
- int loginids[argc];
- pid_t pids[argc], pgrps[argc];
- unsigned int i, j;
-
- proc = getproc (); /* Used often. */
-
- while ((c = getopt_long (argc, argv, "--rgulpiG", longopts, NULL)) != EOF)
- switch (c)
- {
- case 'r':
- remove_ids = 1;
- break;
-
- case 'u':
- mode = user;
- break;
- case 'g':
- mode = group;
- break;
- case 'l':
- mode = loginuser;
- break;
- case 'p':
- mode = pid;
- break;
- case 'i':
- mode = loginid;
- break;
- case 'G':
- mode = pgrp;
- break;
-
- case 1: /* Non-option argument. */
- switch (mode)
- {
- case user:
- auth[authidx++].ids = get_uid (optarg);
- break;
- case group:
- auth[authidx++].ids = get_gid (optarg);
- break;
- case loginuser:
- auth[authidx++].ids = get_user (optarg);
- break;
-
- case pid:
- pids[pididx++] = atoi (optarg);
- break;
- case loginid:
- loginids[loginidx++] = atoi (optarg);
- break;
- case pgrp:
- pgrps[pgrpidx++] = atoi (optarg);
- break;
- }
- break;
-
- case '?':
- default:
- fprintf (stderr, "Usage: %s [-r|--remove]\n\
- [-u|--uid UID...] [-g|--gid GID...] [-l|--loginuser USER...]\n\
- [-p|--pid PID...] [-i|--loginid ID...] [-G|--pgrp PGRP...]\n",
- program_invocation_short_name);
- exit (1);
- }
-
- if (authidx == 0)
- /* No ids specified; default is "su root". */
- auth[authidx++].ids = get_user ("root");
-
- if (pididx == 0 && loginidx == 0 && pgrpidx == 0)
- {
- /* No processes specified; default is current login collection. */
- errno = proc_getloginid (proc, getpid (), &loginids[loginidx++]);
- if (errno)
- {
- perror ("proc_getloginid");
- return 1;
- }
- }
-
- status = 0;
-
- if (! remove_ids)
- for (i = 0; i < authidx; ++i)
- {
- struct auth *a = &auth[i];
- errno = auth_makeauth (getauth (), NULL, MACH_MSG_TYPE_COPY_SEND, 0,
- &a->ids[1], a->ids[0], NULL, 0,
- &a->ids[1 + a->ids[0] + 1],
- a->ids[1 + a->ids[0]], NULL, 0, &a->authport);
- if (errno)
- {
- perror ("auth_makeauth");
- status = 1;
- }
- }
-
- for (j = 0; j < authidx; ++j)
- status |= apply_auth_to_pids (&auth[j], pididx, pids, 0);
-
- for (i = 0; i < loginidx; ++i)
- {
- for (j = 0; j < authidx; ++j)
- status |= apply_auth_to_loginid (&auth[j], loginids[i]);
- }
-
- for (i = 0; i < pgrpidx; ++i)
- {
- for (j = 0; j < authidx; ++j)
- status |= apply_auth_to_loginid (&auth[j], pgrps[i]);
- }
-
-
- return status;
-}
-
-/* Turn USER into a list of ids, giving USER's primary uid and gid from the
- passwd file and all the groups that USER appears in in the group file. */
-
-unsigned int *
-get_user (const char *user)
-{
- struct passwd *p;
- unsigned int ngids, *ids;
-
- p = getpwnam (user);
- if (p == NULL)
- {
- fprintf (stderr, "%s: User `%s' not found\n",
- program_invocation_short_name, user);
- return NULL;
- }
-
- if (! check_password (user, p->pw_passwd))
- return NULL;
-
- /* We don't need to change our own gids, but it doesn't really hurt,
- and initgroups does all the work for us. */
- if (initgroups (user, p->pw_gid) < 0)
- {
- perror ("initgroups");
- return NULL;
- }
- ngids = getgroups (0, NULL);
- if ((int) ngids < 0)
- {
- getgroups_lost:
- perror ("getgroups");
- return NULL;
- }
- assert (sizeof (*ids) == sizeof (gid_t));
- ids = malloc ((3 + ngids) * sizeof (*ids));
- ids[0] = 1;
- ids[1] = p->pw_uid;
- ids[2] = getgroups (ngids, &ids[3]);
- if ((int) ids[2] < 0)
- goto getgroups_lost;
-
- return ids;
-}
-
-/* Return an id list containing just the uid of USER. */
-
-unsigned int *
-get_uid (const char *user)
-{
- struct passwd *p;
- unsigned int *ids;
- uid_t uid;
- char *uend;
-
- uid = strtoul (user, &uend, 10);
- if (uend && *uend == '\0')
- {
- if (remove_ids || getuid () == 0)
- /* No need to verify. */
- p = NULL;
- else
- {
- p = getpwuid (uid);
- if (p == NULL)
- {
- fprintf (stderr, "%s: UID %u not found\n",
- program_invocation_short_name, uid);
- return NULL;
- }
- }
- }
- else
- {
- p = getpwnam (user);
- if (p == NULL)
- {
- fprintf (stderr, "%s: User `%s' not found\n",
- program_invocation_short_name, user);
- return NULL;
- }
- }
-
- if (p != NULL && ! check_password (user, p->pw_passwd))
- return NULL;
-
- ids = malloc (3 * sizeof (*ids));
- ids[0] = 1;
- ids[1] = p->pw_uid;
- ids[2] = 0;
-
- return ids;
-}
-
-/* Return an id list containing just the gid of GROUP. */
-
-unsigned int *
-get_gid (const char *group)
-{
- struct group *g;
- unsigned int *ids;
- gid_t gid;
- char *gend;
-
- gid = strtoul (group, &gend, 10);
- if (gend && *gend == '\0')
- {
- if (remove_ids || getuid () == 0)
- /* No need to verify. */
- g = NULL;
- else
- {
- g = getgrgid (gid);
- if (g == NULL)
- {
- fprintf (stderr, "%s: GID %u not found\n",
- program_invocation_short_name, gid);
- return NULL;
- }
- }
- }
- else
- {
- g = getgrnam (group);
- if (g == NULL)
- {
- fprintf (stderr, "%s: Group `%s' not found\n",
- program_invocation_short_name, group);
- return NULL;
- }
- }
-
- if (g != NULL && ! check_password (group, g->gr_passwd))
- return NULL;
-
- ids = malloc (3 * sizeof (*ids));
- ids[0] = 0;
- ids[1] = 1;
- ids[2] = g->gr_gid;
-
- return ids;
-}
-
-/* Add or delete (under -r) the ids indicated by AUTH to/from PID. If
- IGNORE_BAD_PID is nonzero, return success if PID does not exist.
- Returns zero if successful, nonzero on error (after printing message). */
-
-int
-apply_auth (struct auth *auth, pid_t pid, int ignore_bad_pid)
-{
- error_t err;
-
- if (! auth->ids)
- return 0;
-
- err = HURD_MSGPORT_RPC (proc_getmsgport (proc, pid, &msgport),
- proc_pid2task (proc, pid, &refport), 1,
- remove_ids ?
- msg_del_auth (msgport, refport,
- &auth->ids[1], auth->ids[0],
- &auth->ids[1 + auth->ids[0] + 1],
- auth->ids[1 + auth->ids[0]]) :
- msg_add_auth (msgport, auth->authport));
- if (err &&
- (!ignore_bad_pid || (err != ESRCH && err != MIG_SERVER_DIED)))
- {
- fprintf (stderr, "%s: error in %s_auth from PID %d: %s\n",
- program_invocation_short_name,
- remove_ids ? "del" : "add", pid, strerror (err));
- return 1;
- }
- else
- return 0;
-}
-
-int
-apply_auth_to_pids (struct auth *auth, unsigned int npids, pid_t pids[],
- int ignore_bad_pid)
-{
- int status = 0;
- unsigned int i;
-
- for (i = 0; i < npids; ++i)
- status |= apply_auth (auth, pids[i], ignore_bad_pid);
-
- return status;
-}
-
-int
-apply_auth_to_loginid (struct auth *auth, int loginid)
-{
- unsigned int npids = 20;
- pid_t pidbuf[20], *pids = pidbuf;
- int status;
- error_t err;
-
- err = proc_getloginpids (proc, loginid, &pids, &npids);
- if (err)
- {
- fprintf (stderr, "%s: proc_getloginpids failed for loginid %d: %s\n",
- program_invocation_short_name, loginid, strerror (err));
- return 1;
- }
-
- status = apply_auth_to_pids (auth, npids, pids, 1);
-
- if (pids != pidbuf)
- vm_deallocate (mach_task_self (),
- (vm_address_t) pids, npids * sizeof (pid_t));
-
- return status;
-}
-
-int
-apply_auth_to_pgrp (struct auth *auth, pid_t pgrp)
-{
- unsigned int npids = 20;
- pid_t pidbuf[20], *pids = pidbuf;
- int status;
- error_t err;
-
- err = proc_getpgrppids (proc, pgrp, &pids, &npids);
- if (err)
- {
- fprintf (stderr, "%s: proc_getpgrppids failed for pgrp %d: %s\n",
- program_invocation_short_name, pgrp, strerror (err));
- return 1;
- }
-
- status = apply_auth_to_pids (auth, npids, pids, 1);
-
- if (pids != pidbuf)
- vm_deallocate (mach_task_self (),
- (vm_address_t) pids, npids * sizeof (pid_t));
-
- return status;
-}
-
-/* Return 1 if the user gives the correct password matching the encrypted
- string PASSWORD, 0 if not. Return 1 without asking for a password if
- run by uid 0 or if PASSWORD is an empty password, and always under -r.
- Always prints a message before returning 0. */
-int
-check_password (const char *name, const char *password)
-{
- extern char *crypt (const char *string, const char salt[2]);
-#pragma weak crypt
- char *unencrypted, *encrypted;
- static char *prompt = NULL;
-
- if (remove_ids || getuid () == 0 || password == NULL || password[0] == '\0')
- return 1;
-
- asprintf (&prompt, "%s's Password:", name);
- unencrypted = getpass (prompt);
- if (crypt)
- {
- encrypted = crypt (unencrypted, password);
- memset (unencrypted, 0, strlen (unencrypted)); /* Paranoia may destroya. */
- }
- else
- encrypted = unencrypted;
-
- if (!strcmp (encrypted, password))
- return 1;
-
- fprintf (stderr, "%s: Access denied for `%s'\n",
- program_invocation_short_name, name);
- return 0;
-}
+#define SU
+#include "setauth.c"