]> granicus.if.org Git - sudo/commitdiff
Use fmtsudoers functions in testsudoers.
authorTodd C. Miller <Todd.Miller@sudo.ws>
Tue, 6 Mar 2018 22:09:21 +0000 (15:09 -0700)
committerTodd C. Miller <Todd.Miller@sudo.ws>
Tue, 6 Mar 2018 22:09:21 +0000 (15:09 -0700)
24 files changed:
plugins/sudoers/Makefile.in
plugins/sudoers/regress/sudoers/test1.out.ok
plugins/sudoers/regress/sudoers/test10.out.ok
plugins/sudoers/regress/sudoers/test11.out.ok
plugins/sudoers/regress/sudoers/test12.out.ok
plugins/sudoers/regress/sudoers/test13.out.ok
plugins/sudoers/regress/sudoers/test14.out.ok
plugins/sudoers/regress/sudoers/test15.out.ok
plugins/sudoers/regress/sudoers/test16.out.ok
plugins/sudoers/regress/sudoers/test17.out.ok
plugins/sudoers/regress/sudoers/test18.out.ok
plugins/sudoers/regress/sudoers/test19.out.ok
plugins/sudoers/regress/sudoers/test2.out.ok
plugins/sudoers/regress/sudoers/test20.out.ok
plugins/sudoers/regress/sudoers/test21.out.ok
plugins/sudoers/regress/sudoers/test22.out.ok
plugins/sudoers/regress/sudoers/test3.out.ok
plugins/sudoers/regress/sudoers/test4.out.ok
plugins/sudoers/regress/sudoers/test5.out.ok
plugins/sudoers/regress/sudoers/test6.out.ok
plugins/sudoers/regress/sudoers/test7.out.ok
plugins/sudoers/regress/sudoers/test8.out.ok
plugins/sudoers/regress/sudoers/test9.out.ok
plugins/sudoers/testsudoers.c

index f09cee65a78c356f7d28a07c4e54ad2b4e2a5853..9bc6fd046640101754058310637377f657adf9d4 100644 (file)
@@ -167,7 +167,7 @@ CVTSUDOERS_OBJS = cvtsudoers.o cvtsudoers_json.o cvtsudoers_ldif.o \
 
 REPLAY_OBJS = getdate.o sudoreplay.o
 
-TEST_OBJS = group_plugin.o interfaces.o locale.o net_ifs.o \
+TEST_OBJS = fmtsudoers.o group_plugin.o interfaces.o locale.o net_ifs.o \
            sudo_printf.o testsudoers.o tsgetgrpw.o
 
 TSDUMP_OBJS = tsdump.o sudoers_debug.o locale.o
index 34f9aa2bac990d7b9f95f88698a8b444682dceb1..8693cea0ec67f5fc872c870d483962dc93e9e633 100644 (file)
@@ -1,8 +1,6 @@
 Parses OK.
 
-
-
-user1  ALL = LOG_INPUT: LOG_OUTPUT: /usr/bin/su - : ALL = NOLOG_INPUT: NOLOG_OUTPUT: /usr/bin/id
-user2  ALL = NOEXEC: NOPASSWD: SETENV: /usr/bin/vi : ALL = EXEC: PASSWD: NOSETENV: /usr/bin/echo
-user3  ALL = MAIL: /bin/sh : ALL = NOMAIL: /usr/bin/id
-user4  ALL = FOLLOW: sudoedit /etc/motd : ALL = NOFOLLOW: sudoedit /home/*/*
+user1 ALL = LOG_INPUT: LOG_OUTPUT: /usr/bin/su - : ALL = NOLOG_INPUT: NOLOG_OUTPUT: /usr/bin/id
+user2 ALL = SETENV: NOEXEC: NOPASSWD: /usr/bin/vi : ALL = NOSETENV: EXEC: PASSWD: /usr/bin/echo
+user3 ALL = MAIL: /bin/sh : ALL = NOMAIL: /usr/bin/id
+user4 ALL = FOLLOW: sudoedit /etc/motd : ALL = NOFOLLOW: sudoedit /home/*/*
index ea87d793ca30b618da46a87938717b28f2815c48..40c742df9975b0f9b46b46552558b5207a21870b 100644 (file)
@@ -1,4 +1,2 @@
 Parses OK.
 
-
-
index c2b9d282c659353d41aa34566369d0d08daedcf6..9b2e9d6a9c7e088eb2ad844485e7e04d47930af8 100644 (file)
@@ -1,4 +1,2 @@
 Parse error in sudoers near line 1.
 
