summaryrefslogtreecommitdiff
path: root/utils/frobauth.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1997-05-26 23:19:36 +0000
committerMiles Bader <miles@gnu.org>1997-05-26 23:19:36 +0000
commitfa3f1f47cbee8d8cd572f6986583c8e95f85a562 (patch)
treee7042967740a55d44b8dd873368cbb305849a10e /utils/frobauth.c
parentb4447ed54831cbf4b49b96ed841faaacec6e26b6 (diff)
Initial checkin
Diffstat (limited to 'utils/frobauth.c')
-rw-r--r--utils/frobauth.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/utils/frobauth.c b/utils/frobauth.c
new file mode 100644
index 00000000..ccb7c3bb
--- /dev/null
+++ b/utils/frobauth.c
@@ -0,0 +1,282 @@
+/* Common interface for auth frobbing utilities
+
+ 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. */
+
+/* This file is rather a mess of intertwined argps; it shoud be redone as a
+ single level once argp can handle dynamic option frobbing. XXX */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <hurd.h>
+#include <hurd/process.h>
+
+#include "frobauth.h"
+#include "ugids.h"
+#include "pids.h"
+
+static struct argp common_argp;
+static struct argp fr_ugids_argp;
+
+static const struct argp_option common_options[] =
+{
+ {"verbose", 'v', 0, 0, "Print informational messages"},
+ {"dry-run", 'n', 0, 0, "Don't do anything, just print what would be done"},
+ { 0 }
+};
+static struct argp_child common_child_argps[] =
+{
+ { &pids_argp, 0, "Process selection:" },
+ { 0 }
+};
+
+static const char common_args_doc[] = "USER...";
+static const char common_doc[] =
+ "\vBy default, all processes in the current login collection are selected";
+
+static struct argp_child ugids_child_argps[] =
+{
+ { &ugids_argp, 0, "User/group ids:" },
+ { 0 }
+};
+
+/* An argp on top of the base frobauth argp that provides switchable
+ effective/available ids (XXX this junk should be moved into a single argp
+ [indeed, into ugids_argp] once argp can deal with the init routine
+ frobbing the argp source). */
+static const struct argp_option ea_options[] =
+{
+ {"available", 'a', 0, 0, "USER... specifies available ids"},
+ {"effective", 'e', 0, 0, "USER... specifies effective ids"},
+ { 0 }
+};
+
+static struct argp_child ea_posix_child_argps[] =
+{
+ { &common_argp },
+ { &fr_ugids_argp },
+ { 0 }
+};
+
+static struct argp_child no_ugids_child_argps[] =
+{
+ { &common_argp },
+ { 0 }
+};
+
+/* This holds state information that's only active during parsing. */
+struct frobauth_argp_state
+{
+ struct frobauth *frobauth;
+ struct pids_argp_params pids_argp_params;
+ struct ugids_argp_params ugids_argp_params;
+};
+
+static error_t
+common_parse_opt (int key, char *arg, struct argp_state *state)
+{
+ struct frobauth_argp_state *fs = state->input;
+ struct frobauth *frobauth = fs->frobauth;
+
+ switch (key)
+ {
+ case 'v':
+ frobauth->verbose = 1; break;
+ case 'n':
+ frobauth->dry_run = 1; break;
+
+ case ARGP_KEY_END:
+ if (frobauth->num_pids == 0)
+ /* No pids specified! By default, do the current login collection. */
+ {
+ pid_t lid;
+ error_t err = proc_getloginid (getproc (), getpid (), &lid);
+
+ if (err)
+ argp_failure (state, 2, err,
+ "Couldn't get current login collection");
+
+ err = add_fn_pids (&frobauth->pids, &frobauth->num_pids,
+ lid, proc_getloginpids);
+ if (err)
+ argp_failure (state, 3, err,
+ "%d: Couldn't get login collection pids", lid);
+
+ return err;
+ }
+ break;
+
+ case ARGP_KEY_INIT:
+ bzero (fs, sizeof *fs);
+ fs->frobauth = frobauth;
+ fs->pids_argp_params.pids = &frobauth->pids;
+ fs->pids_argp_params.num_pids = &frobauth->num_pids;
+ state->child_inputs[0] = &fs->pids_argp_params;
+ break;
+
+ case ARGP_KEY_SUCCESS:
+ case ARGP_KEY_ERROR:
+ free (fs);
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static error_t
+ugids_parse_opt (int key, char *arg, struct argp_state *state)
+{
+ struct frobauth_argp_state *fs = state->input;
+ struct frobauth *frobauth = fs->frobauth;
+
+ switch (key)
+ {
+ case ARGP_KEY_INIT:
+ fs->ugids_argp_params.ugids = &frobauth->ugids;
+ fs->ugids_argp_params.parse_user_args = 1;
+ fs->ugids_argp_params.default_user = frobauth->default_user;
+ fs->ugids_argp_params.require_ids = frobauth->require_ids;
+ fs->pids_argp_params.pids = &frobauth->pids;
+ fs->pids_argp_params.num_pids = &frobauth->num_pids;
+
+ state->child_inputs[0] = &fs->ugids_argp_params;
+
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static error_t
+ea_parse_opt (int key, char *arg, struct argp_state *state)
+{
+ struct frobauth_argp_state *fs = state->hook;
+
+ switch (key)
+ {
+ case 'a':
+ fs->ugids_argp_params.user_args_are_available = 1;
+ break;
+ case 'e':
+ fs->ugids_argp_params.user_args_are_effective = 1;
+ break;
+
+ case ARGP_KEY_ARG:
+ if (!fs->ugids_argp_params.user_args_are_effective
+ && !fs->ugids_argp_params.user_args_are_available)
+ /* Default to effective. */
+ fs->ugids_argp_params.user_args_are_effective = 1;
+
+ /* Let someone else parse the arg. */
+ return ARGP_ERR_UNKNOWN;
+
+ case ARGP_KEY_INIT:
+ /* Initialize inputs for child parsers. */
+ fs = state->hook = malloc (sizeof (struct frobauth_argp_state));
+ if (! fs)
+ return ENOMEM;
+
+ fs->frobauth = state->input;
+ state->child_inputs[0] = fs; /* Pass our state to the common parser. */
+ state->child_inputs[1] = fs; /* Pass our state to the common parser. */
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static error_t
+posix_parse_opt (int key, char *arg, struct argp_state *state)
+{
+ struct frobauth_argp_state *fs = state->hook;
+
+ switch (key)
+ {
+ case ARGP_KEY_INIT:
+ /* Initialize inputs for child parsers. */
+ fs = state->hook = malloc (sizeof (struct frobauth_argp_state));
+ if (! fs)
+ return ENOMEM;
+
+ fs->frobauth = state->input;
+ state->child_inputs[0] = fs; /* Pass our state to the common parser. */
+ state->child_inputs[1] = fs; /* Pass our state to the common parser. */
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static error_t
+no_ugids_parse_opt (int key, char *arg, struct argp_state *state)
+{
+ struct frobauth_argp_state *fs = state->hook;
+
+ switch (key)
+ {
+ case ARGP_KEY_INIT:
+ /* Initialize inputs for child parsers. */
+ fs = state->hook = malloc (sizeof (struct frobauth_argp_state));
+ if (! fs)
+ return ENOMEM;
+
+ fs->frobauth = state->input;
+ state->child_inputs[0] = fs; /* Pass our state to the common parser. */
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static struct argp common_argp =
+{
+ common_options, common_parse_opt, 0, common_doc, common_child_argps
+};
+static struct argp fr_ugids_argp =
+{
+ 0, ugids_parse_opt, 0, 0, ugids_child_argps
+};
+
+/* Parse frobauth args/options, where user args are added as single ids to
+ either the effective or available ids. */
+struct argp frobauth_ea_argp =
+{
+ ea_options, ea_parse_opt, 0, 0, ea_posix_child_argps
+};
+
+/* Parse frobauth args/options, where user args are added as posix user. */
+struct argp frobauth_posix_argp =
+{
+ 0, posix_parse_opt, 0, 0, ea_posix_child_argps
+};
+
+/* Parse frobauth args/options, where user args are added as posix user. */
+struct argp frobauth_no_ugids_argp =
+{
+ 0, no_ugids_parse_opt, 0, 0, no_ugids_child_argps
+};