diff options
author | Miles Bader <miles@gnu.org> | 1997-05-26 23:19:36 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1997-05-26 23:19:36 +0000 |
commit | fa3f1f47cbee8d8cd572f6986583c8e95f85a562 (patch) | |
tree | e7042967740a55d44b8dd873368cbb305849a10e /utils/frobauth-mod.c | |
parent | b4447ed54831cbf4b49b96ed841faaacec6e26b6 (diff) |
Initial checkin
Diffstat (limited to 'utils/frobauth-mod.c')
-rw-r--r-- | utils/frobauth-mod.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/utils/frobauth-mod.c b/utils/frobauth-mod.c new file mode 100644 index 00000000..8606e783 --- /dev/null +++ b/utils/frobauth-mod.c @@ -0,0 +1,177 @@ +/* Modify the current authentication selected processes + + Copyright (C) 1997 Free Software Foundation, Inc. + + Written by Miles Bader <miles@gnu.ai.mit.edu> + + This program 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. + + This program 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <hurd.h> +#include <error.h> + +#include "frobauth.h" + +/* For every pid in FROBAUTH, call MODIFY to change its argument UGIDS from + the current authentication to what it should be; CHANGE is whatever ids + the user specified. If the user specifies the --verbose flags, PRINT_INFO + is called after successfully installing the new authentication in each + process, to print a message about what happened. True is returned if no + errors occur, although most errors do not cause termination, and error + messages are printed for them. */ +error_t +frobauth_modify (struct frobauth *frobauth, + error_t (*modify) (struct ugids *ugids, + const struct ugids *change, + pid_t pid, void *hook), + void (*print_info) (const struct ugids *new, + const struct ugids *old, + const struct ugids *change, + pid_t pid, void *hook), + void *hook) +{ + int i; + int ok = 1; + pid_t cur_pid = getpid (); + process_t proc_server = getproc (); + + /* Map MODIFY over all pids. */ + for (i = 0; i < frobauth->num_pids; i++) + if (frobauth->pids[i] != cur_pid) + { + mach_port_t msgport; + pid_t pid = frobauth->pids[i]; + error_t err = proc_getmsgport (proc_server, pid, &msgport); + + if (err) + error (0, err, "%d: Cannot get message port", pid); + else + { + task_t task; + + err = proc_pid2task (proc_server, pid, &task); + if (err) + error (0, err, "%d", pid); + else + { + auth_t old_auth; + + err = msg_get_init_port (msgport, task, INIT_PORT_AUTH, + &old_auth); + if (err) + error (0, err, "%d: Cannot get auth port", pid); + else + { + struct ugids old = UGIDS_INIT; + + err = ugids_merge_auth (&old, old_auth); + + if (err) + error (0, err, "%d: Cannot get auth port ids", pid); + else + { + struct ugids new = UGIDS_INIT; + + /* Assume all gids that can be implied by some uid are + only present for that reason. */ + ugids_imply_all (&old); + + err = ugids_set (&new, &old); + + err = (*modify) (&new, &frobauth->ugids, pid, hook); + if (err) + error (99, err, "%d: Cannot modify ids", pid); + else if (! ugids_equal (&new, &old)) + { + if (! frobauth->dry_run) + { + auth_t new_auth; + err = + ugids_make_auth (&new, old_auth, &new_auth); + if (err) + error (0, err, + "%d: Authentication failure", pid); + else + { + err = + msg_set_init_port (msgport, task, + INIT_PORT_AUTH, + new_auth, + MACH_MSG_TYPE_MOVE_SEND); + if (err) + error (0, err, "%d", pid); + else if (new.eff_uids.num == 0 + ? old.eff_uids.num > 0 + : (old.eff_uids.num == 0 + || (new.eff_uids.ids[0] + != old.eff_uids.ids[0]))) + /* Now change the process's owner. */ + { + process_t proc; + err = + proc_pid2proc (proc_server, pid, + &proc); + if (err) + error (0, err, + "%d: Cannot get proc port", + pid); + else + { + if (new.eff_uids.num == 0) + err = + proc_setowner (proc, 0, 1); + else + err = proc_setowner + (proc, new.eff_uids.ids[0], 0); + if (err) + error + (0, err, + "%d: Cannot set process owner", + pid); + mach_port_deallocate + (mach_task_self (), proc); + } + } + } + + } + + if (frobauth->verbose && !err) + (*print_info) (&new, &old, &frobauth->ugids, + pid, hook); + + } + else if (frobauth->verbose) + printf ("%d: Nothing changed\n", pid); + + ugids_fini (&new); + } + + ugids_fini (&old); + mach_port_deallocate (mach_task_self (), old_auth); + } + mach_port_deallocate (mach_task_self (), task); + } + mach_port_deallocate (mach_task_self (), msgport); + } + + if (err) + ok = 0; /* Something didn't work. */ + } + + return ok; +} |