-
-
index c2b9d282c659353d41aa34566369d0d08daedcf6..9b2e9d6a9c7e088eb2ad844485e7e04d47930af8 100644 (file)
@@ -1,4 +1,2 @@
 Parse error in sudoers near line 1.
 
-
-
index c2b9d282c659353d41aa34566369d0d08daedcf6..9b2e9d6a9c7e088eb2ad844485e7e04d47930af8 100644 (file)
@@ -1,4 +1,2 @@
 Parse error in sudoers near line 1.
 
-
-
index 54cfdcf60279a7ebe05d2d92673b6d96bc9e65a1..bfcb661aa071f213d076f834bd9a6ac9af149469 100644 (file)
@@ -1,7 +1,6 @@
 Parses OK.
 
+Cmnd_Alias LS = sha224:d06a2617c98d377c250edd470fd5e576327748d82915d6e33b5f8db1 /bin/ls
+Cmnd_Alias SH = sha256:hOtoe/iK6SlGg7w4BfZBBdSsXjUmTJ5+ts51yjh7vkM= /bin/sh
 
-Cmnd_Alias     LS = /bin/ls
-Cmnd_Alias     SH = /bin/sh
-
-millert        ALL = LS, SH, /bin/kill
+millert ALL = LS, SH, sha512:srzYEQ2aqzm+it3f74opTMkIImZRLxBARVpb0g9RSouJYdLt7DTRMEY4Ry9NyaOiDoUIplpNjqYH0JMYPVdFnw /bin/kill
index be4dc7647b9b6c9154f86762e220d42467d01c18..fb43c8cd9db8e0d3ebd219228a8f1cb7c7724354 100644 (file)
@@ -1,5 +1,3 @@
 Parses OK.
 
-
-
-user   ALL = sudoedit /etc/motd
+user ALL = sudoedit /etc/motd
index 995171914dd062322292658f8a716c7b609e4d38..f5412426341b0663a0b67ca151e9afcc4da61421 100644 (file)
@@ -1,6 +1,5 @@
 Parses OK.
 
+Cmnd_Alias EDIT = sudoedit /etc/motd
 
-Cmnd_Alias     EDIT = sudoedit /etc/motd
-
-user   ALL = EDIT
+user ALL = EDIT
index c76ef6056cc98745697edfed0d2233b72093cad6..4a2c26da9c782d975067926b7528ac1058316595 100644 (file)
@@ -1,14 +1,13 @@
 Parses OK.
 
-Defaults       command_timeout=2d8h10m59s
+Defaults command_timeout=2d8h10m59s
 
-
-user0  ALL = TIMEOUT=619830 /usr/bin/id, TIMEOUT=619830 /usr/bin/who, /bin/ls
-user1  ALL = TIMEOUT=619830 /usr/bin/id
-user2  ALL = TIMEOUT=15030 /usr/bin/id
-user3  ALL = TIMEOUT=630 /usr/bin/id
-user4  ALL = TIMEOUT=1209600 /usr/bin/id
-user5  ALL = TIMEOUT=300 /usr/bin/id
-user6  ALL = TIMEOUT=30 /usr/bin/id
-user7  ALL = TIMEOUT=45 /usr/bin/id
-user8  ALL = TIMEOUT=619830 /usr/bin/id, TIMEOUT=15030 /usr/bin/id, TIMEOUT=630 /usr/bin/id, TIMEOUT=1209600 /usr/bin/id, TIMEOUT=300 /usr/bin/id, TIMEOUT=30 /usr/bin/id
+user0 ALL = TIMEOUT=619830 /usr/bin/id, /usr/bin/who, /bin/ls
+user1 ALL = TIMEOUT=619830 /usr/bin/id
+user2 ALL = TIMEOUT=15030 /usr/bin/id
+user3 ALL = TIMEOUT=630 /usr/bin/id
+user4 ALL = TIMEOUT=1209600 /usr/bin/id
+user5 ALL = TIMEOUT=300 /usr/bin/id
+user6 ALL = TIMEOUT=30 /usr/bin/id
+user7 ALL = TIMEOUT=45 /usr/bin/id
+user8 ALL = TIMEOUT=619830 /usr/bin/id, TIMEOUT=15030 /usr/bin/id, TIMEOUT=630 /usr/bin/id, TIMEOUT=1209600 /usr/bin/id, TIMEOUT=300 /usr/bin/id, TIMEOUT=30 /usr/bin/id
index 74a9a38dc50c2fc188a9972be5d958af8b834973..ace1ca6596bca5d58ae9a8defea34ee433b7c22e 100644 (file)
@@ -1,6 +1,4 @@
 Parse error in sudoers near line 4 (problem with defaults entries).
 
