/*
- * Copyright (c) 1993-1996, 1998-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1993-1996, 1998-2013 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#include <config.h>
#include <sys/types.h>
-#include <sys/param.h>
#include <stdio.h>
#ifdef STDC_HEADERS
#include <grp.h>
#include <pwd.h>
-#include <sudo_usage.h>
+#include "sudo_usage.h"
#include "sudo.h"
#include "lbuf.h"
{ "bsdauth_type" },
#define ARG_LOGIN_CLASS 1
{ "login_class" },
-#define ARG_DEBUG_LEVEL 2
- { "debug_level" },
+#define ARG_DEBUG_FLAGS 2
+ { "debug_flags" },
#define ARG_PRESERVE_ENVIRONMENT 3
{ "preserve_environment" },
#define ARG_RUNAS_GROUP 4
{ "closefrom" },
#define ARG_NET_ADDRS 19
{ "network_addrs" },
-#define NUM_SETTINGS 20
+#define ARG_MAX_GROUPS 20
+ { "max_groups" },
+#define ARG_PLUGIN_DIR 21
+ { "plugin_dir" },
+#define NUM_SETTINGS 22
{ NULL }
};
int valid_flags, ch;
int i, j;
char *cp, **env_add, **settings;
+ const char *debug_flags;
int nenv = 0;
int env_size = 32;
+ debug_decl(parse_args, SUDO_DEBUG_ARGS)
env_add = emalloc2(env_size, sizeof(char *));
if (get_net_ifs(&cp) > 0)
sudo_settings[ARG_NET_ADDRS].value = cp;
+ /* Set debug file and flags from sudo.conf. */
+ debug_flags = sudo_conf_debug_flags();
+ if (debug_flags != NULL)
+ sudo_settings[ARG_DEBUG_FLAGS].value = debug_flags;
+
+ /* Set max_groups from sudo.conf. */
+ i = sudo_conf_max_groups();
+ if (i != -1) {
+ easprintf(&cp, "%d", i);
+ sudo_settings[ARG_MAX_GROUPS].value = cp;
+ }
+
/* Returns true if the last option string was "--" */
#define got_end_of_args (optind > 1 && argv[optind - 1][0] == '-' && \
argv[optind - 1][1] == '-' && argv[optind - 1][2] == '\0')
break;
case 'C':
if (atoi(optarg) < 3) {
- warningx("the argument to -C must be a number greater than or equal to 3");
+ warningx(_("the argument to -C must be a number greater than or equal to 3"));
usage(1);
}
sudo_settings[ARG_CLOSEFROM].value = optarg;
break;
#endif
case 'D':
- if ((debug_level = atoi(optarg)) < 1 || debug_level > 9) {
- warningx("the argument to -D must be between 1 and 9 inclusive");
- usage(1);
- }
- sudo_settings[ARG_DEBUG_LEVEL].value = optarg;
+ /* Ignored for backwards compatibility. */
break;
case 'E':
sudo_settings[ARG_PRESERVE_ENVIRONMENT].value = "true";
break;
case 'U':
if ((getpwnam(optarg)) == NULL)
- errorx(1, "unknown user: %s", optarg);
+ fatalx(_("unknown user: %s"), optarg);
list_user = optarg;
break;
case 'u':
if (!mode) {
/* Defer -k mode setting until we know whether it is a flag or not */
if (sudo_settings[ARG_IGNORE_TICKET].value != NULL) {
- if (argc == 0) {
+ if (argc == 0 && !(flags & (MODE_SHELL|MODE_LOGIN_SHELL))) {
mode = MODE_INVALIDATE; /* -k by itself */
sudo_settings[ARG_IGNORE_TICKET].value = NULL;
valid_flags = 0;
if (ISSET(flags, MODE_LOGIN_SHELL)) {
if (ISSET(flags, MODE_SHELL)) {
- warningx("you may not specify both the `-i' and `-s' options");
+ warningx(_("you may not specify both the `-i' and `-s' options"));
usage(1);
}
if (ISSET(flags, MODE_PRESERVE_ENV)) {
- warningx("you may not specify both the `-i' and `-E' options");
+ warningx(_("you may not specify both the `-i' and `-E' options"));
usage(1);
}
SET(flags, MODE_SHELL);
if (mode == MODE_EDIT &&
(ISSET(flags, MODE_PRESERVE_ENV) || env_add[0] != NULL)) {
if (ISSET(mode, MODE_PRESERVE_ENV))
- warningx("the `-E' option is not valid in edit mode");
+ warningx(_("the `-E' option is not valid in edit mode"));
if (env_add[0] != NULL)
- warningx("you may not specify environment variables in edit mode");
+ warningx(_("you may not specify environment variables in edit mode"));
usage(1);
}
if ((runas_user != NULL || runas_group != NULL) &&
usage(1);
}
if (list_user != NULL && mode != MODE_LIST && mode != MODE_CHECK) {
- warningx("the `-U' option may only be used with the `-l' option");
+ warningx(_("the `-U' option may only be used with the `-l' option"));
usage(1);
}
if (ISSET(tgetpass_flags, TGP_STDIN) && ISSET(tgetpass_flags, TGP_ASKPASS)) {
- warningx("the `-A' and `-S' options may not be used together");
+ warningx(_("the `-A' and `-S' options may not be used together"));
usage(1);
}
if ((argc == 0 && mode == MODE_EDIT) ||
* For shell mode we need to rewrite argv
*/
if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) {
- char **av;
- int ac;
-
- if (argc == 0) {
- /* just the shell */
- ac = argc + 1;
- av = emalloc2(ac + 1, sizeof(char *));
- memcpy(av + 1, argv, argc * sizeof(char *));
- } else {
+ char **av, *cmnd = NULL;
+ int ac = 1;
+
+ if (argc != 0) {
/* shell -c "command" */
- char *src, *dst, *end;
+ char *src, *dst;
size_t cmnd_size = (size_t) (argv[argc - 1] - argv[0]) +
- strlen(argv[argc - 1]) + 1;
- ac = 3;
- av = emalloc2(ac + 1, sizeof(char *));
- av[1] = "-c";
- av[2] = dst = emalloc(cmnd_size);
- src = argv[0];
- for (end = src + cmnd_size - 1; src < end; src++, dst++)
- *dst = *src == '\0' ? ' ' : *src;
+ strlen(argv[argc - 1]) + 1;
+
+ cmnd = dst = emalloc2(cmnd_size, 2);
+ for (av = argv; *av != NULL; av++) {
+ for (src = *av; *src != '\0'; src++) {
+ /* quote potential meta characters */
+ if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-')
+ *dst++ = '\\';
+ *dst++ = *src;
+ }
+ *dst++ = ' ';
+ }
+ if (cmnd != dst)
+ dst--; /* replace last space with a NUL */
*dst = '\0';
+
+ ac += 2; /* -c cmnd */
}
+
+ av = emalloc2(ac + 1, sizeof(char *));
av[0] = (char *)user_details.shell; /* plugin may override shell */
+ if (cmnd != NULL) {
+ av[1] = "-c";
+ av[2] = cmnd;
+ }
av[ac] = NULL;
argv = av;
/*
* Format setting_pairs into settings array.
*/
+#ifdef _PATH_SUDO_PLUGIN_DIR
+ sudo_settings[ARG_PLUGIN_DIR].value = _PATH_SUDO_PLUGIN_DIR;
+#endif
settings = emalloc2(NUM_SETTINGS + 1, sizeof(char *));
for (i = 0, j = 0; i < NUM_SETTINGS; i++) {
if (sudo_settings[i].value) {
- sudo_debug(9, "settings: %s=%s", sudo_settings[i].name,
- sudo_settings[i].value);
+ sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s=%s",
+ sudo_settings[i].name, sudo_settings[i].value);
settings[j] = fmt_string(sudo_settings[i].name,
sudo_settings[i].value);
if (settings[j] == NULL)
- errorx(1, "unable to allocate memory");
+ fatalx(NULL);
j++;
}
}
argv--;
argv[0] = "sudoedit";
#else
- errorx(1, "sudoedit is not supported on this platform");
+ fatalx(_("sudoedit is not supported on this platform"));
#endif
}
*env_addp = env_add;
*nargc = argc;
*nargv = argv;
- return mode | flags;
+ debug_return_int(mode | flags);
}
static int
lbuf_init(&lbuf, fatal ? usage_err : usage_out, ulen, NULL,
user_details.ts_cols);
for (i = 0; uvec[i] != NULL; i++) {
- lbuf_append(&lbuf, "usage: ", getprogname(), uvec[i], NULL);
+ lbuf_append(&lbuf, "usage: %s%s", getprogname(), uvec[i]);
lbuf_print(&lbuf);
}
lbuf_destroy(&lbuf);
static void
usage_excl(int fatal)
{
- warningx("Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified");
+ debug_decl(usage_excl, SUDO_DEBUG_ARGS)
+
+ warningx(_("Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"));
usage(fatal);
}
struct lbuf lbuf;
int indent = 16;
const char *pname = getprogname();
+ debug_decl(help, SUDO_DEBUG_ARGS)
lbuf_init(&lbuf, usage_out, indent, NULL, user_details.ts_cols);
if (strcmp(pname, "sudoedit") == 0)
- lbuf_append(&lbuf, pname, " - edit files as another user\n\n", NULL);
+ lbuf_append(&lbuf, _("%s - edit files as another user\n\n"), pname);
else
- lbuf_append(&lbuf, pname, " - execute a command as another user\n\n", NULL);
+ lbuf_append(&lbuf, _("%s - execute a command as another user\n\n"), pname);
lbuf_print(&lbuf);
usage(0);
- lbuf_append(&lbuf, "\nOptions:\n", NULL);
+ lbuf_append(&lbuf, _("\nOptions:\n"));
+ lbuf_append(&lbuf, " -A %s",
+ _("use helper program for password prompting\n"));
#ifdef HAVE_BSD_AUTH_H
- lbuf_append(&lbuf,
- " -A use helper program for password prompting\n", NULL);
+ lbuf_append(&lbuf, " -a type %s",
+ _("use specified BSD authentication type\n"));
#endif
- lbuf_append(&lbuf,
- " -a type use specified BSD authentication type\n", NULL);
- lbuf_append(&lbuf,
- " -b run command in the background\n", NULL);
- lbuf_append(&lbuf,
- " -C fd close all file descriptors >= fd\n", NULL);
+ lbuf_append(&lbuf, " -b %s",
+ _("run command in the background\n"));
+ lbuf_append(&lbuf, " -C fd %s",
+ _("close all file descriptors >= fd\n"));
#ifdef HAVE_LOGIN_CAP_H
- lbuf_append(&lbuf,
- " -c class run command with specified login class\n", NULL);
+ lbuf_append(&lbuf, " -c class %s",
+ _("run command with specified login class\n"));
#endif
- lbuf_append(&lbuf,
- " -E preserve user environment when executing command\n",
- NULL);
- lbuf_append(&lbuf,
- " -e edit files instead of running a command\n", NULL);
- lbuf_append(&lbuf,
- " -g group execute command as the specified group\n", NULL);
- lbuf_append(&lbuf,
- " -H set HOME variable to target user's home dir.\n",
- NULL);
- lbuf_append(&lbuf,
- " -h display help message and exit\n", NULL);
- lbuf_append(&lbuf,
- " -i [command] run a login shell as target user\n", NULL);
- lbuf_append(&lbuf,
- " -K remove timestamp file completely\n", NULL);
- lbuf_append(&lbuf,
- " -k invalidate timestamp file\n", NULL);
- lbuf_append(&lbuf,
- " -l[l] command list user's available commands\n", NULL);
- lbuf_append(&lbuf,
- " -n non-interactive mode, will not prompt user\n", NULL);
- lbuf_append(&lbuf,
- " -P preserve group vector instead of setting to target's\n",
- NULL);
- lbuf_append(&lbuf,
- " -p prompt use specified password prompt\n", NULL);
+ lbuf_append(&lbuf, " -E %s",
+ _("preserve user environment when executing command\n"));
+ lbuf_append(&lbuf, " -e %s",
+ _("edit files instead of running a command\n"));
+ lbuf_append(&lbuf, " -g group %s",
+ _("execute command as the specified group\n"));
+ lbuf_append(&lbuf, " -H %s",
+ _("set HOME variable to target user's home dir.\n"));
+ lbuf_append(&lbuf, " -h %s",
+ _("display help message and exit\n"));
+ lbuf_append(&lbuf, " -i [command] %s",
+ _("run a login shell as target user\n"));
+ lbuf_append(&lbuf, " -K %s",
+ _("remove timestamp file completely\n"));
+ lbuf_append(&lbuf, " -k %s",
+ _("invalidate timestamp file\n"));
+ lbuf_append(&lbuf, " -l[l] command %s",
+ _("list user's available commands\n"));
+ lbuf_append(&lbuf, " -n %s",
+ _("non-interactive mode, will not prompt user\n"));
+ lbuf_append(&lbuf, " -P %s",
+ _("preserve group vector instead of setting to target's\n"));
+ lbuf_append(&lbuf, " -p prompt %s",
+ _("use specified password prompt\n"));
#ifdef HAVE_SELINUX
- lbuf_append(&lbuf,
- " -r role create SELinux security context with specified role\n",
- NULL);
+ lbuf_append(&lbuf, " -r role %s",
+ _("create SELinux security context with specified role\n"));
#endif
+ lbuf_append(&lbuf, " -S %s",
+ _("read password from standard input\n"));
lbuf_append(&lbuf,
- " -S read password from standard input\n", NULL);
- lbuf_append(&lbuf,
- " -s [command] run a shell as target user\n", NULL);
+ " -s [command] %s", _("run a shell as target user\n"));
#ifdef HAVE_SELINUX
- lbuf_append(&lbuf,
- " -t type create SELinux security context with specified role\n",
- NULL);
+ lbuf_append(&lbuf, " -t type %s",
+ _("create SELinux security context with specified role\n"));
#endif
- lbuf_append(&lbuf,
- " -U user when listing, list specified user's privileges\n",
- NULL);
- lbuf_append(&lbuf,
- " -u user run command (or edit file) as specified user\n", NULL);
- lbuf_append(&lbuf,
- " -V display version information and exit\n", NULL);
- lbuf_append(&lbuf,
- " -v update user's timestamp without running a command\n",
- NULL);
- lbuf_append(&lbuf,
- " -- stop processing command line arguments\n", NULL);
+ lbuf_append(&lbuf, " -U user %s",
+ _("when listing, list specified user's privileges\n"));
+ lbuf_append(&lbuf, " -u user %s",
+ _("run command (or edit file) as specified user\n"));
+ lbuf_append(&lbuf, " -V %s",
+ _("display version information and exit\n"));
+ lbuf_append(&lbuf, " -v %s",
+ _("update user's timestamp without running a command\n"));
+ lbuf_append(&lbuf, " -- %s",
+ _("stop processing command line arguments\n"));
lbuf_print(&lbuf);
lbuf_destroy(&lbuf);
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 0);
exit(0);
}