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\bhM\bMV\bV] [-\b-b\bb _\bd_\bn] [-\b-c\bc _\bc_\bo_\bn_\bf_\b__\bf_\bi_\bl_\be] [-\b-f\bf _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt]
- [-\b-i\bi _\bi_\bn_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt] [-\b-I\bI _\bi_\bn_\bc_\br_\be_\bm_\be_\bn_\bt] [-\b-m\bm _\bf_\bi_\bl_\bt_\be_\br] [-\b-o\bo _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be]
- [-\b-O\bO _\bs_\bt_\ba_\br_\bt_\b__\bp_\bo_\bi_\bn_\bt] [-\b-s\bs _\bs_\be_\bc_\bt_\bi_\bo_\bn_\bs] [_\bi_\bn_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be]
+ c\bcv\bvt\bts\bsu\bud\bdo\boe\ber\brs\bs [-\b-e\beh\bhM\bMV\bV] [-\b-b\bb _\bd_\bn] [-\b-c\bc _\bc_\bo_\bn_\bf_\b__\bf_\bi_\bl_\be] [-\b-d\bd _\bd_\be_\bf_\bt_\by_\bp_\be_\bs]
+ [-\b-f\bf _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt] [-\b-i\bi _\bi_\bn_\bp_\bu_\bt_\b__\bf_\bo_\br_\bm_\ba_\bt] [-\b-I\bI _\bi_\bn_\bc_\br_\be_\bm_\be_\bn_\bt]
+ [-\b-m\bm _\bf_\bi_\bl_\bt_\be_\br] [-\b-o\bo _\bo_\bu_\bt_\bp_\bu_\bt_\b__\bf_\bi_\bl_\be] [-\b-O\bO _\bs_\bt_\ba_\br_\bt_\b__\bp_\bo_\bi_\bn_\bt] [-\b-s\bs _\bs_\be_\bc_\bt_\bi_\bo_\bn_\bs]
+ [_\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
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-d\bd _\bd_\be_\bf_\bt_\by_\bp_\be_\bs, -\b--\b-d\bde\bef\bfa\bau\bul\blt\bts\bs=_\bd_\be_\bf_\bt_\by_\bp_\be_\bs
+ Only convert Defaults entries of the specified types. One or
+ more Defaults types may be specified, separated by a comma
+ (`,'). The supported types are:
+
+ global Defaults entries that always match.
+
+ user Per-user Defaults entries.
+
+ runas Per-runas user Defaults entries.
+
+ host Per-host Defaults entries.
+
+ commands Per-command Defaults entries.
+
+ See the D\bDe\bef\bfa\bau\bul\blt\bts\bs section in sudoers(4) for more information.
+
+ If the -\b-d\bd option is not specified, all Defaults entries will
+ be converted.
+
-\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.
file distributed with s\bsu\bud\bdo\bo or https://www.sudo.ws/license.html for
complete details.
-Sudo 1.8.23 March 22, 2018 Sudo 1.8.23
+Sudo 1.8.23 March 28, 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" "1" "March 22, 2018" "Sudo @PACKAGE_VERSION@" "General Commands Manual"
+.TH "CVTSUDOERS" "1" "March 28, 2018" "Sudo @PACKAGE_VERSION@" "General Commands Manual"
.nh
.if n .ad l
.SH "NAME"
[\fB\-ehMV\fR]
[\fB\-b\fR\ \fIdn\fR]
[\fB\-c\fR\ \fIconf_file\fR]
+[\fB\-d\fR\ \fIdeftypes\fR]
[\fB\-f\fR\ \fIoutput_format\fR]
[\fB\-i\fR\ \fIinput_format\fR]
[\fB\-I\fR\ \fIincrement\fR]
Defaults to
\fI@sysconfdir@/cvtsudoers.conf\fR.
.TP 12n
+\fB\-d\fR \fIdeftypes\fR, \fB\--defaults\fR=\fIdeftypes\fR
+Only convert
+\fRDefaults\fR
+entries of the specified types.
+One or more
+\fRDefaults\fR
+types may be specified, separated by a comma
+(\(oq\&,\(cq).
+The supported types are:
+.PP
+.RS 12n
+.PD 0
+.TP 10n
+global
+Defaults entries that always match.
+.PD
+.TP 10n
+user
+Per-user Defaults entries.
+.TP 10n
+runas
+Per-runas user Defaults entries.
+.TP 10n
+host
+Per-host Defaults entries.
+.TP 10n
+commands
+Per-command Defaults entries.
+.PP
+See the
+\fBDefaults\fR
+section in
+sudoers(@mansectform@)
+for more information.
+.sp
+If the
+\fB\-d\fR
+option is not specified, all
+\fRDefaults\fR
+entries will be converted.
+.RE
+.TP 12n
\fB\-e\fR, \fB\--expand-aliases\fR
Expand aliases in
\fIinput_file\fR.
struct cvtsudoers_filter *filters;
struct sudo_user sudo_user;
struct passwd *list_pw;
-static const char short_opts[] = "b:c:ef:hi:I:m:Mo:O:s:V";
+static const char short_opts[] = "b:c:d:ef:hi:I:m:Mo:O:s:V";
static struct option long_opts[] = {
{ "base", required_argument, NULL, 'b' },
{ "config", required_argument, NULL, 'c' },
+ { "defaults", required_argument, NULL, 'd' },
{ "expand-aliases", no_argument, NULL, 'e' },
{ "output-format", required_argument, NULL, 'f' },
{ "help", no_argument, NULL, 'h' },
static bool alias_remove_unused(void);
static struct cvtsudoers_config *cvtsudoers_conf_read(const char *conf_file);
static void cvtsudoers_conf_free(struct cvtsudoers_config *conf);
+static int cvtsudoers_parse_defaults(char *expression);
static int cvtsudoers_parse_suppression(char *expression);
static void filter_userspecs(void);
-static void filter_defaults(void);
+static void filter_defaults(struct cvtsudoers_config *conf);
int
main(int argc, char *argv[])
case 'c':
/* handled above */
break;
+ case 'd':
+ conf->defaults = cvtsudoers_parse_defaults(optarg);
+ if (conf->defaults == -1)
+ usage(1);
+ break;
case 'e':
conf->expand_aliases = true;
break;
}
/* Apply filters. */
- if (conf->filter != NULL) {
- filter_userspecs();
-
- filter_defaults();
-
- alias_remove_unused();
- }
+ filter_userspecs();
+ filter_defaults(conf);
+ if (filters != NULL || conf->defaults != CVT_DEFAULTS_ALL)
+ alias_remove_unused();
switch (output_format) {
case format_json:
debug_return;
}
+static int
+cvtsudoers_parse_defaults(char *expression)
+{
+ char *last = NULL, *cp = expression;
+ int flags = 0;
+ debug_decl(cvtsudoers_parse_defaults, SUDOERS_DEBUG_UTIL)
+
+ for ((cp = strtok_r(cp, ",", &last)); cp != NULL; (cp = strtok_r(NULL, ",", &last))) {
+ if (strcasecmp(cp, "global") == 0) {
+ SET(flags, CVT_DEFAULTS_GLOBAL);
+ } else if (strcasecmp(cp, "user") == 0) {
+ SET(flags, CVT_DEFAULTS_USER);
+ } else if (strcasecmp(cp, "runas") == 0) {
+ SET(flags, CVT_DEFAULTS_RUNAS);
+ } else if (strcasecmp(cp, "host") == 0) {
+ SET(flags, CVT_DEFAULTS_HOST);
+ } else if (strcasecmp(cp, "command") == 0) {
+ SET(flags, CVT_DEFAULTS_CMND);
+ } else {
+ sudo_warnx(U_("invalid defaults type: %s"), cp);
+ debug_return_int(-1);
+ }
+ }
+
+ debug_return_int(flags);
+}
+
static int
cvtsudoers_parse_suppression(char *expression)
{
struct privilege *priv, *next_priv;
debug_decl(filter_userspecs, SUDOERS_DEBUG_UTIL)
+ if (filters == NULL)
+ debug_return;
+
/*
* Does not currently prune out non-matching entries in the user or
* host lists. It acts more like a grep than a true filter.
* Apply filters to host/user-based Defaults, removing non-matching entries.
*/
static void
-filter_defaults(void)
+filter_defaults(struct cvtsudoers_config *conf)
{
struct defaults *def, *next;
struct member_list *prev_binding = NULL;
debug_decl(filter_defaults, SUDOERS_DEBUG_DEFAULTS)
+ if (filters == NULL && conf->defaults == CVT_DEFAULTS_ALL)
+ debug_return;
+
TAILQ_FOREACH_SAFE(def, &defaults, entries, next) {
+ bool keep = true;
+
switch (def->type) {
+ case DEFAULTS:
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_GLOBAL))
+ keep = false;
+ break;
case DEFAULTS_USER:
- if (!userlist_matches_filter(def->binding)) {
- TAILQ_REMOVE(&defaults, def, entries);
- free_default(def, &prev_binding);
- } else {
- prev_binding = def->binding;
- }
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_USER) ||
+ !userlist_matches_filter(def->binding))
+ keep = false;
+ break;
+ case DEFAULTS_RUNAS:
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_RUNAS))
+ keep = false;
break;
case DEFAULTS_HOST:
- if (!hostlist_matches_filter(def->binding)) {
- TAILQ_REMOVE(&defaults, def, entries);
- free_default(def, &prev_binding);
- } else {
- prev_binding = def->binding;
- }
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_HOST) ||
+ !hostlist_matches_filter(def->binding))
+ keep = false;
+ break;
+ case DEFAULTS_CMND:
+ if (!ISSET(conf->defaults, CVT_DEFAULTS_RUNAS))
+ keep = false;
break;
default:
+ sudo_fatalx_nodebug("unexpected defaults type %d", def->type);
break;
}
+
+ if (!keep) {
+ TAILQ_REMOVE(&defaults, def, entries);
+ free_default(def, &prev_binding);
+ } else {
+ prev_binding = def->binding;
+ }
}
debug_return;
}
usage(int fatal)
{
(void) fprintf(fatal ? stderr : stdout, "usage: %s [-ehMV] [-b dn] "
- "[-c conf_file ] [-f output_format] [-i input_format] [-I increment] "
- "[-m filter] [-o output_file] [-O start_point] [-s sections] "
- "[input_file]\n", getprogname());
+ "[-c conf_file ] [-d deftypes] [-f output_format] [-i input_format] "
+ "[-I increment] [-m filter] [-o output_file] [-O start_point] "
+ "[-s sections] [input_file]\n", getprogname());
if (fatal)
exit(1);
}
usage(0);
(void) puts(_("\nOptions:\n"
" -b, --base=dn the base DN for sudo LDAP queries\n"
+ " -d, --defaults=deftypes only convert Defaults of the specified types\n"
" -e, --expand-aliases expand aliases when converting\n"
" -f, --output-format=format set output format: JSON, LDIF or sudoers\n"
" -i, --input-format=format set input format: LDIF or sudoers\n"