-Defaults       command_timeout=2d8h10m59ss
-Defaults:root  command_timeout=15f
-
-
+Defaults command_timeout=2d8h10m59ss
+Defaults:root command_timeout=15f
index 81788290e7cb8f9fad3dbed43f2fdb7a0b26f59a..8d7974ef56c0c901f945dfc52f36be74d69dc016 100644 (file)
@@ -1,14 +1,12 @@
 Parses OK.
 
-
-
-user0  ALL = NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /usr/bin/id, NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /bin/ls
-user1  ALL = NOTBEFORE=20170214083000Z /usr/bin/id, NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /bin/ls
-user2  ALL = NOTBEFORE=20170214083018Z /usr/bin/id
-user3  ALL = NOTBEFORE=20170214080000Z /usr/bin/id
-user4  ALL = NOTBEFORE=20170214082400Z /usr/bin/id
-user5  ALL = NOTBEFORE=20170214083000Z /usr/bin/id
-user6  ALL = NOTBEFORE=20170214083000Z /usr/bin/id
-user7  ALL = NOTBEFORE=20170214083000Z /usr/bin/id
-user8  ALL = NOTBEFORE=20170214083000Z /usr/bin/id
-user9  ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+user0 ALL = NOTBEFORE=20170214083000Z NOTAFTER=20170301083000Z /usr/bin/id, /bin/ls
+user1 ALL = NOTBEFORE=20170214083000Z /usr/bin/id, NOTAFTER=20170301083000Z /bin/ls
+user2 ALL = NOTBEFORE=20170214083018Z /usr/bin/id
+user3 ALL = NOTBEFORE=20170214080000Z /usr/bin/id
+user4 ALL = NOTBEFORE=20170214082400Z /usr/bin/id
+user5 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+user6 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+user7 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+user8 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
+user9 ALL = NOTBEFORE=20170214083000Z /usr/bin/id
index 8f55faf4201c2e530ae1b2ea9947afed41f792bd..be5e8f3be448637fd556d11aa8d207fbf510b97d 100644 (file)
@@ -1,42 +1,42 @@
 Parses OK.
 
-Defaults@somehost      set_home
-Defaults@quoted"       set_home
-Defaults:you   set_home
-Defaults:us"   set_home
-Defaults:%them set_home
-Defaults:%: non UNIX 0 c       set_home
-Defaults:+net  set_home
-Defaults>someone       set_home
-Defaults>some one      set_home
+Defaults@somehost set_home
+Defaults@quoted\" set_home
+Defaults:you set_home
+Defaults:us\" set_home
+Defaults:%them set_home
+Defaults:"%: non UNIX 0 c" set_home
+Defaults:+net set_home
+Defaults>someone set_home
+Defaults>"some one" set_home
 
-Runas_Alias    RA1 = foo
-Runas_Alias    RA2 = foo"
-Runas_Alias    RA3 = foo:bar
-Runas_Alias    RA4 = foo:bar"
-User_Alias     UA1 = foo
-User_Alias     UA10 = %:C/non"UNIX"0 c
-User_Alias     UA11 = %:C/non_UNIX_0 c
-User_Alias     UA12 = %:C/non\'UNIX_3 c
-User_Alias     UA2 = foo.bar
-User_Alias     UA3 = foo"
-User_Alias     UA4 = foo:bar
-User_Alias     UA5 = foo:bar"
-User_Alias     UA6 = %baz
-User_Alias     UA7 = %baz.biz
-User_Alias     UA8 = %:C/non UNIX 0 c
-User_Alias     UA9 = %:C/non\'UNIX\'1 c
+Runas_Alias RA1 = foo
+Runas_Alias RA2 = foo\"
+Runas_Alias RA3 = foo\:bar
+Runas_Alias RA4 = foo\:bar\"
+User_Alias UA1 = foo
+User_Alias UA10 = "%:C/non\"UNIX\"0 c"
+User_Alias UA11 = "%:C/non_UNIX_0 c"
+User_Alias UA12 = "%:C/non\'UNIX_3 c"
+User_Alias UA2 = foo.bar
+User_Alias UA3 = foo\"
+User_Alias UA4 = foo\:bar
+User_Alias UA5 = foo\:bar\"
+User_Alias UA6 = %baz
+User_Alias UA7 = %baz.biz
+User_Alias UA8 = "%:C/non UNIX 0 c"
+User_Alias UA9 = "%:C/non\'UNIX\'1 c"
 
