File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / src / parse_args.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 16:23:02 2012 UTC (12 years, 4 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_3p2, HEAD
sudo

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

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