File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / testsudoers.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 07:56:35 2013 UTC (10 years, 9 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, HEAD
v 1.8.8

    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: extern int errorlineno;
  106: extern bool parse_error;
  107: extern char *errorfile;
  108: 
  109: /* For getopt(3) */
  110: extern char *optarg;
  111: extern int optind;
  112: 
  113: #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
  114: extern char *malloc_options;
  115: #endif
  116: #ifdef YYDEBUG
  117: extern int sudoersdebug;
  118: #endif
  119: 
  120: __dso_public int main(int argc, char *argv[]);
  121: 
  122: int
  123: main(int argc, char *argv[])
  124: {
  125:     struct cmndspec *cs;
  126:     struct privilege *priv;
  127:     struct userspec *us;
  128:     char *p, *grfile, *pwfile;
  129:     char hbuf[HOST_NAME_MAX + 1];
  130:     int match, host_match, runas_match, cmnd_match;
  131:     int ch, dflag, exitcode = 0;
  132:     debug_decl(main, SUDO_DEBUG_MAIN)
  133: 
  134: #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
  135:     malloc_options = "AFGJPR";
  136: #endif
  137: #ifdef YYDEBUG
  138:     sudoersdebug = 1;
  139: #endif
  140: 
  141: #if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
  142:     setprogname(argc > 0 ? argv[0] : "testsudoers");
  143: #endif
  144: 
  145:     sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
  146:     bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */
  147:     textdomain("sudoers");
  148: 
  149:     /* Read sudo.conf. */
  150:     sudo_conf_read(NULL);
  151: 
  152:     dflag = 0;
  153:     grfile = pwfile = NULL;
  154:     while ((ch = getopt(argc, argv, "dg:G:h:P:p:tu:U:")) != -1) {
  155: 	switch (ch) {
  156: 	    case 'd':
  157: 		dflag = 1;
  158: 		break;
  159: 	    case 'h':
  160: 		user_host = optarg;
  161: 		break;
  162: 	    case 'G':
  163: 		sudoers_gid = (gid_t)atoi(optarg);
  164: 		break;
  165: 	    case 'g':
  166: 		runas_group = optarg;
  167: 		break;
  168: 	    case 'p':
  169: 		pwfile = optarg;
  170: 		break;
  171: 	    case 'P':
  172: 		grfile = optarg;
  173: 		break;
  174: 	    case 't':
  175: 		trace_print = testsudoers_print;
  176: 		break;
  177: 	    case 'U':
  178: 		sudoers_uid = (uid_t)atoi(optarg);
  179: 		break;
  180: 	    case 'u':
  181: 		runas_user = optarg;
  182: 		break;
  183: 	    default:
  184: 		usage();
  185: 		break;
  186: 	}
  187:     }
  188:     argc -= optind;
  189:     argv += optind;
  190: 
  191:     /* Set group/passwd file and init the cache. */
  192:     if (grfile)
  193: 	setgrfile(grfile);
  194:     if (pwfile)
  195: 	setpwfile(pwfile);
  196:     sudo_setpwent();
  197:     sudo_setgrent();
  198: 
  199:     if (argc < 2) {
  200: 	if (!dflag)
  201: 	    usage();
  202: 	user_name = argc ? *argv++ : "root";
  203: 	user_cmnd = user_base = "true";
  204: 	argc = 0;
  205:     } else {
  206: 	user_name = *argv++;
  207: 	user_cmnd = *argv++;
  208: 	if ((p = strrchr(user_cmnd, '/')) != NULL)
  209: 	    user_base = p + 1;
  210: 	else
  211: 	    user_base = user_cmnd;
  212: 	argc -= 2;
  213:     }
  214:     if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL)
  215: 	fatalx(_("unknown user: %s"), user_name);
  216: 
  217:     if (user_host == NULL) {
  218: 	if (gethostname(hbuf, sizeof(hbuf)) != 0)
  219: 	    fatal("gethostname");
  220: 	hbuf[sizeof(hbuf) - 1] = '\0';
  221: 	user_host = hbuf;
  222:     }
  223:     if ((p = strchr(user_host, '.'))) {
  224: 	*p = '\0';
  225: 	user_shost = estrdup(user_host);
  226: 	*p = '.';
  227:     } else {
  228: 	user_shost = user_host;
  229:     }
  230:     user_runhost = user_host;
  231:     user_srunhost = user_shost;
  232: 
  233:     /* Fill in user_args from argv. */
  234:     if (argc > 0) {
  235: 	char *to, **from;
  236: 	size_t size, n;
  237: 
  238: 	for (size = 0, from = argv; *from; from++)
  239: 	    size += strlen(*from) + 1;
  240: 
  241: 	user_args = (char *) emalloc(size);
  242: 	for (to = user_args, from = argv; *from; from++) {
  243: 	    n = strlcpy(to, *from, size - (to - user_args));
  244: 	    if (n >= size - (to - user_args))
  245: 		fatalx(_("internal error, %s overflow"), "init_vars()");
  246: 	    to += n;
  247: 	    *to++ = ' ';
  248: 	}
  249: 	*--to = '\0';
  250:     }
  251: 
  252:     /* Initialize default values. */
  253:     init_defaults();
  254: 
  255:     /* Set runas callback. */
  256:     sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
  257: 
  258:     /* Load ip addr/mask for each interface. */
  259:     if (get_net_ifs(&p) > 0)
  260: 	set_interfaces(p);
  261: 
  262:     /* Allocate space for data structures in the parser. */
  263:     init_parser("sudoers", false);
  264: 
  265:     if (sudoersparse() != 0 || parse_error) {
  266: 	parse_error = true;
  267: 	if (errorlineno != -1)
  268: 	    (void) printf("Parse error in %s near line %d",
  269: 		errorfile, errorlineno);
  270: 	else
  271: 	    (void) printf("Parse error in %s", errorfile);
  272:     } else {
  273: 	(void) fputs("Parses OK", stdout);
  274:     }
  275: 
  276:     if (!update_defaults(SETDEF_ALL))
  277: 	(void) fputs(" (problem with defaults entries)", stdout);
  278:     puts(".");
  279: 
  280:     if (def_group_plugin && group_plugin_load(def_group_plugin) != true)
  281: 	def_group_plugin = NULL;
  282: 
  283:     /*
  284:      * Set runas passwd/group entries based on command line or sudoers.
  285:      * Note that if runas_group was specified without runas_user we
  286:      * defer setting runas_pw so the match routines know to ignore it.
  287:      */
  288:     if (runas_group != NULL) {
  289:         set_runasgr(runas_group);
  290:         if (runas_user != NULL)
  291:             set_runaspw(runas_user);
  292:     } else
  293:         set_runaspw(runas_user ? runas_user : def_runas_default);
  294: 
  295:     if (dflag) {
  296: 	(void) putchar('\n');
  297: 	dump_sudoers();
  298: 	if (argc < 2) {
  299: 	    exitcode = parse_error ? 1 : 0;
  300: 	    goto done;
  301: 	}
  302:     }
  303: 
  304:     /* This loop must match the one in sudo_file_lookup() */
  305:     printf("\nEntries for user %s:\n", user_name);
  306:     match = UNSPEC;
  307:     tq_foreach_rev(&userspecs, us) {
  308: 	if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
  309: 	    continue;
  310: 	tq_foreach_rev(&us->privileges, priv) {
  311: 	    putchar('\n');
  312: 	    print_privilege(priv); /* XXX */
  313: 	    putchar('\n');
  314: 	    host_match = hostlist_matches(&priv->hostlist);
  315: 	    if (host_match == ALLOW) {
  316: 		puts("\thost  matched");
  317: 		tq_foreach_rev(&priv->cmndlist, cs) {
  318: 		    runas_match = runaslist_matches(&cs->runasuserlist,
  319: 			&cs->runasgrouplist, NULL, NULL);
  320: 		    if (runas_match == ALLOW) {
  321: 			puts("\trunas matched");
  322: 			cmnd_match = cmnd_matches(cs->cmnd);
  323: 			if (cmnd_match != UNSPEC)
  324: 			    match = cmnd_match;
  325: 			printf("\tcmnd  %s\n", match == ALLOW ? "allowed" :
  326: 			    match == DENY ? "denied" : "unmatched");
  327: 		    }
  328: 		}
  329: 	    } else
  330: 		puts(_("\thost  unmatched"));
  331: 	}
  332:     }
  333:     puts(match == ALLOW ? _("\nCommand allowed") :
  334: 	match == DENY ?  _("\nCommand denied") :  _("\nCommand unmatched"));
  335: 
  336:     /*
  337:      * Exit codes:
  338:      *	0 - parsed OK and command matched.
  339:      *	1 - parse error
  340:      *	2 - command not matched
  341:      *	3 - command denied
  342:      */
  343:     exitcode = parse_error ? 1 : (match == ALLOW ? 0 : match + 3);
  344: done:
  345:     sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
  346:     exit(exitcode);
  347: }
  348: 
  349: static void
  350: set_runaspw(const char *user)
  351: {
  352:     debug_decl(main, SUDO_DEBUG_UTIL)
  353: 
  354:     if (runas_pw != NULL)
  355: 	sudo_pw_delref(runas_pw);
  356:     if (*user == '#') {
  357: 	if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)
  358: 	    runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
  359:     } else {
  360: 	if ((runas_pw = sudo_getpwnam(user)) == NULL)
  361: 	    fatalx(_("unknown user: %s"), user);
  362:     }
  363: 
  364:     debug_return;
  365: }
  366: 
  367: static void
  368: set_runasgr(const char *group)
  369: {
  370:     debug_decl(main, SUDO_DEBUG_UTIL)
  371: 
  372:     if (runas_gr != NULL)
  373: 	sudo_gr_delref(runas_gr);
  374:     if (*group == '#') {
  375: 	if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL)
  376: 	    runas_gr = sudo_fakegrnam(group);
  377:     } else {
  378: 	if ((runas_gr = sudo_getgrnam(group)) == NULL)
  379: 	    fatalx(_("unknown group: %s"), group);
  380:     }
  381: 
  382:     debug_return;
  383: }
  384: 
  385: /* 
  386:  * Callback for runas_default sudoers setting.
  387:  */
  388: static int
  389: cb_runas_default(const char *user)
  390: {
  391:     /* Only reset runaspw if user didn't specify one. */
  392:     if (!runas_user && !runas_group)
  393:         set_runaspw(user);
  394:     return true;
  395: }
  396: 
  397: void
  398: sudo_setspent(void)
  399: {
  400:     return;
  401: }
  402: 
  403: void
  404: sudo_endspent(void)
  405: {
  406:     return;
  407: }
  408: 
  409: FILE *
  410: open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
  411: {
  412:     struct stat sb;
  413:     FILE *fp = NULL;
  414:     char *sudoers_base;
  415:     debug_decl(open_sudoers, SUDO_DEBUG_UTIL)
  416: 
  417:     sudoers_base = strrchr(sudoers, '/');
  418:     if (sudoers_base != NULL)
  419: 	sudoers_base++;
  420: 
  421:     switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
  422: 	case SUDO_PATH_SECURE:
  423: 	    fp = fopen(sudoers, "r");
  424: 	    break;
  425: 	case SUDO_PATH_MISSING:
  426: 	    warning("unable to stat %s", sudoers_base);
  427: 	    break;
  428: 	case SUDO_PATH_BAD_TYPE:
  429: 	    warningx("%s is not a regular file", sudoers_base);
  430: 	    break;
  431: 	case SUDO_PATH_WRONG_OWNER:
  432: 	    warningx("%s should be owned by uid %u",
  433: 		sudoers_base, (unsigned int) sudoers_uid);
  434: 	    break;
  435: 	case SUDO_PATH_WORLD_WRITABLE:
  436: 	    warningx("%s is world writable", sudoers_base);
  437: 	    break;
  438: 	case SUDO_PATH_GROUP_WRITABLE:
  439: 	    warningx("%s should be owned by gid %u",
  440: 		sudoers_base, (unsigned int) sudoers_gid);
  441: 	    break;
  442: 	default:
  443: 	    /* NOTREACHED */
  444: 	    break;
  445:     }
  446: 
  447:     debug_return_ptr(fp);
  448: }
  449: 
  450: void
  451: init_envtables(void)
  452: {
  453:     return;
  454: }
  455: 
  456: int
  457: set_perms(int perm)
  458: {
  459:     return 1;
  460: }
  461: 
  462: void
  463: restore_perms(void)
  464: {
  465: }
  466: 
  467: void
  468: print_member(struct member *m)
  469: {
  470:     struct sudo_command *c;
  471:     debug_decl(print_member, SUDO_DEBUG_UTIL)
  472: 
  473:     if (m->negated)
  474: 	putchar('!');
  475:     if (m->name == NULL)
  476: 	fputs("ALL", stdout);
  477:     else if (m->type != COMMAND)
  478: 	fputs(m->name, stdout);
  479:     else {
  480: 	c = (struct sudo_command *) m->name;
  481: 	printf("%s%s%s", c->cmnd, c->args ? " " : "",
  482: 	    c->args ? c->args : "");
  483:     }
  484: 
  485:     debug_return;
  486: }
  487: 
  488: void
  489: print_defaults(void)
  490: {
  491:     struct defaults *d;
  492:     struct member *m;
  493:     debug_decl(print_member, SUDO_DEBUG_UTIL)
  494: 
  495:     tq_foreach_fwd(&defaults, d) {
  496: 	(void) fputs("Defaults", stdout);
  497: 	switch (d->type) {
  498: 	    case DEFAULTS_HOST:
  499: 		putchar('@');
  500: 		break;
  501: 	    case DEFAULTS_USER:
  502: 		putchar(':');
  503: 		break;
  504: 	    case DEFAULTS_RUNAS:
  505: 		putchar('>');
  506: 		break;
  507: 	    case DEFAULTS_CMND:
  508: 		putchar('!');
  509: 		break;
  510: 	}
  511: 	tq_foreach_fwd(&d->binding, m) {
  512: 	    if (m != tq_first(&d->binding))
  513: 		putchar(',');
  514: 	    print_member(m);
  515: 	}
  516: 	printf("\t%s%s", d->op == false ? "!" : "", d->var);
  517: 	if (d->val != NULL) {
  518: 	    printf("%c%s", d->op == true ? '=' : d->op, d->val);
  519: 	}
  520: 	putchar('\n');
  521:     }
  522: 
  523:     debug_return;
  524: }
  525: 
  526: int
  527: print_alias(void *v1, void *v2)
  528: {
  529:     struct alias *a = (struct alias *)v1;
  530:     struct member *m;
  531:     struct sudo_command *c;
  532:     debug_decl(print_alias, SUDO_DEBUG_UTIL)
  533: 
  534:     switch (a->type) {
  535: 	case HOSTALIAS:
  536: 	    (void) printf("Host_Alias\t%s = ", a->name);
  537: 	    break;
  538: 	case CMNDALIAS:
  539: 	    (void) printf("Cmnd_Alias\t%s = ", a->name);
  540: 	    break;
  541: 	case USERALIAS:
  542: 	    (void) printf("User_Alias\t%s = ", a->name);
  543: 	    break;
  544: 	case RUNASALIAS:
  545: 	    (void) printf("Runas_Alias\t%s = ", a->name);
  546: 	    break;
  547:     }
  548:     tq_foreach_fwd(&a->members, m) {
  549: 	if (m != tq_first(&a->members))
  550: 	    fputs(", ", stdout);
  551: 	if (m->type == COMMAND) {
  552: 	    c = (struct sudo_command *) m->name;
  553: 	    printf("%s%s%s", c->cmnd, c->args ? " " : "",
  554: 		c->args ? c->args : "");
  555: 	} else if (m->type == ALL) {
  556: 	    fputs("ALL", stdout);
  557: 	} else {
  558: 	    fputs(m->name, stdout);
  559: 	}
  560:     }
  561:     putchar('\n');
  562:     debug_return_int(0);
  563: }
  564: 
  565: void
  566: print_privilege(struct privilege *priv)
  567: {
  568:     struct cmndspec *cs;
  569:     struct member *m;
  570:     struct privilege *p;
  571:     struct cmndtag tags;
  572:     debug_decl(print_privilege, SUDO_DEBUG_UTIL)
  573: 
  574:     for (p = priv; p != NULL; p = p->next) {
  575: 	if (p != priv)
  576: 	    fputs(" : ", stdout);
  577: 	tq_foreach_fwd(&p->hostlist, m) {
  578: 	    if (m != tq_first(&p->hostlist))
  579: 		fputs(", ", stdout);
  580: 	    print_member(m);
  581: 	}
  582: 	fputs(" = ", stdout);
  583: 	tags.nopasswd = UNSPEC;
  584: 	tags.noexec = UNSPEC;
  585: 	tq_foreach_fwd(&p->cmndlist, cs) {
  586: 	    if (cs != tq_first(&p->cmndlist))
  587: 		fputs(", ", stdout);
  588: 	    if (!tq_empty(&cs->runasuserlist) || !tq_empty(&cs->runasgrouplist)) {
  589: 		fputs("(", stdout);
  590: 		if (!tq_empty(&cs->runasuserlist)) {
  591: 		    tq_foreach_fwd(&cs->runasuserlist, m) {
  592: 			if (m != tq_first(&cs->runasuserlist))
  593: 			    fputs(", ", stdout);
  594: 			print_member(m);
  595: 		    }  
  596: 		} else if (tq_empty(&cs->runasgrouplist)) {
  597: 		    fputs(def_runas_default, stdout);
  598: 		} else {
  599: 		    fputs(sudo_user.pw->pw_name, stdout);
  600: 		}
  601: 		if (!tq_empty(&cs->runasgrouplist)) {
  602: 		    fputs(" : ", stdout);
  603: 		    tq_foreach_fwd(&cs->runasgrouplist, m) {
  604: 			if (m != tq_first(&cs->runasgrouplist))
  605: 			    fputs(", ", stdout);
  606: 			print_member(m);
  607: 		    }
  608: 		}
  609: 		fputs(") ", stdout);
  610: 	    }
  611: #ifdef HAVE_SELINUX
  612: 	    if (cs->role)
  613: 		printf("ROLE=%s ", cs->role);
  614: 	    if (cs->type)
  615: 		printf("TYPE=%s ", cs->type);
  616: #endif /* HAVE_SELINUX */
  617: #ifdef HAVE_PRIV_SET
  618: 	    if (cs->privs)
  619: 		printf("PRIVS=%s ", cs->privs);
  620: 	    if (cs->limitprivs)
  621: 		printf("LIMITPRIVS=%s ", cs->limitprivs);
  622: #endif /* HAVE_PRIV_SET */
  623: 	    if (cs->tags.nopasswd != UNSPEC && cs->tags.nopasswd != tags.nopasswd)
  624: 		printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : "");
  625: 	    if (cs->tags.noexec != UNSPEC && cs->tags.noexec != tags.noexec)
  626: 		printf("%sEXEC: ", cs->tags.noexec ? "NO" : "");
  627: 	    print_member(cs->cmnd);
  628: 	    memcpy(&tags, &cs->tags, sizeof(tags));
  629: 	}
  630:     }
  631:     debug_return;
  632: }
  633: 
  634: void
  635: print_userspecs(void)
  636: {
  637:     struct member *m;
  638:     struct userspec *us;
  639:     debug_decl(print_userspecs, SUDO_DEBUG_UTIL)
  640: 
  641:     tq_foreach_fwd(&userspecs, us) {
  642: 	tq_foreach_fwd(&us->users, m) {
  643: 	    if (m != tq_first(&us->users))
  644: 		fputs(", ", stdout);
  645: 	    print_member(m);
  646: 	}
  647: 	putchar('\t');
  648: 	print_privilege(us->privileges.first); /* XXX */
  649: 	putchar('\n');
  650:     }
  651:     debug_return;
  652: }
  653: 
  654: void
  655: dump_sudoers(void)
  656: {
  657:     debug_decl(dump_sudoers, SUDO_DEBUG_UTIL)
  658: 
  659:     print_defaults();
  660: 
  661:     putchar('\n');
  662:     alias_apply(print_alias, NULL);
  663: 
  664:     putchar('\n');
  665:     print_userspecs();
  666: 
  667:     debug_return;
  668: }
  669: 
  670: static int testsudoers_print(const char *msg)
  671: {
  672:     return fputs(msg, stderr);
  673: }
  674: 
  675: void
  676: usage(void)
  677: {
  678:     (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());
  679:     exit(1);
  680: }

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