-foo    hosta = (root) ALL
-foo.bar        hostb = (root) ALL
-foo"   hostc = (root) ALL
-foo:bar        hostd = (root) ALL
-foo:bar"       hoste = (root) ALL
-%baz   hosta = (root) ALL
-%baz.biz       hostb = (root) ALL
-%:C/non UNIX 0 c       hostc = (root) ALL
-%:C/non\'UNIX\'1 c     hostd = (root) ALL
-%:C/non"UNIX"0 c       hoste = (root) ALL
-%:C/non_UNIX_0 c       hostf = (root) ALL
-%:C/non\'UNIX_3 c      hostg = (root) ALL
-+netgr hosth = (root) ALL
+foo hosta = (root) ALL
+foo.bar hostb = (root) ALL
+foo\" hostc = (root) ALL
+foo\:bar hostd = (root) ALL
+foo\:bar\" hoste = (root) ALL
+%baz hosta = (root) ALL
+%baz.biz hostb = (root) ALL
+"%:C/non UNIX 0 c" hostc = (root) ALL
+"%:C/non\'UNIX\'1 c" hostd = (root) ALL
+"%:C/non\"UNIX\"0 c" hoste = (root) ALL
+"%:C/non_UNIX_0 c" hostf = (root) ALL
+"%:C/non\'UNIX_3 c" hostg = (root) ALL
++netgr hosth = (root) ALL
index fcb54996a946f481b9d4b794dd96f8736a0f622a..882af0ddf70c99cf1a42f6a3d0ff65f0e8238624 100644 (file)
@@ -1,26 +1,24 @@
 Parses OK.
 
-Defaults       lecture
-Defaults       !lecture
-Defaults       lecture=never
-Defaults       lecture=once
-Defaults       lecture=always
-Defaults       listpw
-Defaults       !listpw
-Defaults       listpw=never
-Defaults       listpw=any
-Defaults       listpw=all
-Defaults       listpw=always
-Defaults       verifypw
-Defaults       !verifypw
-Defaults       verifypw=never
-Defaults       verifypw=any
-Defaults       verifypw=all
-Defaults       verifypw=always
-Defaults       fdexec
-Defaults       !fdexec
-Defaults       fdexec=never
-Defaults       fdexec=digest_only
-Defaults       fdexec=always
-
-
+Defaults lecture
+Defaults !lecture
+Defaults lecture=never
+Defaults lecture=once
+Defaults lecture=always
+Defaults listpw
+Defaults !listpw
+Defaults listpw=never
+Defaults listpw=any
+Defaults listpw=all
+Defaults listpw=always
+Defaults verifypw
+Defaults !verifypw
+Defaults verifypw=never
+Defaults verifypw=any
+Defaults verifypw=all
+Defaults verifypw=always
+Defaults fdexec
+Defaults !fdexec
+Defaults fdexec=never
+Defaults fdexec=digest_only
+Defaults fdexec=always
index 4aba66729010177921ac671668cfba48805a8705..630fa6b5e174f641110d8a36f4c1189a4b1d14d8 100644 (file)
@@ -1,37 +1,35 @@
 Parses OK.
 
-Defaults       syslog
-Defaults       !syslog
-Defaults       syslog=auth
-Defaults       syslog=daemon
-Defaults       syslog=user
-Defaults       syslog=local0
-Defaults       syslog=local1
-Defaults       syslog=local2
-Defaults       syslog=local3
-Defaults       syslog=local4
-Defaults       syslog=local5
-Defaults       syslog=local6
-Defaults       syslog=local7
-Defaults       !syslog_goodpri
-Defaults       syslog_goodpri=alert
-Defaults       syslog_goodpri=crit
-Defaults       syslog_goodpri=debug
-Defaults       syslog_goodpri=emerg
-Defaults       syslog_goodpri=err
-Defaults       syslog_goodpri=info
-Defaults       syslog_goodpri=notice
-Defaults       syslog_goodpri=warning
-Defaults       syslog_goodpri=none
-Defaults       !syslog_badpri
-Defaults       syslog_badpri=alert
-Defaults       syslog_badpri=crit
-Defaults       syslog_badpri=debug
-Defaults       syslog_badpri=emerg
-Defaults       syslog_badpri=err
-Defaults       syslog_badpri=info
-Defaults       syslog_badpri=notice
-Defaults       syslog_badpri=warning
-Defaults       syslog_badpri=none
-
-
+Defaults syslog
+Defaults !syslog
+Defaults syslog=auth
+Defaults syslog=daemon
+Defaults syslog=user
+Defaults syslog=local0
+Defaults syslog=local1
+Defaults syslog=local2
+Defaults syslog=local3
+Defaults syslog=local4
+Defaults syslog=local5
+Defaults syslog=local6
+Defaults syslog=local7
+Defaults !syslog_goodpri
+Defaults syslog_goodpri=alert
+Defaults syslog_goodpri=crit
+Defaults syslog_goodpri=debug
+Defaults syslog_goodpri=emerg
+Defaults syslog_goodpri=err
+Defaults syslog_goodpri=info
+Defaults syslog_goodpri=notice
+Defaults syslog_goodpri=warning
+Defaults syslog_goodpri=none
+Defaults !syslog_badpri
+Defaults syslog_badpri=alert
+Defaults syslog_badpri=crit
+Defaults syslog_badpri=debug
+Defaults syslog_badpri=emerg
+Defaults syslog_badpri=err
+Defaults syslog_badpri=info
+Defaults syslog_badpri=notice
+Defaults syslog_badpri=warning
+Defaults syslog_badpri=none
index 59b5e10dfb3c20e05feef2b750eb550159aadfcb..ab43a931f7c2002ada70fba1713784a2f7df75fc 100644 (file)
@@ -1,8 +1,6 @@
 Parses OK.
 
