plugins/sudoers/check.c
plugins/sudoers/check.h
plugins/sudoers/cvtsudoers.c
+plugins/sudoers/cvtsudoers.h
plugins/sudoers/cvtsudoers_json.c
plugins/sudoers/cvtsudoers_ldif.c
plugins/sudoers/def_data.c
c\bcv\bvt\bts\bsu\bud\bdo\boe\ber\brs\bs - convert between sudoers file formats
S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
- c\bcv\bvt\bts\bsu\bud\bdo\boe\ber\brs\bs [-\b-e\beh\bhV\bV] [-\b-b\bb _\bd_\bn] [-\b-i\bi _\bi_\bn_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt] [-\b-f\bf _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt]
- [-\b-o\bo _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be] [_\bi_\bn_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be]
+ c\bcv\bvt\bts\bsu\bud\bdo\boe\ber\brs\bs [-\b-e\beh\bhV\bV] [-\b-b\bb _\bd_\bn] [-\b-c\bc _\bc_\bo_\bn_\bf_\b__\bf_\bi_\bl_\be] [-\b-I\bI _\bi_\bn_\bc_\br_\be_\bm_\be_\bn_\bt] [-\b-i\bi _\bi_\bn_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt]
+ [-\b-f\bf _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt] [-\b-O\bO _\bs_\bt_\ba_\br_\bt_\b__\bp_\bo_\bi_\bn_\bt] [-\b-o\bo _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be]
+ [_\bi_\bn_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be]
D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
c\bcv\bvt\bts\bsu\bud\bdo\boe\ber\brs\bs can be used to convert between _\bs_\bu_\bd_\bo_\be_\br_\bs security policy file
environment variable will be used instead. Only necessary
when converting to LDIF format.
+ -\b-c\bc, -\b--\b-c\bco\bon\bnf\bfi\big\bg
+ Specify the path to a configuration file. Defaults to
+ _\b/_\be_\bt_\bc_\b/_\bc_\bv_\bt_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bc_\bo_\bn_\bf.
+
-\b-e\be, -\b--\b-e\bex\bxp\bpa\ban\bnd\bd-\b-a\bal\bli\bia\bas\bse\bes\bs
Expand aliases in _\bi_\bn_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be. Aliases are preserved by
default when the output _\bf_\bo_\br_\bm_\ba_\bt is JSON or sudoers.
-\b-h\bh, -\b--\b-h\bhe\bel\blp\bp Display a short help message to the standard output and exit.
- -\b-o\bo _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be, -\b--\b-o\bou\but\btp\bpu\but\bt=_\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be
- Write the converted output to _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be. If no _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be
- is specified, or if it is `-', the converted _\bs_\bu_\bd_\bo_\be_\br_\bs policy
- will be written to the standard output.
+ -\b-I\bI _\bi_\bn_\bc_\br_\be_\bm_\be_\bn_\bt, -\b--\b-i\bin\bnc\bcr\bre\bem\bme\ben\bnt\bt=_\bi_\bn_\bc_\br_\be_\bm_\be_\bn_\bt
+ When generating LDIF output, increment each sudoOrder
+ attribute by the specified number. Defaults to an increment
+ of 1.
-\b-i\bi _\bi_\bn_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt, -\b--\b-i\bin\bnp\bpu\but\bt-\b-f\bfo\bor\brm\bma\bat\bt=_\bi_\bn_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt
Specify the input format. The following formats are
sudoers Traditional sudoers format. This is the default
input format.
+ -\b-O\bO _\bs_\bt_\ba_\br_\bt_\b__\bp_\bo_\bi_\bn_\bt, -\b--\b-o\bor\brd\bde\ber\br-\b-s\bst\bta\bar\brt\bt=_\bs_\bt_\ba_\br_\bt_\b__\bp_\bo_\bi_\bn_\bt
+ When generating LDIF output, use the number specified by
+ _\bs_\bt_\ba_\br_\bt_\b__\bp_\bo_\bi_\bn_\bt in the sudoOrder attribute of the first sudoRole
+ object. Subsequent sudoRole object use a sudoOrder value
+ generated by adding an _\bi_\bn_\bc_\br_\be_\bm_\be_\bn_\bt, see the -\b-I\bI option for
+ details. Defaults to a starting point of 1.
+
+ -\b-o\bo _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be, -\b--\b-o\bou\but\btp\bpu\but\bt=_\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be
+ Write the converted output to _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be. If no _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be
+ is specified, or if it is `-', the converted _\bs_\bu_\bd_\bo_\be_\br_\bs policy
+ will be written to the standard output.
+
-\b-V\bV, -\b--\b-v\bve\ber\brs\bsi\bio\bon\bn
Print the c\bcv\bvt\bts\bsu\bud\bdo\boe\ber\brs\bs and _\bs_\bu_\bd_\bo_\be_\br_\bs grammar versions and exit.
+ Options in the form "keyword = value" may also be specified in a
+ configuration file, _\b/_\be_\bt_\bc_\b/_\bc_\bv_\bt_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bc_\bo_\bn_\bf by default. The following
+ keywords are recognized:
+
+ e\bex\bxp\bpa\ban\bnd\bd_\b_a\bal\bli\bia\bas\bse\bes\bs =\b= _\by_\be_\bs | _\bn_\bo
+ See the description of the -\b-e\be command line option.
+
+ i\bin\bnp\bpu\but\bt_\b_f\bfo\bor\brm\bma\bat\bt =\b= _\bl_\bd_\bi_\bf | _\bs_\bu_\bd_\bo_\be_\br_\bs
+ See the description of the -\b-i\bi command line option.
+
+ o\bor\brd\bde\ber\br_\b_i\bin\bnc\bcr\bre\bem\bme\ben\bnt\bt =\b= _\bi_\bn_\bc_\br_\be_\bm_\be_\bn_\bt
+ See the description of the -\b-I\bI command line option.
+
+ o\bor\brd\bde\ber\br_\b_s\bst\bta\bar\brt\bt =\b= _\bs_\bt_\ba_\br_\bt_\b__\bp_\bo_\br_\bt
+ See the description of the -\b-O\bO command line option.
+
+ o\bou\but\btp\bpu\but\bt_\b_f\bfo\bor\brm\bma\bat\bt =\b= _\bj_\bs_\bo_\bn | _\bl_\bd_\bi_\bf | _\bs_\bu_\bd_\bo_\be_\br_\bs
+ See the description of the -\b-f\bf command line option.
+
+ s\bsu\bud\bdo\boe\ber\brs\bs_\b_b\bba\bas\bse\be =\b= _\bd_\bn
+ See the description of the -\b-b\bb command line option.
+
+ Options on the command line will override values from the configuration
+ file.
+
+F\bFI\bIL\bLE\bES\bS
+ _\b/_\be_\bt_\bc_\b/_\bc_\bv_\bt_\bs_\bu_\bd_\bo_\be_\br_\bs_\b._\bc_\bo_\bn_\bf default configuration for cvtsudoers
+
S\bSE\bEE\bE A\bAL\bLS\bSO\bO
sudoers(4), sudoers.ldap(4), sudo(1m)
file distributed with s\bsu\bud\bdo\bo or https://www.sudo.ws/license.html for
complete details.
-Sudo 1.8.23 February 22, 2018 Sudo 1.8.23
+Sudo 1.8.23 February 23, 2018 Sudo 1.8.23
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.TH "CVTSUDOERS" "8" "February 22, 2018" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
+.TH "CVTSUDOERS" "8" "February 23, 2018" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
.nh
.if n .ad l
.SH "NAME"
\fBcvtsudoers\fR
[\fB\-ehV\fR]
[\fB\-b\fR\ \fIdn\fR]
+[\fB\-c\fR\ \fIconf_file\fR]
+[\fB\-I\fR\ \fIincrement\fR]
[\fB\-i\fR\ \fIinput_format\fR]
[\fB\-f\fR\ \fIoutput_format\fR]
+[\fB\-O\fR\ \fIstart_point\fR]
[\fB\-o\fR\ \fIoutput_file\fR]
[\fIinput_file\fR]
.SH "DESCRIPTION"
environment variable will be used instead.
Only necessary when converting to LDIF format.
.TP 12n
+\fB\-c\fR, \fB\--config\fR
+Specify the path to a configuration file.
+Defaults to
+\fI@sysconfdir@/cvtsudoers.conf\fR.
+.TP 12n
\fB\-e\fR, \fB\--expand-aliases\fR
Expand aliases in
\fIinput_file\fR.
\fB\-h\fR, \fB\--help\fR
Display a short help message to the standard output and exit.
.TP 12n
-\fB\-o\fR \fIoutput_file\fR, \fB\--output\fR=\fIoutput_file\fR
-Write the converted output to
-\fIoutput_file\fR.
-If no
-\fIoutput_file\fR
-is specified, or if it is
-\(oq-\(cq,
-the converted
-\fIsudoers\fR
-policy will be written to the standard output.
+\fB\-I\fR \fIincrement\fR, \fB\--increment\fR=\fIincrement\fR
+When generating LDIF output, increment each sudoOrder attribute by
+the specified number.
+Defaults to an increment of 1.
.TP 12n
\fB\-i\fR \fIinput_format\fR, \fB\--input-format\fR=\fIinput_format\fR
Specify the input format.
.RE
.PD
.TP 12n
+\fB\-O\fR \fIstart_point\fR, \fB\--order-start\fR=\fIstart_point\fR
+When generating LDIF output, use the number specified by
+\fIstart_point\fR
+in the sudoOrder attribute of the first sudoRole object.
+Subsequent sudoRole object use a sudoOrder value generated by adding an
+\fIincrement\fR,
+see the
+\fB\-I\fR
+option for details.
+Defaults to a starting point of 1.
+.TP 12n
+\fB\-o\fR \fIoutput_file\fR, \fB\--output\fR=\fIoutput_file\fR
+Write the converted output to
+\fIoutput_file\fR.
+If no
+\fIoutput_file\fR
+is specified, or if it is
+\(oq-\(cq,
+the converted
+\fIsudoers\fR
+policy will be written to the standard output.
+.TP 12n
\fB\-V\fR, \fB\--version\fR
Print the
\fBcvtsudoers\fR
and
\fIsudoers\fR
grammar versions and exit.
+.PP
+Options in the form
+\(Lqkeyword = value\(Rq
+may also be specified in a configuration file,
+\fI@sysconfdir@/cvtsudoers.conf\fR
+by default.
+The following keywords are recognized:
+.TP 6n
+\fBexpand_aliases =\fR \fIyes\fR | \fIno\fR
+See the description of the
+\fB\-e\fR
+command line option.
+.TP 6n
+\fBinput_format =\fR \fIldif\fR | \fIsudoers\fR
+See the description of the
+\fB\-i\fR
+command line option.
+.TP 6n
+\fBorder_increment =\fR \fIincrement\fR
+See the description of the
+\fB\-I\fR
+command line option.
+.TP 6n
+\fBorder_start =\fR \fIstart_port\fR
+See the description of the
+\fB\-O\fR
+command line option.
+.TP 6n
+\fBoutput_format =\fR \fIjson\fR | \fIldif\fR | \fIsudoers\fR
+See the description of the
+\fB\-f\fR
+command line option.
+.TP 6n
+\fBsudoers_base =\fR \fIdn\fR
+See the description of the
+\fB\-b\fR
+command line option.
+.PP
+Options on the command line will override values from the
+configuration file.
+.SH "FILES"
+.TP 26n
+\fI@sysconfdir@/cvtsudoers.conf\fR
+default configuration for cvtsudoers
.SH "SEE ALSO"
sudoers(@mansectform@),
sudoers.ldap(@mansectform@),
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd February 22, 2018
+.Dd February 23, 2018
.Dt CVTSUDOERS @mansectsu@
.Os Sudo @PACKAGE_VERSION@
.Sh NAME
.Nm cvtsudoers
.Op Fl ehV
.Op Fl b Ar dn
+.Op Fl c Ar conf_file
+.Op Fl I Ar increment
.Op Fl i Ar input_format
.Op Fl f Ar output_format
+.Op Fl O Ar start_point
.Op Fl o Ar output_file
.Op Ar input_file
.Sh DESCRIPTION
.Ev SUDOERS_BASE
environment variable will be used instead.
Only necessary when converting to LDIF format.
+.It Fl c , Fl -config
+Specify the path to a configuration file.
+Defaults to
+.Pa @sysconfdir@/cvtsudoers.conf .
.It Fl e , Fl -expand-aliases
Expand aliases in
.Ar input_file .
.El
.It Fl h , Fl -help
Display a short help message to the standard output and exit.
-.It Fl o Ar output_file , Fl -output Ns = Ns Ar output_file
-Write the converted output to
-.Ar output_file .
-If no
-.Ar output_file
-is specified, or if it is
-.Ql - ,
-the converted
-.Em sudoers
-policy will be written to the standard output.
+.It Fl I Ar increment , Fl -increment Ns = Ns Ar increment
+When generating LDIF output, increment each sudoOrder attribute by
+the specified number.
+Defaults to an increment of 1.
.It Fl i Ar input_format , Fl -input-format Ns = Ns Ar input_format
Specify the input format.
The following formats are supported:
Traditional sudoers format.
This is the default input format.
.El
+.It Fl O Ar start_point , Fl -order-start Ns = Ns Ar start_point
+When generating LDIF output, use the number specified by
+.Ar start_point
+in the sudoOrder attribute of the first sudoRole object.
+Subsequent sudoRole object use a sudoOrder value generated by adding an
+.Ar increment ,
+see the
+.Fl I
+option for details.
+Defaults to a starting point of 1.
+.It Fl o Ar output_file , Fl -output Ns = Ns Ar output_file
+Write the converted output to
+.Ar output_file .
+If no
+.Ar output_file
+is specified, or if it is
+.Ql - ,
+the converted
+.Em sudoers
+policy will be written to the standard output.
.It Fl V , -version
Print the
.Nm
.Em sudoers
grammar versions and exit.
.El
+.Pp
+Options in the form
+.Dq keyword = value
+may also be specified in a configuration file,
+.Pa @sysconfdir@/cvtsudoers.conf
+by default.
+The following keywords are recognized:
+.Bl -tag -width 4n
+.It Sy expand_aliases = Ar yes | no
+See the description of the
+.Fl e
+command line option.
+.It Sy input_format = Ar ldif | sudoers
+See the description of the
+.Fl i
+command line option.
+.It Sy order_increment = Ar increment
+See the description of the
+.Fl I
+command line option.
+.It Sy order_start = Ar start_port
+See the description of the
+.Fl O
+command line option.
+.It Sy output_format = Ar json | ldif | sudoers
+See the description of the
+.Fl f
+command line option.
+.It Sy sudoers_base = Ar dn
+See the description of the
+.Fl b
+command line option.
+.El
+.Pp
+Options on the command line will override values from the
+configuration file.
+.Sh FILES
+.Bl -tag -width 24n
+.It Pa @sysconfdir@/cvtsudoers.conf
+default configuration for cvtsudoers
.El
.Sh SEE ALSO
.Xr sudoers @mansectform@ ,
# define _PATH_SUDOERS "/etc/sudoers"
#endif /* _PATH_SUDOERS */
+/*
+ * NOTE: _PATH_CVTSUDOERS_CONF is usually overridden by the Makefile.
+ */
+#ifndef _PATH_CVTSUDOERS_CONF
+# define _PATH_CVTSUDOERS_CONF "/etc/cvtsudoers.conf"
+#endif /* _PATH_CVTSUDOERS_CONF */
+
/*
* The following paths are controlled via the configure script.
*/
#
-# Copyright (c) 1996, 1998-2005, 2007-2017
+# Copyright (c) 1996, 1998-2005, 2007-2018
# Todd C. Miller <Todd.Miller@sudo.ws>
#
# Permission to use, copy, modify, and distribute this software for any
# C preprocessor defines
CPPDEFS = -DLIBDIR=\"$(libdir)\" -DLOCALEDIR=\"$(localedir)\" \
-D_PATH_SUDOERS=\"$(sudoersdir)/sudoers\" \
+ -D_PATH_CVTSUDOERS_CONF=\"$(sysconfdir)/cvtsudoers.conf\" \
-DSUDOERS_UID=$(sudoers_uid) -DSUDOERS_GID=$(sudoers_gid) \
-DSUDOERS_MODE=$(sudoers_mode)
diff $$toke $(srcdir)/$$toke.ok || true; \
fi; \
total=`expr $$total + 1`; \
- ./cvtsudoers -f json $$t >$$json 2>/dev/null || true; \
+ ./cvtsudoers -c "" -f json $$t >$$json 2>/dev/null || true; \
total=`expr $$total + 1`; \
if cmp $$json $(srcdir)/$$json.ok >/dev/null; then \
passed=`expr $$passed + 1`; \
diff $$json $(srcdir)/$$json.ok || true; \
fi; \
SUDOERS_BASE="ou=SUDOers,dc=sudo,dc=ws" \
- ./cvtsudoers -f ldif $$t >$$ldif 2>/dev/null || true; \
+ ./cvtsudoers -c "" -f ldif $$t >$$ldif 2>/dev/null || true; \
total=`expr $$total + 1`; \
if cmp $$ldif $(srcdir)/$$ldif.ok >/dev/null; then \
passed=`expr $$passed + 1`; \
echo "$$dir/$$base: (ldif) FAIL"; \
diff $$ldif $(srcdir)/$$ldif.ok || true; \
fi; \
- ./cvtsudoers -f sudoers $$t >$$sudo 2>/dev/null || true; \
+ ./cvtsudoers -c "" -f sudoers $$t >$$sudo 2>/dev/null || true; \
total=`expr $$total + 1`; \
if ./visudo -qcf $$sudo; then \
passed=`expr $$passed + 1`; \
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_lbuf.h \
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
- $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
- $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(incdir)/sudo_util.h $(srcdir)/cvtsudoers.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
$(srcdir)/sudoers_debug.h $(srcdir)/sudoers_version.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/cvtsudoers.c
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
- $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
- $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
- $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
- $(top_builddir)/pathnames.h
+ $(srcdir)/cvtsudoers.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/cvtsudoers_json.c
cvtsudoers_ldif.o: $(srcdir)/cvtsudoers_ldif.c $(devdir)/def_data.h \
$(devdir)/gram.h $(incdir)/compat/stdbool.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
- $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
- $(srcdir)/redblack.h $(srcdir)/sudo_ldap.h \
- $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
- $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
- $(top_builddir)/pathnames.h
+ $(srcdir)/cvtsudoers.h $(srcdir)/defaults.h \
+ $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/redblack.h \
+ $(srcdir)/sudo_ldap.h $(srcdir)/sudo_nss.h \
+ $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
+ $(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/cvtsudoers_ldif.c
dce.lo: $(authdir)/dce.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
-#include <unistd.h>
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <unistd.h>
#include "sudoers.h"
#include "parse.h"
#include "sudoers_version.h"
#include "sudo_conf.h"
#include "sudo_lbuf.h"
+#include "cvtsudoers.h"
#include <gram.h>
#ifdef HAVE_GETOPT_LONG
# include "compat/getopt.h"
#endif /* HAVE_GETOPT_LONG */
-static bool convert_sudoers_sudoers(const char *output_file, bool expand_aliases);
-static bool parse_sudoers(const char *input_file);
-extern bool convert_sudoers_json(const char *output_file, bool expand_aliases);
-extern bool convert_sudoers_ldif(const char *output_file, const char *base);
-extern bool parse_ldif(const char *input_file, bool store_options, const char *base);
-extern void get_hostname(void);
-
/*
* Globals
*/
struct sudo_user sudo_user;
struct passwd *list_pw;
-static const char short_opts[] = "b:ef:hi:o:V";
+static const char short_opts[] = "b:c:ef:hi:I:o:O:V";
static struct option long_opts[] = {
{ "base", required_argument, NULL, 'b' },
+ { "config", required_argument, NULL, 'c' },
{ "expand-aliases", no_argument, NULL, 'e' },
- { "format", required_argument, NULL, 'f' },
+ { "output-format", required_argument, NULL, 'f' },
{ "help", no_argument, NULL, 'h' },
{ "input-format", required_argument, NULL, 'i' },
+ { "increment", required_argument, NULL, 'I' },
+ { "order-start", required_argument, NULL, 'O' },
{ "output", required_argument, NULL, 'o' },
{ "version", no_argument, NULL, 'V' },
{ NULL, no_argument, NULL, '\0' },
__dso_public int main(int argc, char *argv[]);
static void help(void) __attribute__((__noreturn__));
static void usage(int);
-
-enum sudoers_formats {
- format_json,
- format_ldif,
- format_sudoers
-};
+static bool convert_sudoers_sudoers(const char *output_file, struct cvtsudoers_config *conf);
+static bool parse_sudoers(const char *input_file, struct cvtsudoers_config *conf);
+static struct cvtsudoers_config *cvtsudoers_conf_read(const char *conf_file);
+static void cvtsudoers_conf_free(struct cvtsudoers_config *conf);
int
main(int argc, char *argv[])
int ch, exitcode = EXIT_FAILURE;
enum sudoers_formats output_format = format_ldif;
enum sudoers_formats input_format = format_sudoers;
- bool store_options = true;
+ struct cvtsudoers_config *conf;
const char *input_file = "-";
const char *output_file = "-";
- const char *sudoers_base = NULL;
- bool expand_aliases = false;
+ const char *conf_file = _PATH_CVTSUDOERS_CONF;
+ const char *errstr;
debug_decl(main, SUDOERS_DEBUG_MAIN)
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
if (!sudoers_debug_register(getprogname(), sudo_conf_debug_files(getprogname())))
goto done;
+ /* Check for --config option first (no getopt warnings). */
+ opterr = 0;
+ while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
+ switch (ch) {
+ case 'c':
+ conf_file = optarg;
+ break;
+ }
+ }
+
+ /* Read conf file. */
+ conf = cvtsudoers_conf_read(conf_file);
+
/*
- * Arg handling.
+ * Reset getopt and handle the rest of the arguments.
*/
+ opterr = 1;
+ optind = 1;
+#ifdef HAVE_OPTRESET
+ optreset = 1;
+#endif
while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
switch (ch) {
case 'b':
- sudoers_base = optarg;
+ free(conf->sudoers_base);
+ conf->sudoers_base = strdup(optarg);
+ if (conf->sudoers_base == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ break;
+ case 'c':
+ /* handled above */
break;
case 'e':
- expand_aliases = true;
+ conf->expand_aliases = true;
break;
case 'f':
- if (strcasecmp(optarg, "json") == 0) {
- output_format = format_json;
- store_options = true;
- } else if (strcasecmp(optarg, "ldif") == 0) {
- output_format = format_ldif;
- store_options = true;
- } else if (strcasecmp(optarg, "sudoers") == 0) {
- output_format = format_sudoers;
- store_options = false;
- } else {
- sudo_warnx("unsupported output format %s", optarg);
- usage(1);
+ free(conf->output_format);
+ conf->output_format = strdup(optarg);
+ if (conf->output_format == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
}
break;
case 'h':
help();
break;
case 'i':
- if (strcasecmp(optarg, "ldif") == 0) {
- input_format = format_ldif;
- } else if (strcasecmp(optarg, "sudoers") == 0) {
- input_format = format_sudoers;
- } else {
- sudo_warnx("unsupported input format %s", optarg);
+ free(conf->input_format);
+ conf->input_format = strdup(optarg);
+ if (conf->input_format == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ break;
+ case 'I':
+ conf->order_increment = sudo_strtonum(optarg, 1, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("order increment: %s: %s"), optarg, U_(errstr));
usage(1);
}
break;
case 'o':
output_file = optarg;
break;
+ case 'O':
+ conf->sudo_order = sudo_strtonum(optarg, 1, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("starting order: %s: %s"), optarg, U_(errstr));
+ usage(1);
+ }
+ break;
case 'V':
(void) printf(_("%s version %s\n"), getprogname(),
PACKAGE_VERSION);
argc -= optind;
argv += optind;
+ if (conf->input_format != NULL) {
+ if (strcasecmp(conf->input_format, "ldif") == 0) {
+ input_format = format_ldif;
+ } else if (strcasecmp(conf->input_format, "sudoers") == 0) {
+ input_format = format_sudoers;
+ } else {
+ sudo_warnx(U_("unsupported input format %s"), conf->input_format);
+ usage(1);
+ }
+ }
+ if (conf->output_format != NULL) {
+ if (strcasecmp(conf->output_format, "json") == 0) {
+ output_format = format_json;
+ conf->store_options = true;
+ } else if (strcasecmp(conf->output_format, "ldif") == 0) {
+ output_format = format_ldif;
+ conf->store_options = true;
+ } else if (strcasecmp(conf->output_format, "sudoers") == 0) {
+ output_format = format_sudoers;
+ conf->store_options = false;
+ } else {
+ sudo_warnx(U_("unsupported output format %s"), conf->output_format);
+ usage(1);
+ }
+ }
+
/* If no base DN specified, check SUDOERS_BASE. */
- if (sudoers_base == NULL)
- sudoers_base = getenv("SUDOERS_BASE");
+ if (conf->sudoers_base == NULL) {
+ conf->sudoers_base = getenv("SUDOERS_BASE");
+ if (conf->sudoers_base != NULL && *conf->sudoers_base != '\0') {
+ if ((conf->sudoers_base = strdup(conf->sudoers_base)) == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ }
+ }
/* Input file (defaults to stdin). */
if (argc > 0) {
if (argc > 1)
usage(1);
- input_file = argv[0];
+ input_file = argv[0];
}
if (strcmp(input_file, "-") != 0) {
}
/* Mock up a fake sudo_user struct. */
- /* XXX - common with visudo */
+ /* XXX - should not be required */
user_cmnd = user_base = "";
if (geteuid() == 0) {
const char *user = getenv("SUDO_USER");
switch (input_format) {
case format_ldif:
- if (!parse_ldif(input_file, store_options, sudoers_base))
+ if (!parse_ldif(input_file, conf))
goto done;
break;
case format_sudoers:
- if (!parse_sudoers(input_file))
+ if (!parse_sudoers(input_file, conf))
goto done;
break;
default:
switch (output_format) {
case format_json:
- exitcode = !convert_sudoers_json(output_file, expand_aliases);
+ exitcode = !convert_sudoers_json(output_file, conf);
break;
case format_ldif:
- exitcode = !convert_sudoers_ldif(output_file, sudoers_base);
+ exitcode = !convert_sudoers_ldif(output_file, conf);
break;
case format_sudoers:
- exitcode = !convert_sudoers_sudoers(output_file, expand_aliases);
+ exitcode = !convert_sudoers_sudoers(output_file, conf);
break;
default:
sudo_fatalx("error: unhandled output format %d", output_format);
}
done:
+ cvtsudoers_conf_free(conf);
sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
return exitcode;
}
+/*
+ * cvtsudoers configuration data.
+ */
+static struct cvtsudoers_config cvtsudoers_config = INITIAL_CONFIG;
+static struct cvtsudoers_conf_table cvtsudoers_conf_vars[] = {
+ { "order_start", CONF_UINT, &cvtsudoers_config.sudo_order },
+ { "order_increment", CONF_UINT, &cvtsudoers_config.order_increment },
+ { "sudoers_base", CONF_STR, &cvtsudoers_config.sudoers_base },
+ { "input_format", CONF_STR, &cvtsudoers_config.input_format },
+ { "output_format", CONF_STR, &cvtsudoers_config.output_format },
+ { "expand_aliases", CONF_BOOL, &cvtsudoers_config.expand_aliases }
+};
+
+/*
+ * Look up keyword in config table.
+ * Returns true if found, else false.
+ */
+static bool
+cvtsudoers_parse_keyword(const char *conf_file, const char *keyword,
+ const char *value, struct cvtsudoers_conf_table *table)
+{
+ struct cvtsudoers_conf_table *cur;
+ const char *errstr;
+ debug_decl(sudo_ldap_parse_keyword, SUDOERS_DEBUG_UTIL)
+
+ /* Look up keyword in config tables */
+ for (cur = table; cur->conf_str != NULL; cur++) {
+ if (strcasecmp(keyword, cur->conf_str) == 0) {
+ switch (cur->type) {
+ case CONF_BOOL:
+ *(bool *)(cur->valp) = sudo_strtobool(value) == true;
+ break;
+ case CONF_UINT:
+ {
+ unsigned int uval =
+ strtonum(value, 0, UINT_MAX, &errstr);
+ if (errstr != NULL) {
+ sudo_warnx(U_("%s: %s: %s: %s"),
+ conf_file, keyword, value, U_(errstr));
+ continue;
+ }
+ *(unsigned int *)(cur->valp) = uval;
+ }
+ break;
+ case CONF_STR:
+ {
+ char *cp = strdup(value);
+ if (cp == NULL) {
+ sudo_fatalx(U_("%s: %s"), __func__,
+ U_("unable to allocate memory"));
+ }
+ free(*(char **)(cur->valp));
+ *(char **)(cur->valp) = cp;
+ break;
+ }
+ }
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false);
+}
+
+static struct cvtsudoers_config *
+cvtsudoers_conf_read(const char *conf_file)
+{
+ char *line = NULL;
+ size_t linesize = 0;
+ FILE *fp;
+ debug_decl(cvtsudoers_conf_read, SUDOERS_DEBUG_UTIL)
+
+ if ((fp = fopen(conf_file, "r")) == NULL)
+ debug_return_ptr(&cvtsudoers_config);
+
+ while (sudo_parseln(&line, &linesize, NULL, fp, 0) != -1) {
+ char *cp, *keyword, *value;
+
+ if (*line == '\0')
+ continue; /* skip empty line */
+
+ /* Parse keyword = value */
+ keyword = line;
+ if ((cp = strchr(line, '=')) == NULL)
+ continue;
+ value = cp-- + 1;
+
+ /* Trim whitespace after keyword. */
+ while (cp != line && isblank((unsigned char)cp[-1]))
+ cp--;
+ *cp = '\0';
+
+ /* Trim whitespace before value. */
+ while (isblank((unsigned char)*value))
+ value++;
+
+ /* Look up keyword in config tables */
+ if (!cvtsudoers_parse_keyword(conf_file, keyword, value, cvtsudoers_conf_vars))
+ sudo_warnx(U_("%s: unknown key word: %s"), conf_file, keyword);
+ }
+ free(line);
+ fclose(fp);
+
+ debug_return_ptr(&cvtsudoers_config);
+}
+
+static void
+cvtsudoers_conf_free(struct cvtsudoers_config *conf)
+{
+ debug_decl(cvtsudoers_conf_free, SUDOERS_DEBUG_UTIL)
+
+ free(conf->sudoers_base);
+ free(conf->input_format);
+ free(conf->output_format);
+ conf->sudoers_base = NULL;
+ conf->input_format = NULL;
+ conf->output_format = NULL;
+
+ debug_return;
+}
+
static bool
-parse_sudoers(const char *input_file)
+parse_sudoers(const char *input_file, struct cvtsudoers_config *conf)
{
debug_decl(parse_sudoers, SUDOERS_DEBUG_UTIL)
* Convert back to sudoers.
*/
static bool
-convert_sudoers_sudoers(const char *output_file, bool expand_aliases)
+convert_sudoers_sudoers(const char *output_file, struct cvtsudoers_config *conf)
{
bool ret = true;
struct sudo_lbuf lbuf;
sudo_lbuf_init(&lbuf, convert_sudoers_output, 4, "\\", 80);
/* Print Defaults */
- if (!print_defaults_sudoers(&lbuf, expand_aliases))
+ if (!print_defaults_sudoers(&lbuf, conf->expand_aliases))
goto done;
if (lbuf.len > 0) {
sudo_lbuf_print(&lbuf);
}
/* Print Aliases */
- if (!expand_aliases) {
+ if (!conf->expand_aliases) {
if (!print_aliases_sudoers(&lbuf))
goto done;
if (lbuf.len > 1) {
}
/* Print User_Specs */
- if (!sudoers_format_userspecs(&lbuf, &userspecs, expand_aliases))
+ if (!sudoers_format_userspecs(&lbuf, &userspecs, conf->expand_aliases))
goto done;
if (lbuf.len > 1) {
sudo_lbuf_print(&lbuf);
usage(int fatal)
{
(void) fprintf(fatal ? stderr : stdout, "usage: %s [-ehV] [-b dn] "
- "[-f output_format] [-i input_format] [-o output_file] [input_file]\n",
+ "[-c conf_file ] [-f output_format] [-i input_format] [-I increment] "
+ "[-o output_file] [-O start_point] [input_file]\n",
getprogname());
if (fatal)
exit(1);
(void) printf(_("%s - convert between sudoers file formats\n\n"), getprogname());
usage(0);
(void) puts(_("\nOptions:\n"
- " -b, --base=dn the base DN for sudo LDAP queries\n"
- " -f, --format=JSON|LDIF specify output format (JSON or LDIF)\n"
- " -h, --help display help message and exit\n"
- " -o, --output=output_file write converted sudoers to output_file\n"
- " -V, --version display version information and exit"));
+ " -b, --base=dn the base DN for sudo LDAP queries\n"
+ " -e, --expand-aliases expand aliases when converting\n"
+ " -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
+ " -I, --increment=num amount to increase each sudoOrder by\n"
+ " -i, --input-format=format set input format: LDIF or sudoers\n"
+ " -h, --help display help message and exit\n"
+ " -O, --order-start=num starting point for first sudoOrder\n"
+ " -o, --output=output_file write converted sudoers to output_file\n"
+ " -V, --version display version information and exit"));
exit(0);
}
--- /dev/null
+/*
+ * Copyright (c) 2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SUDOERS_CVTSUDOERS_H
+#define SUDOERS_CVTSUDOERS_H
+
+/* Supported input/output formats. */
+enum sudoers_formats {
+ format_json,
+ format_ldif,
+ format_sudoers
+};
+
+/* cvtsudoers.conf settings */
+struct cvtsudoers_config {
+ char *sudoers_base;
+ char *input_format;
+ char *output_format;
+ unsigned int sudo_order;
+ unsigned int order_increment;
+ bool expand_aliases;
+ bool store_options;
+};
+
+/* Initial config settings for above. */
+#define INITIAL_CONFIG { NULL, NULL, NULL, 1, 1, false, true }
+
+#define CONF_BOOL 0
+#define CONF_UINT 1
+#define CONF_STR 2
+
+struct cvtsudoers_conf_table {
+ const char *conf_str; /* config file string */
+ int type; /* CONF_BOOL, CONF_UINT, CONF_STR */
+ void *valp; /* pointer into cvtsudoers_config */
+};
+
+bool convert_sudoers_json(const char *output_file, struct cvtsudoers_config *conf);
+bool convert_sudoers_ldif(const char *output_file, struct cvtsudoers_config *conf);
+bool parse_ldif(const char *input_file, struct cvtsudoers_config *conf);
+void get_hostname(void);
+
+#endif /* SUDOERS_CVTSUDOERS_H */
#include "sudoers.h"
#include "parse.h"
+#include "cvtsudoers.h"
#include <gram.h>
/*
* Export the parsed sudoers file in JSON format.
*/
bool
-convert_sudoers_json(const char *output_file, bool expand_aliases)
+convert_sudoers_json(const char *output_file, struct cvtsudoers_config *conf)
{
bool ret = true, need_comma = false;
const int indent = 4;
FILE *output_fp = stdout;
debug_decl(convert_sudoers_json, SUDOERS_DEBUG_UTIL)
- if (strcmp(output_file, "-") != 0) {
+ if (strcmp(output_file, "-") != 0) {
if ((output_fp = fopen(output_file, "w")) == NULL)
sudo_fatal(U_("unable to open %s"), output_file);
}
putc('{', output_fp);
/* Dump Defaults in JSON format. */
- need_comma = print_defaults_json(output_fp, indent, expand_aliases, need_comma);
+ need_comma = print_defaults_json(output_fp, indent, conf->expand_aliases, need_comma);
/* Dump Aliases in JSON format. */
- if (!expand_aliases)
+ if (!conf->expand_aliases)
need_comma = print_aliases_json(output_fp, indent, need_comma);
/* Dump User_Specs in JSON format. */
- print_userspecs_json(output_fp, indent, expand_aliases, need_comma);
+ print_userspecs_json(output_fp, indent, conf->expand_aliases, need_comma);
/* Close JSON output. */
fputs("\n}\n", output_fp);
#include "sudo_ldap.h"
#include "parse.h"
#include "redblack.h"
+#include "cvtsudoers.h"
#include <gram.h>
struct seen_user {
unsigned long count;
};
-static int sudo_order;
static struct rbtree *seen_users;
static int
* Print a single User_Spec.
*/
static bool
-print_userspec_ldif(FILE *fp, struct userspec *us, const char *base)
+print_userspec_ldif(FILE *fp, struct userspec *us, struct cvtsudoers_config *conf)
{
struct privilege *priv;
struct member *m;
U_("unable to allocate memory"));
}
- fprintf(fp, "dn: cn=%s,%s\n", cn, base);
+ fprintf(fp, "dn: cn=%s,%s\n", cn, conf->sudoers_base);
fprintf(fp, "objectClass: top\n");
fprintf(fp, "objectClass: sudoRole\n");
fprintf(fp, "cn: %s\n", cn);
print_cmndspec_ldif(fp, cs, &next, &priv->defaults);
- fprintf(fp, "sudoOrder: %d\n\n", ++sudo_order);
+ fprintf(fp, "sudoOrder: %d\n\n", conf->sudo_order);
+ conf->sudo_order += conf->order_increment;
}
}
* Print User_Specs.
*/
static bool
-print_userspecs_ldif(FILE *fp, const char *base)
+print_userspecs_ldif(FILE *fp, struct cvtsudoers_config *conf)
{
struct userspec *us;
debug_decl(print_userspecs_ldif, SUDOERS_DEBUG_UTIL)
TAILQ_FOREACH(us, &userspecs, entries) {
- if (!print_userspec_ldif(fp, us, base))
+ if (!print_userspec_ldif(fp, us, conf))
debug_return_bool(false);
}
debug_return_bool(true);
* Export the parsed sudoers file in LDIF format.
*/
bool
-convert_sudoers_ldif(const char *output_file, const char *base)
+convert_sudoers_ldif(const char *output_file, struct cvtsudoers_config *conf)
{
bool ret = true;
FILE *output_fp = stdout;
debug_decl(convert_sudoers_ldif, SUDOERS_DEBUG_UTIL)
- if (base == NULL) {
+ if (conf->sudoers_base == NULL) {
sudo_fatalx(U_("the SUDOERS_BASE environment variable is not set and the -b option was not specified."));
}
- if (strcmp(output_file, "-") != 0) {
+ if (output_file != NULL && strcmp(output_file, "-") != 0) {
if ((output_fp = fopen(output_file, "w")) == NULL)
sudo_fatal(U_("unable to open %s"), output_file);
}
seen_users = rbcreate(seen_user_compare);
/* Dump global Defaults in LDIF format. */
- print_global_defaults_ldif(output_fp, base);
+ print_global_defaults_ldif(output_fp, conf->sudoers_base);
/* Dump User_Specs in LDIF format, expanding Aliases. */
- print_userspecs_ldif(output_fp, base);
+ print_userspecs_ldif(output_fp, conf);
/* Warn about non-translatable Defaults entries. */
warn_bound_defaults_ldif(output_fp);
* create aliases on the fly for multiple users/hosts?
*/
bool
-parse_ldif(const char *input_file, bool store_options, const char *base)
+parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
{
struct sudo_role_list roles = STAILQ_HEAD_INITIALIZER(roles);
struct sudo_role **role_array, *role = NULL;
/* Parse dn and objectClass. */
if (strncasecmp(line, "dn:", 3) == 0) {
/* Compare dn to base, if specified. */
- if (base != NULL) {
+ if (conf->sudoers_base != NULL) {
cp = line + 3;
while (isblank((unsigned char)*cp))
cp++;
if (*cp == ',')
cp++;
}
- if (strcasecmp(cp, base) != 0) {
+ if (strcasecmp(cp, conf->sudoers_base) != 0) {
/* Doesn't match base, skip the rest of it. */
mismatch = true;
continue;
priv = sudo_ldap_role_to_priv(role->cn, STAILQ_FIRST(&role->hosts),
STAILQ_FIRST(&role->runasusers), STAILQ_FIRST(&role->runasgroups),
STAILQ_FIRST(&role->cmnds), STAILQ_FIRST(&role->options),
- role->notbefore, role->notafter, true, store_options,
+ role->notbefore, role->notafter, true, conf->store_options,
ldif_string_iter);
if (priv == NULL) {
sudo_fatalx(U_("%s: %s"), __func__,