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

    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: 
  231:     /* Fill in user_args from argv. */
  232:     if (argc > 0) {
  233: 	char *to, **from;
  234: 	size_t size, n;
  235: 
  236: 	for (size = 0, from = argv; *from; from++)
  237: 	    size += strlen(*from) + 1;
  238: 
  239: 	user_args = (char *) emalloc(size);
  240: 	for (to = user_args, from = argv; *from; from++) {
  241: 	    n = strlcpy(to, *from, size - (to - user_args));
  242: 	    if (n >= size - (to - user_args))
  243: 		fatalx(_("internal error, %s overflow"), "init_vars()");
  244: 	    to += n;
  245: 	    *to++ = ' ';
  246: 	}
  247: 	*--to = '\0';
  248:     }
  249: 
  250:     /* Initialize default values. */
  251:     init_defaults();
  252: 
  253:     /* Set runas callback. */
  254:     sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
  255: 
  256:     /* Load ip addr/mask for each interface. */
  257:     if (get_net_ifs(&p) > 0)
  258: 	set_interfaces(p);
  259: 
  260:     /* Allocate space for data structures in the parser. */
  261:     init_parser("sudoers", false);
  262: 
  263:     if (sudoersparse() != 0 || parse_error) {
  264: 	parse_error = true;
  265: 	if (errorlineno != -1)
  266: 	    (void) printf("Parse error in %s near line %d",
  267: 		errorfile, errorlineno);
  268: 	else
  269: 	    (void) printf("Parse error in %s", errorfile);
  270:     } else {
  271: 	(void) fputs("Parses OK", stdout);
  272:     }
  273: 
  274:     if (!update_defaults(SETDEF_ALL))
  275: 	(void) fputs(" (problem with defaults entries)", stdout);
  276:     puts(".");
  277: 
  278:     if (def_group_plugin && group_plugin_load(def_group_plugin) != true)
  279: 	def_group_plugin = NULL;
  280: 
  281:     /*
  282:      * Set runas passwd/group entries based on command line or sudoers.
  283:      * Note that if runas_group was specified without runas_user we
  284:      * defer setting runas_pw so the match routines know to ignore it.
  285:      */
  286:     if (runas_group != NULL) {
  287:         set_runasgr(runas_group);
  288:         if (runas_user != NULL)
  289:             set_runaspw(runas_user);
  290:     } else
  291:         set_runaspw(runas_user ? runas_user : def_runas_default);
  292: 
  293:     if (dflag) {
  294: 	(void) putchar('\n');
  295: 	dump_sudoers();
  296: 	if (argc < 2) {
  297: 	    exitcode = parse_error ? 1 : 0;
  298: 	    goto done;
  299: 	}
  300:     }
  301: 
  302:     /* This loop must match the one in sudo_file_lookup() */
  303:     printf("\nEntries for user %s:\n", user_name);
  304:     match = UNSPEC;
  305:     tq_foreach_rev(&userspecs, us) {
  306: 	if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
  307: 	    continue;
  308: 	tq_foreach_rev(&us->privileges, priv) {
  309: 	    putchar('\n');
  310: 	    print_privilege(priv); /* XXX */
  311: 	    putchar('\n');
  312: 	    host_match = hostlist_matches(&priv->hostlist);
  313: 	    if (host_match == ALLOW) {
  314: 		puts("\thost  matched");
  315: 		tq_foreach_rev(&priv->cmndlist, cs) {
  316: 		    runas_match = runaslist_matches(&cs->runasuserlist,
  317: 			&cs->runasgrouplist, NULL, NULL);
  318: 		    if (runas_match == ALLOW) {
  319: 			puts("\trunas matched");
  320: 			cmnd_match = cmnd_matches(cs->cmnd);
  321: 			if (cmnd_match != UNSPEC)
  322: 			    match = cmnd_match;
  323: 			printf("\tcmnd  %s\n", match == ALLOW ? "allowed" :
  324: 			    match == DENY ? "denied" : "unmatched");
  325: 		    }
  326: 		}
  327: 	    } else
  328: 		puts(_("\thost  unmatched"));
  329: 	}
  330:     }
  331:     puts(match == ALLOW ? _("\nCommand allowed") :
  332: 	match == DENY ?  _("\nCommand denied") :  _("\nCommand unmatched"));
  333: 
  334:     /*
  335:      * Exit codes:
  336:      *	0 - parsed OK and command matched.
  337:      *	1 - parse error
  338:      *	2 - command not matched
  339:      *	3 - command denied
  340:      */
  341:     exitcode = parse_error ? 1 : (match == ALLOW ? 0 : match + 3);
  342: done:
  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:     debug_decl(main, SUDO_DEBUG_UTIL)
  351: 
  352:     if (runas_pw != NULL)
  353: 	sudo_pw_delref(runas_pw);
  354:     if (*user == '#') {
  355: 	if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)
  356: 	    runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
  357:     } else {
  358: 	if ((runas_pw = sudo_getpwnam(user)) == NULL)
  359: 	    fatalx(_("unknown user: %s"), user);
  360:     }
  361: 
  362:     debug_return;
  363: }
  364: 
  365: static void
  366: set_runasgr(const char *group)
  367: {
  368:     debug_decl(main, SUDO_DEBUG_UTIL)
  369: 
  370:     if (runas_gr != NULL)
  371: 	sudo_gr_delref(runas_gr);
  372:     if (*group == '#') {
  373: 	if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL)
  374: 	    runas_gr = sudo_fakegrnam(group);
  375:     } else {
  376: 	if ((runas_gr = sudo_getgrnam(group)) == NULL)
  377: 	    fatalx(_("unknown group: %s"), group);
  378:     }
  379: 
  380:     debug_return;
  381: }
  382: 
  383: /* 
  384:  * Callback for runas_default sudoers setting.
  385:  */
  386: static int
  387: cb_runas_default(const char *user)
  388: {
  389:     /* Only reset runaspw if user didn't specify one. */
  390:     if (!runas_user && !runas_group)
  391:         set_runaspw(user);
  392:     return true;
  393: }
  394: 
  395: void
  396: sudo_setspent(void)
  397: {
  398:     return;
  399: }
  400: 
  401: void
  402: sudo_endspent(void)
  403: {
  404:     return;
  405: }
  406: 
  407: FILE *
  408: open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
  409: {
  410:     struct stat sb;
  411:     FILE *fp = NULL;
  412:     char *sudoers_base;
  413:     debug_decl(open_sudoers, SUDO_DEBUG_UTIL)
  414: 
  415:     sudoers_base = strrchr(sudoers, '/');
  416:     if (sudoers_base != NULL)
  417: 	sudoers_base++;
  418: 
  419:     switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
  420: 	case SUDO_PATH_SECURE:
  421: 	    fp = fopen(sudoers, "r");
  422: 	    break;
  423: 	case SUDO_PATH_MISSING:
  424: 	    warning("unable to stat %s", sudoers_base);
  425: 	    break;
  426: 	case SUDO_PATH_BAD_TYPE:
  427: 	    warningx("%s is not a regular file", sudoers_base);
  428: 	    break;
  429: 	case SUDO_PATH_WRONG_OWNER:
  430: 	    warningx("%s should be owned by uid %u",
  431: 		sudoers_base, (unsigned int) sudoers_uid);
  432: 	    break;
  433: 	case SUDO_PATH_WORLD_WRITABLE:
  434: 	    warningx("%s is world writable", sudoers_base);
  435: 	    break;
  436: 	case SUDO_PATH_GROUP_WRITABLE:
  437: 	    warningx("%s should be owned by gid %u",
  438: 		sudoers_base, (unsigned int) sudoers_gid);
  439: 	    break;
  440: 	default:
  441: 	    /* NOTREACHED */
  442: 	    break;
  443:     }
  444: 
  445:     debug_return_ptr(fp);
  446: }
  447: 
  448: void
  449: init_envtables(void)
  450: {
  451:     return;
  452: }
  453: 
  454: int
  455: set_perms(int perm)
  456: {
  457:     return 1;
  458: }
  459: 
  460: void
  461: restore_perms(void)
  462: {
  463: }
  464: 
  465: void
  466: print_member(struct member *m)
  467: {
  468:     struct sudo_command *c;
  469:     debug_decl(print_member, SUDO_DEBUG_UTIL)
  470: 
  471:     if (m->negated)
  472: 	putchar('!');
  473:     if (m->name == NULL)
  474: 	fputs("ALL", stdout);
  475:     else if (m->type != COMMAND)
  476: 	fputs(m->name, stdout);
  477:     else {
  478: 	c = (struct sudo_command *) m->name;
  479: 	printf("%s%s%s", c->cmnd, c->args ? " " : "",
  480: 	    c->args ? c->args : "");
  481:     }
  482: 
  483:     debug_return;
  484: }
  485: 
  486: void
  487: print_defaults(void)
  488: {
  489:     struct defaults *d;
  490:     struct member *m;
  491:     debug_decl(print_member, SUDO_DEBUG_UTIL)
  492: 
  493:     tq_foreach_fwd(&defaults, d) {
  494: 	(void) fputs("Defaults", stdout);
  495: 	switch (d->type) {
  496: 	    case DEFAULTS_HOST:
  497: 		putchar('@');
  498: 		break;
  499: 	    case DEFAULTS_USER:
  500: 		putchar(':');
  501: 		break;
  502: 	    case DEFAULTS_RUNAS:
  503: 		putchar('>');
  504: 		break;
  505: 	    case DEFAULTS_CMND:
  506: 		putchar('!');
  507: 		break;
  508: 	}
  509: 	tq_foreach_fwd(&d->binding, m) {
  510: 	    if (m != tq_first(&d->binding))
  511: 		putchar(',');
  512: 	    print_member(m);
  513: 	}
  514: 	printf("\t%s%s", d->op == false ? "!" : "", d->var);
  515: 	if (d->val != NULL) {
  516: 	    printf("%c%s", d->op == true ? '=' : d->op, d->val);
  517: 	}
  518: 	putchar('\n');
  519:     }
  520: 
  521:     debug_return;
  522: }
  523: 
  524: int
  525: print_alias(void *v1, void *v2)
  526: {
  527:     struct alias *a = (struct alias *)v1;
  528:     struct member *m;
  529:     struct sudo_command *c;
  530:     debug_decl(print_alias, SUDO_DEBUG_UTIL)
  531: 
  532:     switch (a->type) {
  533: 	case HOSTALIAS:
  534: 	    (void) printf("Host_Alias\t%s = ", a->name);
  535: 	    break;
  536: 	case CMNDALIAS:
  537: 	    (void) printf("Cmnd_Alias\t%s = ", a->name);
  538: 	    break;
  539: 	case USERALIAS:
  540: 	    (void) printf("User_Alias\t%s = ", a->name);
  541: 	    break;
  542: 	case RUNASALIAS:
  543: 	    (void) printf("Runas_Alias\t%s = ", a->name);
  544: 	    break;
  545:     }
  546:     tq_foreach_fwd(&a->members, m) {
  547: 	if (m != tq_first(&a->members))
  548: 	    fputs(", ", stdout);
  549: 	if (m->type == COMMAND) {
  550: 	    c = (struct sudo_command *) m->name;
  551: 	    printf("%s%s%s", c->cmnd, c->args ? " " : "",
  552: 		c->args ? c->args : "");
  553: 	} else if (m->type == ALL) {
  554: 	    fputs("ALL", stdout);
  555: 	} else {
  556: 	    fputs(m->name, stdout);
  557: 	}
  558:     }
  559:     putchar('\n');
  560:     debug_return_int(0);
  561: }
  562: 
  563: void
  564: print_privilege(struct privilege *priv)
  565: {
  566:     struct cmndspec *cs;
  567:     struct member *m;
  568:     struct privilege *p;
  569:     struct cmndtag tags;
  570:     debug_decl(print_privilege, SUDO_DEBUG_UTIL)
  571: 
  572:     for (p = priv; p != NULL; p = p->next) {
  573: 	if (p != priv)
  574: 	    fputs(" : ", stdout);
  575: 	tq_foreach_fwd(&p->hostlist, m) {
  576: 	    if (m != tq_first(&p->hostlist))
  577: 		fputs(", ", stdout);
  578: 	    print_member(m);
  579: 	}
  580: 	fputs(" = ", stdout);
  581: 	tags.nopasswd = UNSPEC;
  582: 	tags.noexec = UNSPEC;
  583: 	tq_foreach_fwd(&p->cmndlist, cs) {
  584: 	    if (cs != tq_first(&p->cmndlist))
  585: 		fputs(", ", stdout);
  586: 	    if (!tq_empty(&cs->runasuserlist) || !tq_empty(&cs->runasgrouplist)) {
  587: 		fputs("(", stdout);
  588: 		if (!tq_empty(&cs->runasuserlist)) {
  589: 		    tq_foreach_fwd(&cs->runasuserlist, m) {
  590: 			if (m != tq_first(&cs->runasuserlist))
  591: 			    fputs(", ", stdout);
  592: 			print_member(m);
  593: 		    }  
  594: 		} else if (tq_empty(&cs->runasgrouplist)) {
  595: 		    fputs(def_runas_default, stdout);
  596: 		} else {
  597: 		    fputs(sudo_user.pw->pw_name, stdout);
  598: 		}
  599: 		if (!tq_empty(&cs->runasgrouplist)) {
  600: 		    fputs(" : ", stdout);
  601: 		    tq_foreach_fwd(&cs->runasgrouplist, m) {
  602: 			if (m != tq_first(&cs->runasgrouplist))
  603: 			    fputs(", ", stdout);
  604: 			print_member(m);
  605: 		    }
  606: 		}
  607: 		fputs(") ", stdout);
  608: 	    }
  609: #ifdef HAVE_SELINUX
  610: 	    if (cs->role)
  611: 		printf("ROLE=%s ", cs->role);
  612: 	    if (cs->type)
  613: 		printf("TYPE=%s ", cs->type);
  614: #endif /* HAVE_SELINUX */
  615: #ifdef HAVE_PRIV_SET
  616: 	    if (cs->privs)
  617: 		printf("PRIVS=%s ", cs->privs);
  618: 	    if (cs->limitprivs)
  619: 		printf("LIMITPRIVS=%s ", cs->limitprivs);
  620: #endif /* HAVE_PRIV_SET */
  621: 	    if (cs->tags.nopasswd != UNSPEC && cs->tags.nopasswd != tags.nopasswd)
  622: 		printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : "");
  623: 	    if (cs->tags.noexec != UNSPEC && cs->tags.noexec != tags.noexec)
  624: 		printf("%sEXEC: ", cs->tags.noexec ? "NO" : "");
  625: 	    print_member(cs->cmnd);
  626: 	    memcpy(&tags, &cs->tags, sizeof(tags));
  627: 	}
  628:     }
  629:     debug_return;
  630: }
  631: 
  632: void
  633: print_userspecs(void)
  634: {
  635:     struct member *m;
  636:     struct userspec *us;
  637:     debug_decl(print_userspecs, SUDO_DEBUG_UTIL)
  638: 
  639:     tq_foreach_fwd(&userspecs, us) {
  640: 	tq_foreach_fwd(&us->users, m) {
  641: 	    if (m != tq_first(&us->users))
  642: 		fputs(", ", stdout);
  643: 	    print_member(m);
  644: 	}
  645: 	putchar('\t');
  646: 	print_privilege(us->privileges.first); /* XXX */
  647: 	putchar('\n');
  648:     }
  649:     debug_return;
  650: }
  651: 
  652: void
  653: dump_sudoers(void)
  654: {
  655:     debug_decl(dump_sudoers, SUDO_DEBUG_UTIL)
  656: 
  657:     print_defaults();
  658: 
  659:     putchar('\n');
  660:     alias_apply(print_alias, NULL);
  661: 
  662:     putchar('\n');
  663:     print_userspecs();
  664: 
  665:     debug_return;
  666: }
  667: 
  668: static int testsudoers_print(const char *msg)
  669: {
  670:     return fputs(msg, stderr);
  671: }
  672: 
  673: void
  674: usage(void)
  675: {
  676:     (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());
  677:     exit(1);
  678: }

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