-
-
-user1  ALL = () ALL
-user2  ALL = () ALL
-user3  ALL = () ALL
-user4  ALL = () ALL
+user1 ALL = (root) ALL
+user2 ALL = (root) ALL
+user3 ALL = (root) ALL
+user4 ALL = (root) ALL
index af2f4020f5ff8e237776ba04bf168e8603d43e4b..566aec18e21ed2721dfbc822f1addd2b65ac80a0 100644 (file)
@@ -1,9 +1,8 @@
 Parses OK.
 
-Defaults:FOO   env_reset
-Defaults:foo,bar       env_reset
-Defaults:foo, bar      env_reset
-Defaults:foo,bar       env_reset
-
-User_Alias     FOO = foo, bar
+Defaults:FOO env_reset
+Defaults:foo, bar env_reset
+Defaults:foo, " bar" env_reset
+Defaults:foo, bar env_reset
 
+User_Alias FOO = foo, bar
index 1c0bc4b436124ae2fbcb15b317f051f3992484a0..3552d3bcc953535f22e5c24a7c8ab646c9c7141e 100644 (file)
@@ -1,6 +1,4 @@
 Parse error in sudoers near line 7.
 
-
-User_Alias     BAR = bar
-User_Alias     FOO = foo
-
+User_Alias BAR = bar
+User_Alias FOO = foo
index 3f6e2f215e2b21429c6d6a64143bfc55bdce4c6c..3cd2ec8bfdcb8a3f8a8cd2dc7d95651390d697e9 100644 (file)
@@ -1,4 +1,2 @@
 Parse error in sudoers near line 2.
 
-
-
index 275add61d3c6ac19f5a2d7e39ced5e8eaedf6566..ccc1627b1d19059c381db7d30cf38b50c6f77124 100644 (file)
@@ -1,14 +1,13 @@
 Parses OK.
 
-Defaults:#123  set_home
-Defaults>#123  set_home
-Defaults:#123  set_home
-Defaults>#123  set_home
+Defaults:#123 set_home
+Defaults>#123 set_home
+Defaults:#123 set_home
+Defaults>#123 set_home
 
-
-#0     ALL = ALL
-#0     ALL = (#0 : #0) ALL
-#0     ALL = ALL
-#0     ALL = (#0 : #0) ALL
-%#0    ALL = ALL
-%#0    ALL = ALL
+#0 ALL = ALL
+#0 ALL = (#0 : #0) ALL
+#0 ALL = ALL
+#0 ALL = (#0 : #0) ALL
+%#0 ALL = ALL
+%#0 ALL = ALL
index 3f6e2f215e2b21429c6d6a64143bfc55bdce4c6c..3cd2ec8bfdcb8a3f8a8cd2dc7d95651390d697e9 100644 (file)
@@ -1,4 +1,2 @@
 Parse error in sudoers near line 2.
 
-
-
index 2f07300776701f056bc3e7c4d79050f694d62a44..2ae8c6b39323e2b591541bb15dc87a7d43ddf885 100644 (file)
@@ -1,7 +1,5 @@
 Parse error in sudoers near line 8.
 
-
-User_Alias     UA1 = xy
-User_Alias     UA2 = xy
-User_Alias     UA3 = x"y
-
+User_Alias UA1 = xy
+User_Alias UA2 = xy
+User_Alias UA3 = x\"y
index ea87d793ca30b618da46a87938717b28f2815c48..40c742df9975b0f9b46b46552558b5207a21870b 100644 (file)
@@ -1,4 +1,2 @@
 Parses OK.
 
