diff options
author | Miles Bader <miles@gnu.org> | 1997-05-26 23:30:36 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1997-05-26 23:30:36 +0000 |
commit | 45e6c096327167a10796d454fa556ac29be23372 (patch) | |
tree | eda591bfbb00fda60d6babeaf0a173859b1c2cd7 | |
parent | b2777dd5ad21289a7cf3776d4185d9a31997ed00 (diff) |
Totally rewritten.
-rw-r--r-- | utils/addauth.c | 392 | ||||
-rw-r--r-- | utils/su.c | 483 |
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); } @@ -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" |