File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / src / parse_args.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 10:46:13 2013 UTC (10 years, 11 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_7p0, v1_8_7, HEAD
1.8.7

    1: /*
    2:  * Copyright (c) 1993-1996, 1998-2013 Todd C. Miller <Todd.Miller@courtesan.com>
    3:  *
    4:  * Permission to use, copy, modify, and distribute this software for any
    5:  * purpose with or without fee is hereby granted, provided that the above
    6:  * copyright notice and this permission notice appear in all copies.
    7:  *
    8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   15:  *
   16:  * Sponsored in part by the Defense Advanced Research Projects
   17:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   18:  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
   19:  */
   20: 
   21: #include <config.h>
   22: 
   23: #include <sys/types.h>
   24: 
   25: #include <stdio.h>
   26: #ifdef STDC_HEADERS
   27: # include <stdlib.h>
   28: # include <stddef.h>
   29: #else
   30: # ifdef HAVE_STDLIB_H
   31: #  include <stdlib.h>
   32: # endif
   33: #endif /* STDC_HEADERS */
   34: #ifdef HAVE_STRING_H
   35: # include <string.h>
   36: #endif /* HAVE_STRING_H */
   37: #ifdef HAVE_STRINGS_H
   38: # include <strings.h>
   39: #endif /* HAVE_STRINGS_H */
   40: #ifdef HAVE_UNISTD_H
   41: # include <unistd.h>
   42: #endif /* HAVE_UNISTD_H */
   43: #include <ctype.h>
   44: #include <grp.h>
   45: #include <pwd.h>
   46: 
   47: #include "sudo_usage.h"
   48: #include "sudo.h"
   49: #include "lbuf.h"
   50: 
   51: /* For getopt(3) */
   52: extern char *optarg;
   53: extern int optind;
   54: 
   55: int tgetpass_flags;
   56: 
   57: /*
   58:  * Local functions.
   59:  */
   60: static void help(void) __attribute__((__noreturn__));
   61: static void usage_excl(int);
   62: 
   63: /*
   64:  * Mapping of command line flags to name/value settings.
   65:  */
   66: static struct sudo_settings {
   67:     const char *name;
   68:     const char *value;
   69: } sudo_settings[] = {
   70: #define ARG_BSDAUTH_TYPE 0
   71:     { "bsdauth_type" },
   72: #define ARG_LOGIN_CLASS 1
   73:     { "login_class" },
   74: #define ARG_DEBUG_FLAGS 2
   75:     { "debug_flags" },
   76: #define ARG_PRESERVE_ENVIRONMENT 3
   77:     { "preserve_environment" },
   78: #define ARG_RUNAS_GROUP 4
   79:     { "runas_group" },
   80: #define ARG_SET_HOME 5
   81:     { "set_home" },
   82: #define ARG_USER_SHELL 6
   83:     { "run_shell" },
   84: #define ARG_LOGIN_SHELL 7
   85:     { "login_shell" },
   86: #define ARG_IGNORE_TICKET 8
   87:     { "ignore_ticket" },
   88: #define ARG_PROMPT 9
   89:     { "prompt" },
   90: #define ARG_SELINUX_ROLE 10
   91:     { "selinux_role" },
   92: #define ARG_SELINUX_TYPE 11
   93:     { "selinux_type" },
   94: #define ARG_RUNAS_USER 12
   95:     { "runas_user" },
   96: #define ARG_PROGNAME 13
   97:     { "progname" },
   98: #define ARG_IMPLIED_SHELL 14
   99:     { "implied_shell" },
  100: #define ARG_PRESERVE_GROUPS 15
  101:     { "preserve_groups" },
  102: #define ARG_NONINTERACTIVE 16
  103:     { "noninteractive" },
  104: #define ARG_SUDOEDIT 17
  105:     { "sudoedit" },
  106: #define ARG_CLOSEFROM 18
  107:     { "closefrom" },
  108: #define ARG_NET_ADDRS 19
  109:     { "network_addrs" },
  110: #define ARG_MAX_GROUPS 20
  111:     { "max_groups" },
  112: #define ARG_PLUGIN_DIR 21
  113:     { "plugin_dir" },
  114: #define NUM_SETTINGS 22
  115:     { NULL }
  116: };
  117: 
  118: /*
  119:  * Command line argument parsing.
  120:  * Sets nargc and nargv which corresponds to the argc/argv we'll use
  121:  * for the command to be run (if we are running one).
  122:  */
  123: int
  124: parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
  125:     char ***env_addp)
  126: {
  127:     int mode = 0;		/* what mode is sudo to be run in? */
  128:     int flags = 0;		/* mode flags */
  129:     int valid_flags, ch;
  130:     int i, j;
  131:     char *cp, **env_add, **settings;
  132:     const char *debug_flags;
  133:     int nenv = 0;
  134:     int env_size = 32;
  135:     debug_decl(parse_args, SUDO_DEBUG_ARGS)
  136: 
  137:     env_add = emalloc2(env_size, sizeof(char *));
  138: 
  139:     /* Pass progname to plugin so it can call setprogname() */
  140:     sudo_settings[ARG_PROGNAME].value = getprogname();
  141: 
  142:     /* First, check to see if we were invoked as "sudoedit". */
  143:     if (strcmp(getprogname(), "sudoedit") == 0) {
  144: 	mode = MODE_EDIT;
  145: 	sudo_settings[ARG_SUDOEDIT].value = "true";
  146:     }
  147: 
  148:     /* Load local IP addresses and masks. */
  149:     if (get_net_ifs(&cp) > 0)
  150: 	sudo_settings[ARG_NET_ADDRS].value = cp;
  151: 
  152:     /* Set debug file and flags from sudo.conf. */
  153:     debug_flags = sudo_conf_debug_flags();
  154:     if (debug_flags != NULL)
  155: 	sudo_settings[ARG_DEBUG_FLAGS].value = debug_flags;
  156: 
  157:     /* Set max_groups from sudo.conf. */
  158:     i = sudo_conf_max_groups();
  159:     if (i != -1) {
  160: 	easprintf(&cp, "%d", i);
  161: 	sudo_settings[ARG_MAX_GROUPS].value = cp;
  162:     }
  163: 
  164:     /* Returns true if the last option string was "--" */
  165: #define got_end_of_args	(optind > 1 && argv[optind - 1][0] == '-' && \
  166: 	    argv[optind - 1][1] == '-' && argv[optind - 1][2] == '\0')
  167: 
  168:     /* Returns true if next option is an environment variable */
  169: #define is_envar (optind < argc && argv[optind][0] != '/' && \
  170: 	    strchr(argv[optind], '=') != NULL)
  171: 
  172:     /* Flags allowed when running a command */
  173:     valid_flags = MODE_BACKGROUND|MODE_PRESERVE_ENV|MODE_RESET_HOME|
  174: 		  MODE_LOGIN_SHELL|MODE_NONINTERACTIVE|MODE_SHELL;
  175:     /* XXX - should fill in settings at the end to avoid dupes */
  176:     for (;;) {
  177: 	/*
  178: 	 * We disable arg permutation for GNU getopt().
  179: 	 * Some trickiness is required to allow environment variables
  180: 	 * to be interspersed with command line options.
  181: 	 */
  182: 	if ((ch = getopt(argc, argv, "+Aa:bC:c:D:Eeg:HhiKklnPp:r:Sst:U:u:Vv")) != -1) {
  183: 	    switch (ch) {
  184: 		case 'A':
  185: 		    SET(tgetpass_flags, TGP_ASKPASS);
  186: 		    break;
  187: #ifdef HAVE_BSD_AUTH_H
  188: 		case 'a':
  189: 		    sudo_settings[ARG_BSDAUTH_TYPE].value = optarg;
  190: 		    break;
  191: #endif
  192: 		case 'b':
  193: 		    SET(flags, MODE_BACKGROUND);
  194: 		    break;
  195: 		case 'C':
  196: 		    if (atoi(optarg) < 3) {
  197: 			warningx(_("the argument to -C must be a number greater than or equal to 3"));
  198: 			usage(1);
  199: 		    }
  200: 		    sudo_settings[ARG_CLOSEFROM].value = optarg;
  201: 		    break;
  202: #ifdef HAVE_LOGIN_CAP_H
  203: 		case 'c':
  204: 		    sudo_settings[ARG_LOGIN_CLASS].value = optarg;
  205: 		    break;
  206: #endif
  207: 		case 'D':
  208: 		    /* Ignored for backwards compatibility. */
  209: 		    break;
  210: 		case 'E':
  211: 		    sudo_settings[ARG_PRESERVE_ENVIRONMENT].value = "true";
  212: 		    break;
  213: 		case 'e':
  214: 		    if (mode && mode != MODE_EDIT)
  215: 			usage_excl(1);
  216: 		    mode = MODE_EDIT;
  217: 		    sudo_settings[ARG_SUDOEDIT].value = "true";
  218: 		    valid_flags = MODE_NONINTERACTIVE;
  219: 		    break;
  220: 		case 'g':
  221: 		    runas_group = optarg;
  222: 		    sudo_settings[ARG_RUNAS_GROUP].value = optarg;
  223: 		    break;
  224: 		case 'H':
  225: 		    sudo_settings[ARG_SET_HOME].value = "true";
  226: 		    break;
  227: 		case 'h':
  228: 		    if (mode && mode != MODE_HELP) {
  229: 			if (strcmp(getprogname(), "sudoedit") != 0)
  230: 			    usage_excl(1);
  231: 		    }
  232: 		    mode = MODE_HELP;
  233: 		    valid_flags = 0;
  234: 		    break;
  235: 		case 'i':
  236: 		    sudo_settings[ARG_LOGIN_SHELL].value = "true";
  237: 		    SET(flags, MODE_LOGIN_SHELL);
  238: 		    break;
  239: 		case 'k':
  240: 		    sudo_settings[ARG_IGNORE_TICKET].value = "true";
  241: 		    break;
  242: 		case 'K':
  243: 		    sudo_settings[ARG_IGNORE_TICKET].value = "true";
  244: 		    if (mode && mode != MODE_KILL)
  245: 			usage_excl(1);
  246: 		    mode = MODE_KILL;
  247: 		    valid_flags = 0;
  248: 		    break;
  249: 		case 'l':
  250: 		    if (mode) {
  251: 			if (mode == MODE_LIST)
  252: 			    SET(flags, MODE_LONG_LIST);
  253: 			else
  254: 			    usage_excl(1);
  255: 		    }
  256: 		    mode = MODE_LIST;
  257: 		    valid_flags = MODE_NONINTERACTIVE|MODE_LONG_LIST;
  258: 		    break;
  259: 		case 'n':
  260: 		    SET(flags, MODE_NONINTERACTIVE);
  261: 		    sudo_settings[ARG_NONINTERACTIVE].value = "true";
  262: 		    break;
  263: 		case 'P':
  264: 		    sudo_settings[ARG_PRESERVE_GROUPS].value = "true";
  265: 		    break;
  266: 		case 'p':
  267: 		    sudo_settings[ARG_PROMPT].value = optarg;
  268: 		    break;
  269: #ifdef HAVE_SELINUX
  270: 		case 'r':
  271: 		    sudo_settings[ARG_SELINUX_ROLE].value = optarg;
  272: 		    break;
  273: 		case 't':
  274: 		    sudo_settings[ARG_SELINUX_TYPE].value = optarg;
  275: 		    break;
  276: #endif
  277: 		case 'S':
  278: 		    SET(tgetpass_flags, TGP_STDIN);
  279: 		    break;
  280: 		case 's':
  281: 		    sudo_settings[ARG_USER_SHELL].value = "true";
  282: 		    SET(flags, MODE_SHELL);
  283: 		    break;
  284: 		case 'U':
  285: 		    if ((getpwnam(optarg)) == NULL)
  286: 			fatalx(_("unknown user: %s"), optarg);
  287: 		    list_user = optarg;
  288: 		    break;
  289: 		case 'u':
  290: 		    runas_user = optarg;
  291: 		    sudo_settings[ARG_RUNAS_USER].value = optarg;
  292: 		    break;
  293: 		case 'v':
  294: 		    if (mode && mode != MODE_VALIDATE)
  295: 			usage_excl(1);
  296: 		    mode = MODE_VALIDATE;
  297: 		    valid_flags = MODE_NONINTERACTIVE;
  298: 		    break;
  299: 		case 'V':
  300: 		    if (mode && mode != MODE_VERSION)
  301: 			usage_excl(1);
  302: 		    mode = MODE_VERSION;
  303: 		    valid_flags = 0;
  304: 		    break;
  305: 		default:
  306: 		    usage(1);
  307: 	    }
  308: 	} else if (!got_end_of_args && is_envar) {
  309: 	    if (nenv == env_size - 2) {
  310: 		env_size *= 2;
  311: 		env_add = erealloc3(env_add, env_size, sizeof(char *));
  312: 	    }
  313: 	    env_add[nenv++] = argv[optind];
  314: 
  315: 	    /* Crank optind and resume getopt. */
  316: 	    optind++;
  317: 	} else {
  318: 	    /* Not an option or an environment variable -- we're done. */
  319: 	    break;
  320: 	}
  321:     }
  322:     env_add[nenv] = NULL;
  323: 
  324:     argc -= optind;
  325:     argv += optind;
  326: 
  327:     if (!mode) {
  328: 	/* Defer -k mode setting until we know whether it is a flag or not */
  329: 	if (sudo_settings[ARG_IGNORE_TICKET].value != NULL) {
  330: 	    if (argc == 0 && !(flags & (MODE_SHELL|MODE_LOGIN_SHELL))) {
  331: 		mode = MODE_INVALIDATE;	/* -k by itself */
  332: 		sudo_settings[ARG_IGNORE_TICKET].value = NULL;
  333: 		valid_flags = 0;
  334: 	    }
  335: 	}
  336: 	if (!mode)
  337: 	    mode = MODE_RUN;		/* running a command */
  338:     }
  339: 
  340:     if (argc > 0 && mode == MODE_LIST)
  341: 	mode = MODE_CHECK;
  342: 
  343:     if (ISSET(flags, MODE_LOGIN_SHELL)) {
  344: 	if (ISSET(flags, MODE_SHELL)) {
  345: 	    warningx(_("you may not specify both the `-i' and `-s' options"));
  346: 	    usage(1);
  347: 	}
  348: 	if (ISSET(flags, MODE_PRESERVE_ENV)) {
  349: 	    warningx(_("you may not specify both the `-i' and `-E' options"));
  350: 	    usage(1);
  351: 	}
  352: 	SET(flags, MODE_SHELL);
  353:     }
  354:     if ((flags & valid_flags) != flags)
  355: 	usage(1);
  356:     if (mode == MODE_EDIT &&
  357:        (ISSET(flags, MODE_PRESERVE_ENV) || env_add[0] != NULL)) {
  358: 	if (ISSET(mode, MODE_PRESERVE_ENV))
  359: 	    warningx(_("the `-E' option is not valid in edit mode"));
  360: 	if (env_add[0] != NULL)
  361: 	    warningx(_("you may not specify environment variables in edit mode"));
  362: 	usage(1);
  363:     }
  364:     if ((runas_user != NULL || runas_group != NULL) &&
  365: 	!ISSET(mode, MODE_EDIT | MODE_RUN | MODE_CHECK | MODE_VALIDATE)) {
  366: 	usage(1);
  367:     }
  368:     if (list_user != NULL && mode != MODE_LIST && mode != MODE_CHECK) {
  369: 	warningx(_("the `-U' option may only be used with the `-l' option"));
  370: 	usage(1);
  371:     }
  372:     if (ISSET(tgetpass_flags, TGP_STDIN) && ISSET(tgetpass_flags, TGP_ASKPASS)) {
  373: 	warningx(_("the `-A' and `-S' options may not be used together"));
  374: 	usage(1);
  375:     }
  376:     if ((argc == 0 && mode == MODE_EDIT) ||
  377: 	(argc > 0 && !ISSET(mode, MODE_RUN | MODE_EDIT | MODE_CHECK)))
  378: 	usage(1);
  379:     if (argc == 0 && mode == MODE_RUN && !ISSET(flags, MODE_SHELL)) {
  380: 	SET(flags, (MODE_IMPLIED_SHELL | MODE_SHELL));
  381: 	sudo_settings[ARG_IMPLIED_SHELL].value = "true";
  382:     }
  383: 
  384:     if (mode == MODE_HELP)
  385: 	help();
  386: 
  387:     /*
  388:      * For shell mode we need to rewrite argv
  389:      */
  390:     if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) {
  391: 	char **av, *cmnd = NULL;
  392: 	int ac = 1;
  393: 
  394: 	if (argc != 0) {
  395: 	    /* shell -c "command" */
  396: 	    char *src, *dst;
  397: 	    size_t cmnd_size = (size_t) (argv[argc - 1] - argv[0]) +
  398: 		strlen(argv[argc - 1]) + 1;
  399: 
  400: 	    cmnd = dst = emalloc2(cmnd_size, 2);
  401: 	    for (av = argv; *av != NULL; av++) {
  402: 		for (src = *av; *src != '\0'; src++) {
  403: 		    /* quote potential meta characters */
  404: 		    if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-')
  405: 			*dst++ = '\\';
  406: 		    *dst++ = *src;
  407: 		}
  408: 		*dst++ = ' ';
  409: 	    }
  410: 	    if (cmnd != dst)
  411: 		dst--;  /* replace last space with a NUL */
  412: 	    *dst = '\0';
  413: 
  414: 	    ac += 2; /* -c cmnd */
  415: 	}
  416: 
  417: 	av = emalloc2(ac + 1, sizeof(char *));
  418: 	av[0] = (char *)user_details.shell; /* plugin may override shell */
  419: 	if (cmnd != NULL) {
  420: 	    av[1] = "-c";
  421: 	    av[2] = cmnd;
  422: 	}
  423: 	av[ac] = NULL;
  424: 
  425: 	argv = av;
  426: 	argc = ac;
  427:     }
  428: 
  429:     /*
  430:      * Format setting_pairs into settings array.
  431:      */
  432: #ifdef _PATH_SUDO_PLUGIN_DIR
  433:     sudo_settings[ARG_PLUGIN_DIR].value = _PATH_SUDO_PLUGIN_DIR;
  434: #endif
  435:     settings = emalloc2(NUM_SETTINGS + 1, sizeof(char *));
  436:     for (i = 0, j = 0; i < NUM_SETTINGS; i++) {
  437: 	if (sudo_settings[i].value) {
  438: 	    sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s=%s",
  439: 		sudo_settings[i].name, sudo_settings[i].value);
  440: 	    settings[j] = fmt_string(sudo_settings[i].name,
  441: 		sudo_settings[i].value);
  442: 	    if (settings[j] == NULL)
  443: 		fatalx(NULL);
  444: 	    j++;
  445: 	}
  446:     }
  447:     settings[j] = NULL;
  448: 
  449:     if (mode == MODE_EDIT) {
  450: #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
  451: 	/* Must have the command in argv[0]. */
  452: 	argc++;
  453: 	argv--;
  454: 	argv[0] = "sudoedit";
  455: #else
  456: 	fatalx(_("sudoedit is not supported on this platform"));
  457: #endif
  458:     }
  459: 
  460:     *settingsp = settings;
  461:     *env_addp = env_add;
  462:     *nargc = argc;
  463:     *nargv = argv;
  464:     debug_return_int(mode | flags);
  465: }
  466: 
  467: static int
  468: usage_err(const char *buf)
  469: {
  470:     return fputs(buf, stderr);
  471: }
  472: 
  473: static int
  474: usage_out(const char *buf)
  475: {
  476:     return fputs(buf, stdout);
  477: }
  478: 
  479: /*
  480:  * Give usage message and exit.
  481:  * The actual usage strings are in sudo_usage.h for configure substitution.
  482:  */
  483: void
  484: usage(int fatal)
  485: {
  486:     struct lbuf lbuf;
  487:     char *uvec[6];
  488:     int i, ulen;
  489: 
  490:     /*
  491:      * Use usage vectors appropriate to the progname.
  492:      */
  493:     if (strcmp(getprogname(), "sudoedit") == 0) {
  494: 	uvec[0] = SUDO_USAGE5 + 3;
  495: 	uvec[1] = NULL;
  496:     } else {
  497: 	uvec[0] = SUDO_USAGE1;
  498: 	uvec[1] = SUDO_USAGE2;
  499: 	uvec[2] = SUDO_USAGE3;
  500: 	uvec[3] = SUDO_USAGE4;
  501: 	uvec[4] = SUDO_USAGE5;
  502: 	uvec[5] = NULL;
  503:     }
  504: 
  505:     /*
  506:      * Print usage and wrap lines as needed, depending on the
  507:      * tty width.
  508:      */
  509:     ulen = (int)strlen(getprogname()) + 8;
  510:     lbuf_init(&lbuf, fatal ? usage_err : usage_out, ulen, NULL,
  511: 	user_details.ts_cols);
  512:     for (i = 0; uvec[i] != NULL; i++) {
  513: 	lbuf_append(&lbuf, "usage: %s%s", getprogname(), uvec[i]);
  514: 	lbuf_print(&lbuf);
  515:     }
  516:     lbuf_destroy(&lbuf);
  517:     if (fatal)
  518: 	exit(1);
  519: }
  520: 
  521: /*
  522:  * Tell which options are mutually exclusive and exit.
  523:  */
  524: static void
  525: usage_excl(int fatal)
  526: {
  527:     debug_decl(usage_excl, SUDO_DEBUG_ARGS)
  528: 
  529:     warningx(_("Only one of the -e, -h, -i, -K, -l, -s, -v or -V options may be specified"));
  530:     usage(fatal);
  531: }
  532: 
  533: static void
  534: help(void)
  535: {
  536:     struct lbuf lbuf;
  537:     int indent = 16;
  538:     const char *pname = getprogname();
  539:     debug_decl(help, SUDO_DEBUG_ARGS)
  540: 
  541:     lbuf_init(&lbuf, usage_out, indent, NULL, user_details.ts_cols);
  542:     if (strcmp(pname, "sudoedit") == 0)
  543: 	lbuf_append(&lbuf, _("%s - edit files as another user\n\n"), pname);
  544:     else
  545: 	lbuf_append(&lbuf, _("%s - execute a command as another user\n\n"), pname);
  546:     lbuf_print(&lbuf);
  547: 
  548:     usage(0);
  549: 
  550:     lbuf_append(&lbuf, _("\nOptions:\n"));
  551:     lbuf_append(&lbuf, "  -A            %s",
  552: 	_("use helper program for password prompting\n"));
  553: #ifdef HAVE_BSD_AUTH_H
  554:     lbuf_append(&lbuf, "  -a type       %s",
  555: 	_("use specified BSD authentication type\n"));
  556: #endif
  557:     lbuf_append(&lbuf, "  -b            %s",
  558: 	_("run command in the background\n"));
  559:     lbuf_append(&lbuf, "  -C fd         %s",
  560: 	_("close all file descriptors >= fd\n"));
  561: #ifdef HAVE_LOGIN_CAP_H
  562:     lbuf_append(&lbuf, "  -c class      %s",
  563: 	_("run command with specified login class\n"));
  564: #endif
  565:     lbuf_append(&lbuf, "  -E            %s",
  566: 	_("preserve user environment when executing command\n"));
  567:     lbuf_append(&lbuf, "  -e            %s",
  568: 	_("edit files instead of running a command\n"));
  569:     lbuf_append(&lbuf, "  -g group      %s",
  570: 	_("execute command as the specified group\n"));
  571:     lbuf_append(&lbuf, "  -H            %s",
  572: 	_("set HOME variable to target user's home dir.\n"));
  573:     lbuf_append(&lbuf, "  -h            %s",
  574: 	_("display help message and exit\n"));
  575:     lbuf_append(&lbuf, "  -i [command]  %s",
  576: 	_("run a login shell as target user\n"));
  577:     lbuf_append(&lbuf, "  -K            %s",
  578: 	_("remove timestamp file completely\n"));
  579:     lbuf_append(&lbuf, "  -k            %s",
  580: 	_("invalidate timestamp file\n"));
  581:     lbuf_append(&lbuf, "  -l[l] command %s",
  582: 	_("list user's available commands\n"));
  583:     lbuf_append(&lbuf, "  -n            %s",
  584: 	_("non-interactive mode, will not prompt user\n"));
  585:     lbuf_append(&lbuf, "  -P            %s",
  586: 	_("preserve group vector instead of setting to target's\n"));
  587:     lbuf_append(&lbuf, "  -p prompt     %s",
  588: 	_("use specified password prompt\n"));
  589: #ifdef HAVE_SELINUX
  590:     lbuf_append(&lbuf, "  -r role       %s",
  591: 	_("create SELinux security context with specified role\n"));
  592: #endif
  593:     lbuf_append(&lbuf, "  -S            %s",
  594: 	_("read password from standard input\n"));
  595:     lbuf_append(&lbuf,
  596: 	"  -s [command]  %s", _("run a shell as target user\n"));
  597: #ifdef HAVE_SELINUX
  598:     lbuf_append(&lbuf, "  -t type       %s",
  599: 	_("create SELinux security context with specified role\n"));
  600: #endif
  601:     lbuf_append(&lbuf, "  -U user       %s",
  602: 	_("when listing, list specified user's privileges\n"));
  603:     lbuf_append(&lbuf, "  -u user       %s",
  604: 	_("run command (or edit file) as specified user\n"));
  605:     lbuf_append(&lbuf, "  -V            %s",
  606: 	_("display version information and exit\n"));
  607:     lbuf_append(&lbuf, "  -v            %s",
  608: 	_("update user's timestamp without running a command\n"));
  609:     lbuf_append(&lbuf, "  --            %s",
  610: 	_("stop processing command line arguments\n"));
  611:     lbuf_print(&lbuf);
  612:     lbuf_destroy(&lbuf);
  613:     sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, 0);
  614:     exit(0);
  615: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>