-
-
index cf7785044111de561b7012460011f935ab2c3c01..ff99ff3285d3b2b16b442738b57992856cf34797 100644 (file)
@@ -49,6 +49,7 @@
 #include "interfaces.h"
 #include "parse.h"
 #include "sudo_conf.h"
+#include "sudo_lbuf.h"
 #include <gram.h>
 
 #ifdef HAVE_FNMATCH
 /*
  * Function Prototypes
  */
-int  print_alias(void *, void *);
-void dump_sudoers(void);
-void print_defaults(void);
-void print_privilege(struct privilege *);
-void print_userspecs(void);
-void usage(void) __attribute__((__noreturn__));
+static void dump_sudoers(struct sudo_lbuf *lbuf);
+static void usage(void) __attribute__((__noreturn__));
 static void set_runaspw(const char *);
 static void set_runasgr(const char *);
 static bool cb_runas_default(const union sudo_defs_val *);
-static int testsudoers_print(const char *msg);
+static int testsudoers_error(const char *msg);
+static int testsudoers_output(const char *buf);
 
 extern void setgrfile(const char *);
 extern void setgrent(void);
@@ -116,6 +114,7 @@ main(int argc, char *argv[])
     const char *errstr;
     int match, host_match, runas_match, cmnd_match;
     int ch, dflag, exitcode = EXIT_FAILURE;
+    struct sudo_lbuf lbuf;
     debug_decl(main, SUDOERS_DEBUG_MAIN)
 
 #if defined(SUDO_DEVEL) && defined(__OpenBSD__)
@@ -133,6 +132,8 @@ main(int argc, char *argv[])
     bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */
     textdomain("sudoers");
 
+    sudo_lbuf_init(&lbuf, testsudoers_output, 0, NULL, 0);
+
     /* Initialize the debug subsystem. */
     if (sudo_conf_read(NULL, SUDO_CONF_DEBUG) == -1)
        goto done;
@@ -165,7 +166,7 @@ main(int argc, char *argv[])
                grfile = optarg;
                break;
            case 't':
-               trace_print = testsudoers_print;
+               trace_print = testsudoers_error;
                break;
            case 'U':
                sudoers_uid = (uid_t)sudo_strtoid(optarg, NULL, NULL, &errstr);
