Add -M option to cvtsudoers to force the use of the local passwd
and group databases when matching.
This commit is contained in:
@@ -4,7 +4,7 @@ NNAAMMEE
|
||||
ccvvttssuuddooeerrss - convert between sudoers file formats
|
||||
|
||||
SSYYNNOOPPSSIISS
|
||||
ccvvttssuuddooeerrss [--eehhVV] [--bb _d_n] [--cc _c_o_n_f___f_i_l_e] [--ff _o_u_t_p_u_t___f_o_r_m_a_t]
|
||||
ccvvttssuuddooeerrss [--eehhMMVV] [--bb _d_n] [--cc _c_o_n_f___f_i_l_e] [--ff _o_u_t_p_u_t___f_o_r_m_a_t]
|
||||
[--ii _i_n_p_u_t___f_o_r_m_a_t] [--II _i_n_c_r_e_m_e_n_t] [--mm _f_i_l_t_e_r] [--oo _o_u_t_p_u_t___f_i_l_e]
|
||||
[--OO _s_t_a_r_t___p_o_i_n_t] [--ss _s_e_c_t_i_o_n_s] [_i_n_p_u_t___f_i_l_e]
|
||||
|
||||
@@ -99,6 +99,16 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
are referenced by the filtered policy rules will be
|
||||
displayed.
|
||||
|
||||
--MM, ----mmaattcchh--llooccaall
|
||||
When the --mm 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 --MM is _n_o_t
|
||||
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.
|
||||
|
||||
--oo _o_u_t_p_u_t___f_i_l_e, ----oouuttppuutt=_o_u_t_p_u_t___f_i_l_e
|
||||
Write the converted output to _o_u_t_p_u_t___f_i_l_e. If no _o_u_t_p_u_t___f_i_l_e
|
||||
is specified, or if it is `-', the converted _s_u_d_o_e_r_s policy
|
||||
|
@@ -25,7 +25,7 @@
|
||||
.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]
|
||||
@@ -191,6 +191,21 @@ on the local system.
|
||||
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.
|
||||
|
@@ -22,7 +22,7 @@
|
||||
.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
|
||||
@@ -155,6 +155,20 @@ against the filter so the users and groups do not need to be present
|
||||
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 .
|
||||
|
@@ -56,7 +56,7 @@
|
||||
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' },
|
||||
@@ -66,6 +66,7 @@ static struct option long_opts[] = {
|
||||
{ "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' },
|
||||
@@ -93,6 +94,7 @@ main(int argc, char *argv[])
|
||||
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;
|
||||
@@ -187,6 +189,9 @@ main(int argc, char *argv[])
|
||||
case 'm':
|
||||
conf->filter = optarg;
|
||||
break;
|
||||
case 'M':
|
||||
match_local = true;
|
||||
break;
|
||||
case 'o':
|
||||
output_file = optarg;
|
||||
break;
|
||||
@@ -272,6 +277,12 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
/* 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();
|
||||
|
||||
@@ -610,7 +621,7 @@ open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
|
||||
return fopen(sudoers, "r");
|
||||
}
|
||||
|
||||
bool
|
||||
static bool
|
||||
userlist_matches_filter(struct member_list *userlist)
|
||||
{
|
||||
struct cvtsudoers_string *s;
|
||||
@@ -658,7 +669,7 @@ userlist_matches_filter(struct member_list *userlist)
|
||||
debug_return_bool(matches);
|
||||
}
|
||||
|
||||
bool
|
||||
static bool
|
||||
hostlist_matches_filter(struct member_list *hostlist)
|
||||
{
|
||||
struct cvtsudoers_string *s;
|
||||
@@ -1011,7 +1022,7 @@ done:
|
||||
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());
|
||||
@@ -1031,7 +1042,8 @@ help(void)
|
||||
" -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"
|
||||
|
@@ -74,21 +74,25 @@ struct cvtsudoers_filter {
|
||||
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 */
|
||||
|
@@ -73,7 +73,7 @@ do { \
|
||||
* 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;
|
||||
@@ -179,7 +179,7 @@ sudo_make_pwitem(uid_t uid, const char *name)
|
||||
* 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;
|
||||
@@ -292,7 +292,7 @@ static struct cache_item_gidlist *gidlist_item;
|
||||
* 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;
|
||||
@@ -391,7 +391,7 @@ static struct cache_item_gidlist *grlist_item;
|
||||
* 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;
|
||||
|
@@ -54,6 +54,14 @@ static int cmp_pwuid(const void *, const void *);
|
||||
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
|
||||
|
||||
/*
|
||||
@@ -68,6 +76,24 @@ static int cmp_grgid(const void *, const void *);
|
||||
# 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.
|
||||
@@ -179,7 +205,7 @@ sudo_getpwuid(uid_t uid)
|
||||
#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
|
||||
@@ -250,7 +276,7 @@ sudo_getpwnam(const char *name)
|
||||
#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
|
||||
@@ -497,7 +523,7 @@ sudo_getgrgid(gid_t gid)
|
||||
/*
|
||||
* 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"),
|
||||
@@ -562,7 +588,7 @@ sudo_getgrnam(const char *name)
|
||||
/*
|
||||
* 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) {
|
||||
@@ -789,7 +815,7 @@ sudo_get_grlist(const struct passwd *pw)
|
||||
/*
|
||||
* 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);
|
||||
@@ -843,7 +869,7 @@ sudo_set_grlist(struct passwd *pw, char * const *groups)
|
||||
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);
|
||||
}
|
||||
@@ -892,7 +918,7 @@ sudo_get_gidlist(const struct passwd *pw, unsigned int type)
|
||||
/*
|
||||
* 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);
|
||||
@@ -947,7 +973,7 @@ sudo_set_gidlist(struct passwd *pw, char * const *gids, unsigned int type)
|
||||
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);
|
||||
}
|
||||
|
@@ -304,6 +304,10 @@ int display_privs(struct sudo_nss_list *, struct passwd *);
|
||||
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 *);
|
||||
@@ -327,6 +331,7 @@ void sudo_pw_addref(struct passwd *);
|
||||
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 */
|
||||
|
Reference in New Issue
Block a user