and group databases when matching.
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-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]
+ 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]
are referenced by the filtered policy rules will be
displayed.
+ -\b-M\bM, -\b--\b-m\bma\bat\btc\bch\bh-\b-l\blo\boc\bca\bal\bl
+ When the -\b-m\bm option is also specified, use password and group
+ database information when matching users and groups in the
+ filter. Only users and groups in the filter that exist on
+ the local system will match, and a user's groups will
+ automatically be added to the filter. If the -\b-M\bM is _\bn_\bo_\bt
+ specified, users and groups in the filter do not need to
+ exist on the local system, but all groups used for matching
+ must be explicitly listed in the filter.
+
-\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
.SH "SYNOPSIS"
.HP 11n
\fBcvtsudoers\fR
-[\fB\-ehV\fR]
+[\fB\-ehMV\fR]
[\fB\-b\fR\ \fIdn\fR]
[\fB\-c\fR\ \fIconf_file\fR]
[\fB\-f\fR\ \fIoutput_format\fR]
Only aliases that are referenced by the filtered policy rules will
be displayed.
.TP 12n
+\fB\-M\fR, \fB\--match-local\fR
+When the
+\fB\-m\fR
+option is also specified, use password and group database information
+when matching users and groups in the filter.
+Only users and groups in the filter that exist on the local system will match,
+and a user's groups will automatically be added to the filter.
+If the
+\fB\-M\fR
+is
+\fInot\fR
+specified, users and groups in the filter do not need to exist on the
+local system, but all groups used for matching must be explicitly listed
+in the filter.
+.TP 12n
\fB\-o\fR \fIoutput_file\fR, \fB\--output\fR=\fIoutput_file\fR
Write the converted output to
\fIoutput_file\fR.
.Nd convert between sudoers file formats
.Sh SYNOPSIS
.Nm cvtsudoers
-.Op Fl ehV
+.Op Fl ehMV
.Op Fl b Ar dn
.Op Fl c Ar conf_file
.Op Fl f Ar output_format
on the local system.
Only aliases that are referenced by the filtered policy rules will
be displayed.
+.It Fl M , Fl -match-local
+When the
+.Fl m
+option is also specified, use password and group database information
+when matching users and groups in the filter.
+Only users and groups in the filter that exist on the local system will match,
+and a user's groups will automatically be added to the filter.
+If the
+.Fl M
+is
+.Em not
+specified, users and groups in the filter do not need to exist on the
+local system, but all groups used for matching must be explicitly listed
+in the filter.
.It Fl o Ar output_file , Fl -output Ns = Ns Ar output_file
Write the converted output to
.Ar output_file .
struct cvtsudoers_filter *filters;
struct sudo_user sudo_user;
struct passwd *list_pw;
-static const char short_opts[] = "b:c:ef:hi:I:m:o:O:s:V";
+static const char short_opts[] = "b:c:ef:hi:I:m:Mo:O:s:V";
static struct option long_opts[] = {
{ "base", required_argument, NULL, 'b' },
{ "config", required_argument, NULL, 'c' },
{ "input-format", required_argument, NULL, 'i' },
{ "increment", required_argument, NULL, 'I' },
{ "match", required_argument, NULL, 'm' },
+ { "match-local", no_argument, NULL, 'M' },
{ "order-start", required_argument, NULL, 'O' },
{ "output", required_argument, NULL, 'o' },
{ "suppress", required_argument, NULL, 's' },
enum sudoers_formats output_format = format_ldif;
enum sudoers_formats input_format = format_sudoers;
struct cvtsudoers_config *conf = NULL;
+ bool match_local = false;
const char *input_file = "-";
const char *output_file = "-";
const char *conf_file = _PATH_CVTSUDOERS_CONF;
case 'm':
conf->filter = optarg;
break;
+ case 'M':
+ match_local = true;
+ break;
case 'o':
output_file = optarg;
break;
}
}
+ /* Set pwutil backend to use the filter data. */
+ if (conf->filter != NULL && !match_local) {
+ sudo_pwutil_set_backend(cvtsudoers_make_pwitem, cvtsudoers_make_gritem,
+ cvtsudoers_make_gidlist_item, cvtsudoers_make_grlist_item);
+ }
+
/* We may need the hostname to resolve %h escapes in include files. */
get_hostname();
return fopen(sudoers, "r");
}
-bool
+static bool
userlist_matches_filter(struct member_list *userlist)
{
struct cvtsudoers_string *s;
debug_return_bool(matches);
}
-bool
+static bool
hostlist_matches_filter(struct member_list *hostlist)
{
struct cvtsudoers_string *s;
static void
usage(int fatal)
{
- (void) fprintf(fatal ? stderr : stdout, "usage: %s [-ehV] [-b dn] "
+ (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());
" -i, --input-format=format set input format: LDIF or sudoers\n"
" -I, --increment=num amount to increase each sudoOrder by\n"
" -h, --help display help message and exit\n"
- " -m, --match=filter only convert entries that match the filter expression\n"
+ " -m, --match=filter only convert entries that match the filter\n"
+ " -M, --match-local match filter uses passwd and group databases\n"
" -o, --output=output_file write converted sudoers to output_file\n"
" -O, --order-start=num starting point for first sudoOrder\n"
" -s, --suppress=sections suppress output of certain sections\n"
struct cvtsudoers_str_list hosts;
};
-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);
-
-struct member_list;
-struct userspec_list;
-bool userlist_matches_filter(struct member_list *userlist);
-bool hostlist_matches_filter(struct member_list *hostlist);
-
+/* cvtsudoers.c */
+extern struct cvtsudoers_filter *filters;
struct cvtsudoers_str_list *str_list_alloc(void);
void str_list_free(void *v);
struct cvtsudoers_string *cvtsudoers_string_alloc(const char *s);
void cvtsudoers_string_free(struct cvtsudoers_string *ls);
-extern struct cvtsudoers_filter *filters;
+/* cvtsudoers_json.c */
+bool convert_sudoers_json(const char *output_file, struct cvtsudoers_config *conf);
+
+/* cvtsudoers_ldif.c */
+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);
+
+/* cvtsudoers_pwutil.c */
+struct cache_item *cvtsudoers_make_pwitem(uid_t uid, const char *name);
+struct cache_item *cvtsudoers_make_gritem(gid_t gid, const char *name);
+struct cache_item *cvtsudoers_make_gidlist_item(const struct passwd *pw, char * const *unused1, unsigned int type);
+struct cache_item *cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1);
#endif /* SUDOERS_CVTSUDOERS_H */
* to ENOMEM or ENOENT respectively.
*/
struct cache_item *
-sudo_make_pwitem(uid_t uid, const char *name)
+cvtsudoers_make_pwitem(uid_t uid, const char *name)
{
char *cp, uidstr[MAX_UID_T_LEN + 2];
size_t nsize, psize, csize, gsize, dsize, ssize, total;
* to ENOMEM or ENOENT respectively.
*/
struct cache_item *
-sudo_make_gritem(gid_t gid, const char *name)
+cvtsudoers_make_gritem(gid_t gid, const char *name)
{
char *cp, gidstr[MAX_UID_T_LEN + 2];
size_t nsize, psize, nmem, total, len;
* elements. Fills in datum from user_gids or from getgrouplist(3).
*/
struct cache_item *
-sudo_make_gidlist_item(const struct passwd *pw, char * const *unused1,
+cvtsudoers_make_gidlist_item(const struct passwd *pw, char * const *unused1,
unsigned int type)
{
char *cp;
* elements. Fills in group names from a call to sudo_get_gidlist().
*/
struct cache_item *
-sudo_make_grlist_item(const struct passwd *pw, char * const *unused1)
+cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1)
{
char *cp;
size_t nsize, ngroups, total, len;
static int cmp_pwnam(const void *, const void *);
static int cmp_grgid(const void *, const void *);
+/*
+ * Default functions for building cache items.
+ */
+static sudo_make_pwitem_t make_pwitem = sudo_make_pwitem;
+static sudo_make_gritem_t make_gritem = sudo_make_gritem;
+static sudo_make_gidlist_item_t make_gidlist_item = sudo_make_gidlist_item;
+static sudo_make_grlist_item_t make_grlist_item = sudo_make_grlist_item;
+
#define cmp_grnam cmp_pwnam
/*
# define getauthregistry(u, r) ((r)[0] = '\0')
#endif
+/*
+ * Change the default pwutil backend functions.
+ * The default functions query the password and group databases.
+ */
+void
+sudo_pwutil_set_backend(sudo_make_pwitem_t pwitem, sudo_make_gritem_t gritem,
+ sudo_make_gidlist_item_t gidlist_item, sudo_make_grlist_item_t grlist_item)
+{
+ debug_decl(sudo_pwutil_set_backend, SUDOERS_DEBUG_NSS)
+
+ make_pwitem = pwitem;
+ make_gritem = gritem;
+ make_gidlist_item = gidlist_item;
+ make_grlist_item = grlist_item;
+
+ debug_return;
+}
+
/*
* Compare by user ID.
* v1 is the key to find or data to insert, v2 is in-tree data.
#ifdef HAVE_SETAUTHDB
aix_setauthdb(IDtouser(uid), key.registry);
#endif
- item = sudo_make_pwitem(uid, NULL);
+ item = make_pwitem(uid, NULL);
#ifdef HAVE_SETAUTHDB
aix_restoreauthdb();
#endif
#ifdef HAVE_SETAUTHDB
aix_setauthdb((char *) name, key.registry);
#endif
- item = sudo_make_pwitem((uid_t)-1, name);
+ item = make_pwitem((uid_t)-1, name);
#ifdef HAVE_SETAUTHDB
aix_restoreauthdb();
#endif
/*
* Cache group db entry if it exists or a negative response if not.
*/
- item = sudo_make_gritem(gid, NULL);
+ item = make_gritem(gid, NULL);
if (item == NULL) {
if (errno != ENOENT || (item = calloc(1, sizeof(*item))) == NULL) {
sudo_warnx(U_("unable to cache gid %u, out of memory"),
/*
* Cache group db entry if it exists or a negative response if not.
*/
- item = sudo_make_gritem((gid_t)-1, name);
+ item = make_gritem((gid_t)-1, name);
if (item == NULL) {
const size_t len = strlen(name) + 1;
if (errno != ENOENT || (item = calloc(1, sizeof(*item) + len)) == NULL) {
/*
* Cache group db entry if it exists or a negative response if not.
*/
- item = sudo_make_grlist_item(pw, NULL);
+ item = make_grlist_item(pw, NULL);
if (item == NULL) {
/* Out of memory? */
debug_return_ptr(NULL);
key.k.name = pw->pw_name;
getauthregistry(NULL, key.registry);
if ((node = rbfind(grlist_cache, &key)) == NULL) {
- if ((item = sudo_make_grlist_item(pw, groups)) == NULL) {
+ if ((item = make_grlist_item(pw, groups)) == NULL) {
sudo_warnx(U_("unable to parse groups for %s"), pw->pw_name);
debug_return_int(-1);
}
/*
* Cache group db entry if it exists or a negative response if not.
*/
- item = sudo_make_gidlist_item(pw, NULL, type);
+ item = make_gidlist_item(pw, NULL, type);
if (item == NULL) {
/* Out of memory? */
debug_return_ptr(NULL);
key.type = type;
getauthregistry(NULL, key.registry);
if ((node = rbfind(gidlist_cache, &key)) == NULL) {
- if ((item = sudo_make_gidlist_item(pw, gids, type)) == NULL) {
+ if ((item = make_gidlist_item(pw, gids, type)) == NULL) {
sudo_warnx(U_("unable to parse gids for %s"), pw->pw_name);
debug_return_int(-1);
}
int display_cmnd(struct sudo_nss_list *, struct passwd *);
/* pwutil.c */
+typedef struct cache_item * (*sudo_make_pwitem_t)(uid_t uid, const char *user);
+typedef struct cache_item * (*sudo_make_gritem_t)(gid_t gid, const char *group);
+typedef struct cache_item * (*sudo_make_gidlist_item_t)(const struct passwd *pw, char * const *gids, unsigned int type);
+typedef struct cache_item * (*sudo_make_grlist_item_t)(const struct passwd *pw, char * const *groups);
__dso_public struct group *sudo_getgrgid(gid_t);
__dso_public struct group *sudo_getgrnam(const char *);
__dso_public void sudo_gr_addref(struct group *);
void sudo_pw_delref(struct passwd *);
int sudo_set_gidlist(struct passwd *pw, char * const *gids, unsigned int type);
int sudo_set_grlist(struct passwd *pw, char * const *groups);
+void sudo_pwutil_set_backend(sudo_make_pwitem_t, sudo_make_gritem_t, sudo_make_gidlist_item_t, sudo_make_grlist_item_t);
void sudo_setspent(void);
/* timestr.c */