@@ -294,7 +295,7 @@ main(int argc, char *argv[])
 
     if (dflag) {
        (void) putchar('\n');
-       dump_sudoers();
+       dump_sudoers(&lbuf);
        if (argc < 2) {
            exitcode = parse_error ? 1 : 0;
            goto done;
@@ -308,9 +309,9 @@ main(int argc, char *argv[])
        if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
            continue;
        TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
-           putchar('\n');
-           print_privilege(priv);
-           putchar('\n');
+           sudo_lbuf_append(&lbuf, "\n");
+           sudoers_format_privilege(&lbuf, priv, false);
+           sudo_lbuf_print(&lbuf);
            host_match = hostlist_matches(sudo_user.pw, &priv->hostlist);
            if (host_match == ALLOW) {
                puts("\thost  matched");
@@ -342,6 +343,7 @@ main(int argc, char *argv[])
      */
     exitcode = parse_error ? 1 : (match == ALLOW ? 0 : match + 3);
 done:
+    sudo_lbuf_destroy(&lbuf);
     sudo_freepwcache();
     sudo_freegrcache();
     sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
@@ -479,244 +481,98 @@ restore_perms(void)
     return true;
 }
 
-void
-print_member(struct member *m)
-{
-    struct sudo_command *c;
-    debug_decl(print_member, SUDOERS_DEBUG_UTIL)
-
-    if (m->negated)
-       putchar('!');
-    if (m->type == ALL)
-       fputs("ALL", stdout);
-    else if (m->type != COMMAND)
-       fputs(m->name ? m->name : "", stdout);
-    else {
-       c = (struct sudo_command *) m->name;
-       printf("%s%s%s", c->cmnd, c->args ? " " : "",
-           c->args ? c->args : "");
-    }
-
-    debug_return;
-}
-
-void
-print_defaults(void)
+static bool
+print_defaults(struct sudo_lbuf *lbuf)
 {
-    struct defaults *d;
-    struct member *m;
+    struct defaults *def, *next;
     debug_decl(print_defaults, SUDOERS_DEBUG_UTIL)
 
-    TAILQ_FOREACH(d, &defaults, entries) {
-       (void) fputs("Defaults", stdout);
-       switch (d->type) {
-           case DEFAULTS_HOST:
-               putchar('@');
-               break;
-           case DEFAULTS_USER:
-               putchar(':');
-               break;
-           case DEFAULTS_RUNAS:
-               putchar('>');
-               break;
-           case DEFAULTS_CMND:
-               putchar('!');
-               break;
-       }
-       TAILQ_FOREACH(m, d->binding, entries) {
-           if (m != TAILQ_FIRST(d->binding))
-               putchar(',');
-           print_member(m);
-       }
-       printf("\t%s%s", d->op == false ? "!" : "", d->var);
-       if (d->val != NULL) {
-           printf("%c%s", d->op == true ? '=' : d->op, d->val);
-       }
-       putchar('\n');
-    }
+    TAILQ_FOREACH_SAFE(def, &defaults, entries, next)
+       sudoers_format_default_line(lbuf, def, &next, false);
 
-    debug_return;
+    debug_return_bool(!sudo_lbuf_error(lbuf));
 }
 
-int
+static int
 print_alias(void *v1, void *v2)
 {
-    struct alias *a = (struct alias *)v1;
+    struct alias *a = v1;
+    struct sudo_lbuf *lbuf = v2;
     struct member *m;
-    struct sudo_command *c;
     debug_decl(print_alias, SUDOERS_DEBUG_UTIL)
 
-    switch (a->type) {
-       case HOSTALIAS:
-           (void) printf("Host_Alias\t%s = ", a->name);
-           break;
-       case CMNDALIAS:
-           (void) printf("Cmnd_Alias\t%s = ", a->name);
-           break;
-       case USERALIAS:
-           (void) printf("User_Alias\t%s = ", a->name);
-           break;
-       case RUNASALIAS:
-           (void) printf("Runas_Alias\t%s = ", a->name);
-           break;
-    }
+    sudo_lbuf_append(lbuf, "%s %s = ", alias_type_to_string(a->type),
+       a->name);
     TAILQ_FOREACH(m, &a->members, entries) {
        if (m != TAILQ_FIRST(&a->members))
-           fputs(", ", stdout);
-       if (m->type == COMMAND) {
-           c = (struct sudo_command *) m->name;
-           printf("%s%s%s", c->cmnd, c->args ? " " : "",
-               c->args ? c->args : "");
-       } else if (m->type == ALL) {
-           fputs("ALL", stdout);
-       } else {
-           fputs(m->name, stdout);
-       }
+           sudo_lbuf_append(lbuf, ", ");
+       sudoers_format_member(lbuf, m, NULL, UNSPEC);
     }
-    putchar('\n');
-    debug_return_int(0);
+    sudo_lbuf_append(lbuf, "\n");
+
+    debug_return_int(sudo_lbuf_error(lbuf) ? -1 : 0);
 }
 
-#define TAG_SET(tt) \
-    ((tt) != UNSPEC && (tt) != IMPLIED)
+static bool
+print_aliases(struct sudo_lbuf *lbuf)
+{
+    debug_decl(print_aliases, SUDOERS_DEBUG_UTIL)
+
+    alias_apply(print_alias, lbuf);
 
-#define TAG_CHANGED(t) \
-    (TAG_SET(cs->tags.t) && cs->tags.t != tags.t)
+    debug_return_bool(!sudo_lbuf_error(lbuf));
+}
 
-void
-print_privilege(struct privilege *priv)
+static void
+dump_sudoers(struct sudo_lbuf *lbuf)
 {
-    struct cmndspec *cs;
-    struct member *m;
-    struct cmndtag tags;
-    debug_decl(print_privilege, SUDOERS_DEBUG_UTIL)
+    debug_decl(dump_sudoers, SUDOERS_DEBUG_UTIL)
 
-    TAILQ_FOREACH(m, &priv->hostlist, entries) {
-       if (m != TAILQ_FIRST(&priv->hostlist))
-           fputs(", ", stdout);
-       print_member(m);
+    /* Print Defaults */
+    if (!print_defaults(lbuf))
+       goto done;
+    if (lbuf->len > 0) {
+       sudo_lbuf_print(lbuf);
+       sudo_lbuf_append(lbuf, "\n");
     }
-    fputs(" = ", stdout);
-    TAGS_INIT(tags);
-    TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
-       if (cs != TAILQ_FIRST(&priv->cmndlist))
-           fputs(", ", stdout);
-       if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL) {
-           fputs("(", stdout);
-           if (cs->runasuserlist != NULL) {
-               TAILQ_FOREACH(m, cs->runasuserlist, entries) {
-                   if (m != TAILQ_FIRST(cs->runasuserlist))
-                       fputs(", ", stdout);
-                   print_member(m);
-               }  
-           } else if (cs->runasgrouplist == NULL) {
-               fputs(def_runas_default, stdout);
-           } else {
-               fputs(sudo_user.pw->pw_name, stdout);
-           }
-           if (cs->runasgrouplist != NULL) {
-               fputs(" : ", stdout);
-               TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
-                   if (m != TAILQ_FIRST(cs->runasgrouplist))
-                       fputs(", ", stdout);
-                   print_member(m);
-               }
-           }
-           fputs(") ", stdout);
-       }
-#ifdef HAVE_SELINUX
-       if (cs->role)
-           printf("ROLE=%s ", cs->role);
-       if (cs->type)
-           printf("TYPE=%s ", cs->type);
-#endif /* HAVE_SELINUX */
-#ifdef HAVE_PRIV_SET
-       if (cs->privs)
-           printf("PRIVS=%s ", cs->privs);
-       if (cs->limitprivs)
-           printf("LIMITPRIVS=%s ", cs->limitprivs);
-#endif /* HAVE_PRIV_SET */
-       if (cs->timeout > 0)
-           printf("TIMEOUT=%d ", cs->timeout);
-       if (cs->notbefore != UNSPEC) {
-           struct tm *tm = gmtime(&cs->notbefore);
-           printf("NOTBEFORE=%04d%02d%02d%02d%02d%02dZ ",
-               tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-               tm->tm_hour, tm->tm_min, tm->tm_sec);
-       }
-       if (cs->notafter != UNSPEC) {
-           struct tm *tm = gmtime(&cs->notafter);
-           printf("NOTAFTER=%04d%02d%02d%02d%02d%02dZ ",
-               tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-               tm->tm_hour, tm->tm_min, tm->tm_sec);
-       }
-       if (TAG_CHANGED(follow))
-           printf("%sFOLLOW: ", cs->tags.follow ? "" : "NO");
-       if (TAG_CHANGED(log_input))
-           printf("%sLOG_INPUT: ", cs->tags.log_input ? "" : "NO");
-       if (TAG_CHANGED(log_output))
-           printf("%sLOG_OUTPUT: ", cs->tags.log_output ? "" : "NO");
-       if (TAG_CHANGED(noexec))
-           printf("%sEXEC: ", cs->tags.noexec ? "NO" : "");
-       if (TAG_CHANGED(nopasswd))
-           printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : "");
-       if (TAG_CHANGED(send_mail))
-           printf("%sMAIL: ", cs->tags.send_mail ? "" : "NO");
-       if (TAG_CHANGED(setenv))
-           printf("%sSETENV: ", cs->tags.setenv ? "" : "NO");
-       print_member(cs->cmnd);
-       memcpy(&tags, &cs->tags, sizeof(tags));
+
+    /* Print Aliases */
+    if (!print_aliases(lbuf))
+       goto done;
+    if (lbuf->len > 1) {
+       sudo_lbuf_print(lbuf);
+       sudo_lbuf_append(lbuf, "\n");
     }
-    debug_return;
-}
 
