File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / testsudoers.c
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:12:54 2014 UTC (10 years, 1 month ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_10p3_0, v1_8_10p3, HEAD
sudo v 1.8.10p3

    1: /*
    2:  * Copyright (c) 1996, 1998-2005, 2007-2013
    3:  *	Todd C. Miller <Todd.Miller@courtesan.com>
    4:  *
    5:  * Permission to use, copy, modify, and distribute this software for any
    6:  * purpose with or without fee is hereby granted, provided that the above
    7:  * copyright notice and this permission notice appear in all copies.
    8:  *
    9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   17:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   18:  *
   19:  * Sponsored in part by the Defense Advanced Research Projects
   20:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   21:  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
   22:  */
   23: 
   24: #define _SUDO_MAIN
   25: 
   26: #include <config.h>
   27: 
   28: #include <sys/types.h>
   29: #include <sys/stat.h>
   30: #include <sys/socket.h>
   31: #include <stdio.h>
   32: #ifdef STDC_HEADERS
   33: # include <stdlib.h>
   34: # include <stddef.h>
   35: #else
   36: # ifdef HAVE_STDLIB_H
   37: #  include <stdlib.h>
   38: # endif
   39: #endif /* STDC_HEADERS */
   40: #ifdef HAVE_STRING_H
   41: # include <string.h>
   42: #endif /* HAVE_STRING_H */
   43: #ifdef HAVE_STRINGS_H
   44: # include <strings.h>
   45: #endif /* HAVE_STRINGS_H */
   46: #ifdef HAVE_UNISTD_H
   47: # include <unistd.h>
   48: #endif /* HAVE_UNISTD_H */
   49: #ifdef HAVE_FNMATCH
   50: # include <fnmatch.h>
   51: #else
   52: # include "compat/fnmatch.h"
   53: #endif /* HAVE_FNMATCH */
   54: #ifdef HAVE_NETGROUP_H
   55: # include <netgroup.h>
   56: #endif /* HAVE_NETGROUP_H */
   57: #include <ctype.h>
   58: #include <errno.h>
   59: #include <netinet/in.h>
   60: #include <arpa/inet.h>
   61: 
   62: #include "tsgetgrpw.h"
   63: #include "sudoers.h"
   64: #include "interfaces.h"
   65: #include "parse.h"
   66: #include "sudo_conf.h"
   67: #include "secure_path.h"
   68: #include <gram.h>
   69: 
   70: /*
   71:  * Function Prototypes
   72:  */
   73: int  print_alias(void *, void *);
   74: void dump_sudoers(void);
   75: void print_defaults(void);
   76: void print_privilege(struct privilege *);
   77: void print_userspecs(void);
   78: void usage(void) __attribute__((__noreturn__));
   79: static void set_runaspw(const char *);
   80: static void set_runasgr(const char *);
   81: static int cb_runas_default(const char *);
   82: static int testsudoers_print(const char *msg);
   83: 
   84: extern void setgrfile(const char *);
   85: extern void setgrent(void);
   86: extern void endgrent(void);
   87: extern struct group *getgrent(void);
   88: extern struct group *getgrnam(const char *);
   89: extern struct group *getgrgid(gid_t);
   90: extern void setpwfile(const char *);
   91: extern void setpwent(void);
   92: extern void endpwent(void);
   93: extern struct passwd *getpwent(void);
   94: extern struct passwd *getpwnam(const char *);
   95: extern struct passwd *getpwuid(uid_t);
   96: 
   97: extern int (*trace_print)(const char *msg);
   98: 
   99: /*
  100:  * Globals
  101:  */
  102: struct sudo_user sudo_user;
  103: struct passwd *list_pw;
  104: static char *runas_group, *runas_user;
  105: 
  106: #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
  107: extern char *malloc_options;
  108: #endif
  109: #ifdef YYDEBUG
  110: extern int sudoersdebug;
  111: #endif
  112: 
  113: __dso_public int main(int argc, char *argv[]);
  114: 
  115: int
  116: main(int argc, char *argv[])
  117: {
  118:     struct cmndspec *cs;
  119:     struct privilege *priv;
  120:     struct userspec *us;
  121:     char *p, *grfile, *pwfile;
  122:     char hbuf[HOST_NAME_MAX + 1];
  123:     const char *errstr;
  124:     int match, host_match, runas_match, cmnd_match;
  125:     int ch, dflag, exitcode = 0;
  126:     debug_decl(main, SUDO_DEBUG_MAIN)
  127: 
  128: #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
  129:     malloc_options = "AFGJPR";
  130: #endif
  131: #ifdef YYDEBUG
  132:     sudoersdebug = 1;
  133: #endif
  134: 
  135:     initprogname(argc > 0 ? argv[0] : "testsudoers");
  136: 
  137:     sudoers_initlocale(setlocale(LC_ALL, ""), def_sudoers_locale);
  138:     bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */
  139:     textdomain("sudoers");
  140: 
  141:     /* Read sudo.conf. */
  142:     sudo_conf_read(NULL);
  143: 
  144:     dflag = 0;
  145:     grfile = pwfile = NULL;
  146:     while ((ch = getopt(argc, argv, "dg:G:h:P:p:tu:U:")) != -1) {
  147: 	switch (ch) {
  148: 	    case 'd':
  149: 		dflag = 1;
  150: 		break;
  151: 	    case 'h':
  152: 		user_host = optarg;
  153: 		break;
  154: 	    case 'G':
  155: 		sudoers_gid = (gid_t)atoid(optarg, NULL, NULL, &errstr);
  156: 		if (errstr != NULL)
  157: 		    fatalx("group ID %s: %s", optarg, errstr);
  158: 		break;
  159: 	    case 'g':
  160: 		runas_group = optarg;
  161: 		break;
  162: 	    case 'p':
  163: 		pwfile = optarg;
  164: 		break;
  165: 	    case 'P':
  166: 		grfile = optarg;
  167: 		break;
  168: 	    case 't':
  169: 		trace_print = testsudoers_print;
  170: 		break;
  171: 	    case 'U':
  172: 		sudoers_uid = (uid_t)atoid(optarg, NULL, NULL, &errstr);
  173: 		if (errstr != NULL)
  174: 		    fatalx("user ID %s: %s", optarg, errstr);
  175: 		break;
  176: 	    case 'u':
  177: 		runas_user = optarg;
  178: 		break;
  179: 	    default:
  180: 		usage();
  181: 		break;
  182: 	}
  183:     }
  184:     argc -= optind;
  185:     argv += optind;
  186: 
  187:     /* Set group/passwd file and init the cache. */
  188:     if (grfile)
  189: 	setgrfile(grfile);
  190:     if (pwfile)
  191: 	setpwfile(pwfile);
  192:     sudo_setpwent();
  193:     sudo_setgrent();
  194: 
  195:     if (argc < 2) {
  196: 	if (!dflag)
  197: 	    usage();
  198: 	user_name = argc ? *argv++ : "root";
  199: 	user_cmnd = user_base = "true";
  200: 	argc = 0;
  201:     } else {
  202: 	user_name = *argv++;
  203: 	user_cmnd = *argv++;
  204: 	if ((p = strrchr(user_cmnd, '/')) != NULL)
  205: 	    user_base = p + 1;
  206: 	else
  207: 	    user_base = user_cmnd;
  208: 	argc -= 2;
  209:     }
  210:     if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL)
  211: 	fatalx(U_("unknown user: %s"), user_name);
  212: 
  213:     if (user_host == NULL) {
  214: 	if (gethostname(hbuf, sizeof(hbuf)) != 0)
  215: 	    fatal("gethostname");
  216: 	hbuf[sizeof(hbuf) - 1] = '\0';
  217: 	user_host = hbuf;
  218:     }
  219:     if ((p = strchr(user_host, '.'))) {
  220: 	*p = '\0';
  221: 	user_shost = estrdup(user_host);
  222: 	*p = '.';
  223:     } else {
  224: 	user_shost = user_host;
  225:     }
  226:     user_runhost = user_host;
  227:     user_srunhost = user_shost;
  228: 
  229:     /* Fill in user_args from argv. */
  230:     if (argc > 0) {
  231: 	char *to, **from;
  232: 	size_t size, n;
  233: 
  234: 	for (size = 0, from = argv; *from; from++)
  235: 	    size += strlen(*from) + 1;
  236: 
  237: 	user_args = (char *) emalloc(size);
  238: 	for (to = user_args, from = argv; *from; from++) {
  239: 	    n = strlcpy(to, *from, size - (to - user_args));
  240: 	    if (n >= size - (to - user_args))
  241: 		fatalx(U_("internal error, %s overflow"), "init_vars()");
  242: 	    to += n;
  243: 	    *to++ = ' ';
  244: 	}
  245: 	*--to = '\0';
  246:     }
  247: 
  248:     /* Initialize default values. */
  249:     init_defaults();
  250: 
  251:     /* Set runas callback. */
  252:     sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
  253: 
  254:     /* Load ip addr/mask for each interface. */
  255:     if (get_net_ifs(&p) > 0)
  256: 	set_interfaces(p);
  257: 
  258:     /* Allocate space for data structures in the parser. */
  259:     init_parser("sudoers", false);
  260: 
  261:     if (sudoersparse() != 0 || parse_error) {
  262: 	parse_error = true;
  263: 	if (errorlineno != -1)
  264: 	    (void) printf("Parse error in %s near line %d",
  265: 		errorfile, errorlineno);
  266: 	else
  267: 	    (void) printf("Parse error in %s", errorfile);
  268:     } else {
  269: 	(void) fputs("Parses OK", stdout);
  270:     }
  271: 
  272:     if (!update_defaults(SETDEF_ALL))
  273: 	(void) fputs(" (problem with defaults entries)", stdout);
  274:     puts(".");
  275: 
  276:     if (def_group_plugin && group_plugin_load(def_group_plugin) != true)
  277: 	def_group_plugin = NULL;
  278: 
  279:     /*
  280:      * Set runas passwd/group entries based on command line or sudoers.
  281:      * Note that if runas_group was specified without runas_user we
  282:      * defer setting runas_pw so the match routines know to ignore it.
  283:      */
  284:     if (runas_group != NULL) {
  285:         set_runasgr(runas_group);
  286:         if (runas_user != NULL)
  287:             set_runaspw(runas_user);
  288:     } else
  289:         set_runaspw(runas_user ? runas_user : def_runas_default);
  290: 
  291:     if (dflag) {
  292: 	(void) putchar('\n');
  293: 	dump_sudoers();
  294: 	if (argc < 2) {
  295: 	    exitcode = parse_error ? 1 : 0;
  296: 	    goto done;
  297: 	}
  298:     }
  299: 
  300:     /* This loop must match the one in sudo_file_lookup() */
  301:     printf("\nEntries for user %s:\n", user_name);
  302:     match = UNSPEC;
  303:     TAILQ_FOREACH_REVERSE(us, &userspecs, userspec_list, entries) {
  304: 	if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
  305: 	    continue;
  306: 	TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
  307: 	    putchar('\n');
  308: 	    print_privilege(priv);
  309: 	    putchar('\n');
  310: 	    host_match = hostlist_matches(&priv->hostlist);
  311: 	    if (host_match == ALLOW) {
  312: 		puts("\thost  matched");
  313: 		TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
  314: 		    runas_match = runaslist_matches(cs->runasuserlist,
  315: 			cs->runasgrouplist, NULL, NULL);
  316: 		    if (runas_match == ALLOW) {
  317: 			puts("\trunas matched");
  318: 			cmnd_match = cmnd_matches(cs->cmnd);
  319: 			if (cmnd_match != UNSPEC)
  320: 			    match = cmnd_match;
  321: 			printf("\tcmnd  %s\n", match == ALLOW ? "allowed" :
  322: 			    match == DENY ? "denied" : "unmatched");
  323: 		    }
  324: 		}
  325: 	    } else
  326: 		puts(_("\thost  unmatched"));
  327: 	}
  328:     }
  329:     puts(match == ALLOW ? _("\nCommand allowed") :
  330: 	match == DENY ?  _("\nCommand denied") :  _("\nCommand unmatched"));
  331: 
  332:     /*
  333:      * Exit codes:
  334:      *	0 - parsed OK and command matched.
  335:      *	1 - parse error
  336:      *	2 - command not matched
  337:      *	3 - command denied
  338:      */
  339:     exitcode = parse_error ? 1 : (match == ALLOW ? 0 : match + 3);
  340: done:
  341:     sudo_endpwent();
  342:     sudo_endgrent();
  343:     sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
  344:     exit(exitcode);
  345: }
  346: 
  347: static void
  348: set_runaspw(const char *user)
  349: {
  350:     struct passwd *pw = NULL;
  351:     debug_decl(set_runaspw, SUDO_DEBUG_UTIL)
  352: 
  353:     if (*user == '#') {
  354: 	const char *errstr;
  355: 	uid_t uid = atoid(user + 1, NULL, NULL, &errstr);
  356: 	if (errstr == NULL) {
  357: 	    if ((pw = sudo_getpwuid(uid)) == NULL)
  358: 		pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
  359: 	}
  360:     }
  361:     if (pw == NULL) {
  362: 	if ((pw = sudo_getpwnam(user)) == NULL)
  363: 	    fatalx(U_("unknown user: %s"), user);
  364:     }
  365:     if (runas_pw != NULL)
  366: 	sudo_pw_delref(runas_pw);
  367:     runas_pw = pw;
  368:     debug_return;
  369: }
  370: 
  371: static void
  372: set_runasgr(const char *group)
  373: {
  374:     struct group *gr = NULL;
  375:     debug_decl(set_runasgr, SUDO_DEBUG_UTIL)
  376: 
  377:     if (*group == '#') {
  378: 	const char *errstr;
  379: 	gid_t gid = atoid(group + 1, NULL, NULL, &errstr);
  380: 	if (errstr == NULL) {
  381: 	    if ((gr = sudo_getgrgid(gid)) == NULL)
  382: 		gr = sudo_fakegrnam(group);
  383: 	}
  384:     }
  385:     if (gr == NULL) {
  386: 	if ((gr = sudo_getgrnam(group)) == NULL)
  387: 	    fatalx(U_("unknown group: %s"), group);
  388:     }
  389:     if (runas_gr != NULL)
  390: 	sudo_gr_delref(runas_gr);
  391:     runas_gr = gr;
  392:     debug_return;
  393: }
  394: 
  395: /* 
  396:  * Callback for runas_default sudoers setting.
  397:  */
  398: static int
  399: cb_runas_default(const char *user)
  400: {
  401:     /* Only reset runaspw if user didn't specify one. */
  402:     if (!runas_user && !runas_group)
  403:         set_runaspw(user);
  404:     return true;
  405: }
  406: 
  407: void
  408: sudo_setspent(void)
  409: {
  410:     return;
  411: }
  412: 
  413: void
  414: sudo_endspent(void)
  415: {
  416:     return;
  417: }
  418: 
  419: FILE *
  420: open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
  421: {
  422:     struct stat sb;
  423:     FILE *fp = NULL;
  424:     char *sudoers_base;
  425:     debug_decl(open_sudoers, SUDO_DEBUG_UTIL)
  426: 
  427:     sudoers_base = strrchr(sudoers, '/');
  428:     if (sudoers_base != NULL)
  429: 	sudoers_base++;
  430: 
  431:     switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
  432: 	case SUDO_PATH_SECURE:
  433: 	    fp = fopen(sudoers, "r");
  434: 	    break;
  435: 	case SUDO_PATH_MISSING:
  436: 	    warning("unable to stat %s", sudoers_base);
  437: 	    break;
  438: 	case SUDO_PATH_BAD_TYPE:
  439: 	    warningx("%s is not a regular file", sudoers_base);
  440: 	    break;
  441: 	case SUDO_PATH_WRONG_OWNER:
  442: 	    warningx("%s should be owned by uid %u",
  443: 		sudoers_base, (unsigned int) sudoers_uid);
  444: 	    break;
  445: 	case SUDO_PATH_WORLD_WRITABLE:
  446: 	    warningx("%s is world writable", sudoers_base);
  447: 	    break;
  448: 	case SUDO_PATH_GROUP_WRITABLE:
  449: 	    warningx("%s should be owned by gid %u",
  450: 		sudoers_base, (unsigned int) sudoers_gid);
  451: 	    break;
  452: 	default:
  453: 	    /* NOTREACHED */
  454: 	    break;
  455:     }
  456: 
  457:     debug_return_ptr(fp);
  458: }
  459: 
  460: void
  461: init_envtables(void)
  462: {
  463:     return;
  464: }
  465: 
  466: int
  467: set_perms(int perm)
  468: {
  469:     return 1;
  470: }
  471: 
  472: void
  473: restore_perms(void)
  474: {
  475: }
  476: 
  477: void
  478: print_member(struct member *m)
  479: {
  480:     struct sudo_command *c;
  481:     debug_decl(print_member, SUDO_DEBUG_UTIL)
  482: 
  483:     if (m->negated)
  484: 	putchar('!');
  485:     if (m->name == NULL)
  486: 	fputs("ALL", stdout);
  487:     else if (m->type != COMMAND)
  488: 	fputs(m->name, stdout);
  489:     else {
  490: 	c = (struct sudo_command *) m->name;
  491: 	printf("%s%s%s", c->cmnd, c->args ? " " : "",
  492: 	    c->args ? c->args : "");
  493:     }
  494: 
  495:     debug_return;
  496: }
  497: 
  498: void
  499: print_defaults(void)
  500: {
  501:     struct defaults *d;
  502:     struct member *m;
  503:     debug_decl(print_defaults, SUDO_DEBUG_UTIL)
  504: 
  505:     TAILQ_FOREACH(d, &defaults, entries) {
  506: 	(void) fputs("Defaults", stdout);
  507: 	switch (d->type) {
  508: 	    case DEFAULTS_HOST:
  509: 		putchar('@');
  510: 		break;
  511: 	    case DEFAULTS_USER:
  512: 		putchar(':');
  513: 		break;
  514: 	    case DEFAULTS_RUNAS:
  515: 		putchar('>');
  516: 		break;
  517: 	    case DEFAULTS_CMND:
  518: 		putchar('!');
  519: 		break;
  520: 	}
  521: 	TAILQ_FOREACH(m, d->binding, entries) {
  522: 	    if (m != TAILQ_FIRST(d->binding))
  523: 		putchar(',');
  524: 	    print_member(m);
  525: 	}
  526: 	printf("\t%s%s", d->op == false ? "!" : "", d->var);
  527: 	if (d->val != NULL) {
  528: 	    printf("%c%s", d->op == true ? '=' : d->op, d->val);
  529: 	}
  530: 	putchar('\n');
  531:     }
  532: 
  533:     debug_return;
  534: }
  535: 
  536: int
  537: print_alias(void *v1, void *v2)
  538: {
  539:     struct alias *a = (struct alias *)v1;
  540:     struct member *m;
  541:     struct sudo_command *c;
  542:     debug_decl(print_alias, SUDO_DEBUG_UTIL)
  543: 
  544:     switch (a->type) {
  545: 	case HOSTALIAS:
  546: 	    (void) printf("Host_Alias\t%s = ", a->name);
  547: 	    break;
  548: 	case CMNDALIAS:
  549: 	    (void) printf("Cmnd_Alias\t%s = ", a->name);
  550: 	    break;
  551: 	case USERALIAS:
  552: 	    (void) printf("User_Alias\t%s = ", a->name);
  553: 	    break;
  554: 	case RUNASALIAS:
  555: 	    (void) printf("Runas_Alias\t%s = ", a->name);
  556: 	    break;
  557:     }
  558:     TAILQ_FOREACH(m, &a->members, entries) {
  559: 	if (m != TAILQ_FIRST(&a->members))
  560: 	    fputs(", ", stdout);
  561: 	if (m->type == COMMAND) {
  562: 	    c = (struct sudo_command *) m->name;
  563: 	    printf("%s%s%s", c->cmnd, c->args ? " " : "",
  564: 		c->args ? c->args : "");
  565: 	} else if (m->type == ALL) {
  566: 	    fputs("ALL", stdout);
  567: 	} else {
  568: 	    fputs(m->name, stdout);
  569: 	}
  570:     }
  571:     putchar('\n');
  572:     debug_return_int(0);
  573: }
  574: 
  575: void
  576: print_privilege(struct privilege *priv)
  577: {
  578:     struct cmndspec *cs;
  579:     struct member *m;
  580:     struct cmndtag tags;
  581:     debug_decl(print_privilege, SUDO_DEBUG_UTIL)
  582: 
  583:     TAILQ_FOREACH(m, &priv->hostlist, entries) {
  584: 	if (m != TAILQ_FIRST(&priv->hostlist))
  585: 	    fputs(", ", stdout);
  586: 	print_member(m);
  587:     }
  588:     fputs(" = ", stdout);
  589:     tags.nopasswd = UNSPEC;
  590:     tags.noexec = UNSPEC;
  591:     TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
  592: 	if (cs != TAILQ_FIRST(&priv->cmndlist))
  593: 	    fputs(", ", stdout);
  594: 	if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL) {
  595: 	    fputs("(", stdout);
  596: 	    if (cs->runasuserlist != NULL) {
  597: 		TAILQ_FOREACH(m, cs->runasuserlist, entries) {
  598: 		    if (m != TAILQ_FIRST(cs->runasuserlist))
  599: 			fputs(", ", stdout);
  600: 		    print_member(m);
  601: 		}  
  602: 	    } else if (cs->runasgrouplist == NULL) {
  603: 		fputs(def_runas_default, stdout);
  604: 	    } else {
  605: 		fputs(sudo_user.pw->pw_name, stdout);
  606: 	    }
  607: 	    if (cs->runasgrouplist != NULL) {
  608: 		fputs(" : ", stdout);
  609: 		TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
  610: 		    if (m != TAILQ_FIRST(cs->runasgrouplist))
  611: 			fputs(", ", stdout);
  612: 		    print_member(m);
  613: 		}
  614: 	    }
  615: 	    fputs(") ", stdout);
  616: 	}
  617: #ifdef HAVE_SELINUX
  618: 	if (cs->role)
  619: 	    printf("ROLE=%s ", cs->role);
  620: 	if (cs->type)
  621: 	    printf("TYPE=%s ", cs->type);
  622: #endif /* HAVE_SELINUX */
  623: #ifdef HAVE_PRIV_SET
  624: 	if (cs->privs)
  625: 	    printf("PRIVS=%s ", cs->privs);
  626: 	if (cs->limitprivs)
  627: 	    printf("LIMITPRIVS=%s ", cs->limitprivs);
  628: #endif /* HAVE_PRIV_SET */
  629: 	if (cs->tags.nopasswd != UNSPEC && cs->tags.nopasswd != tags.nopasswd)
  630: 	    printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : "");
  631: 	if (cs->tags.noexec != UNSPEC && cs->tags.noexec != tags.noexec)
  632: 	    printf("%sEXEC: ", cs->tags.noexec ? "NO" : "");
  633: 	print_member(cs->cmnd);
  634: 	memcpy(&tags, &cs->tags, sizeof(tags));
  635:     }
  636:     debug_return;
  637: }
  638: 
  639: void
  640: print_userspecs(void)
  641: {
  642:     struct member *m;
  643:     struct userspec *us;
  644:     struct privilege *priv;
  645:     debug_decl(print_userspecs, SUDO_DEBUG_UTIL)
  646: 
  647:     TAILQ_FOREACH(us, &userspecs, entries) {
  648: 	TAILQ_FOREACH(m, &us->users, entries) {
  649: 	    if (m != TAILQ_FIRST(&us->users))
  650: 		fputs(", ", stdout);
  651: 	    print_member(m);
  652: 	}
  653: 	putchar('\t');
  654: 	TAILQ_FOREACH(priv, &us->privileges, entries) {
  655: 	    if (priv != TAILQ_FIRST(&us->privileges))
  656: 		fputs(" : ", stdout);
  657: 	    print_privilege(priv);
  658: 	}
  659: 	putchar('\n');
  660:     }
  661:     debug_return;
  662: }
  663: 
  664: void
  665: dump_sudoers(void)
  666: {
  667:     debug_decl(dump_sudoers, SUDO_DEBUG_UTIL)
  668: 
  669:     print_defaults();
  670: 
  671:     putchar('\n');
  672:     alias_apply(print_alias, NULL);
  673: 
  674:     putchar('\n');
  675:     print_userspecs();
  676: 
  677:     debug_return;
  678: }
  679: 
  680: static int testsudoers_print(const char *msg)
  681: {
  682:     return fputs(msg, stderr);
  683: }
  684: 
  685: void
  686: usage(void)
  687: {
  688:     (void) fprintf(stderr, "usage: %s [-dt] [-G sudoers_gid] [-g group] [-h host] [-P grfile] [-p pwfile] [-U sudoers_uid] [-u user] <user> <command> [args]\n", getprogname());
  689:     exit(1);
  690: }

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