-void
-print_userspecs(void)
-{
-    struct member *m;
-    struct userspec *us;
-    struct privilege *priv;
-    debug_decl(print_userspecs, SUDOERS_DEBUG_UTIL)
+    /* Print User_Specs */
+    if (!sudoers_format_userspecs(lbuf, &userspecs, NULL, false, true))
+       goto done;
+    if (lbuf->len > 1) {
+       sudo_lbuf_print(lbuf);
+    }
 
-    TAILQ_FOREACH(us, &userspecs, entries) {
-       TAILQ_FOREACH(m, &us->users, entries) {
-           if (m != TAILQ_FIRST(&us->users))
-               fputs(", ", stdout);
-           print_member(m);
-       }
-       putchar('\t');
-       TAILQ_FOREACH(priv, &us->privileges, entries) {
-           if (priv != TAILQ_FIRST(&us->privileges))
-               fputs(" : ", stdout);
-           print_privilege(priv);
-       }
-       putchar('\n');
+done:
+    if (sudo_lbuf_error(lbuf)) {
+       if (errno == ENOMEM)
+           sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
     }
+
     debug_return;
 }
 
-void
-dump_sudoers(void)
+static int
+testsudoers_output(const char *buf)
 {
-    debug_decl(dump_sudoers, SUDOERS_DEBUG_UTIL)
-
-    print_defaults();
-
-    putchar('\n');
-    alias_apply(print_alias, NULL);
-
-    putchar('\n');
-    print_userspecs();
-
-    debug_return;
+    return fputs(buf, stdout);
 }
 
-static int testsudoers_print(const char *msg)
+static int
+testsudoers_error(const char *buf)
 {
-    return fputs(msg, stderr);
+    return fputs(buf, stderr);
 }
 
-void
+static void
 usage(void)
 {
     (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());