Add option to prune non-matching entries from cvtsudoers output with -m
option is used.
This commit is contained in:
@@ -4,7 +4,7 @@ NNAAMMEE
|
||||
ccvvttssuuddooeerrss - convert between sudoers file formats
|
||||
|
||||
SSYYNNOOPPSSIISS
|
||||
ccvvttssuuddooeerrss [--eehhMMVV] [--bb _d_n] [--cc _c_o_n_f___f_i_l_e] [--dd _d_e_f_t_y_p_e_s]
|
||||
ccvvttssuuddooeerrss [--eehhMMppVV] [--bb _d_n] [--cc _c_o_n_f___f_i_l_e] [--dd _d_e_f_t_y_p_e_s]
|
||||
[--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]
|
||||
@@ -147,6 +147,11 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
point of 0 will disable the generation of sudoOrder
|
||||
attributes in the resulting LDIF file.
|
||||
|
||||
--pp, ----pprruunnee--mmaattcchheess
|
||||
When the --mm option is also specified, ccvvttssuuddooeerrss will prune
|
||||
out non-matching users, groups and hosts from matching
|
||||
entries.
|
||||
|
||||
--ss _s_e_c_t_i_o_n_s, ----ssuupppprreessss=_s_e_c_t_i_o_n_s
|
||||
Suppress the output of specific _s_e_c_t_i_o_n_s of the security
|
||||
policy. One or more section names may be specified,
|
||||
@@ -182,6 +187,9 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
oouuttppuutt__ffoorrmmaatt == _j_s_o_n | _l_d_i_f | _s_u_d_o_e_r_s
|
||||
See the description of the --ff command line option.
|
||||
|
||||
pprruunnee__mmaattcchheess == _y_e_s | _n_o
|
||||
See the description of the --pp command line option.
|
||||
|
||||
ssuuddooeerrss__bbaassee == _d_n
|
||||
See the description of the --bb command line option.
|
||||
|
||||
@@ -223,4 +231,4 @@ DDIISSCCLLAAIIMMEERR
|
||||
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
|
||||
complete details.
|
||||
|
||||
Sudo 1.8.23 March 30, 2018 Sudo 1.8.23
|
||||
Sudo 1.8.23 April 4, 2018 Sudo 1.8.23
|
||||
|
@@ -16,7 +16,7 @@
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.TH "CVTSUDOERS" "1" "March 30, 2018" "Sudo @PACKAGE_VERSION@" "General Commands Manual"
|
||||
.TH "CVTSUDOERS" "1" "April 4, 2018" "Sudo @PACKAGE_VERSION@" "General Commands Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@@ -25,7 +25,7 @@
|
||||
.SH "SYNOPSIS"
|
||||
.HP 11n
|
||||
\fBcvtsudoers\fR
|
||||
[\fB\-ehMV\fR]
|
||||
[\fB\-ehMpV\fR]
|
||||
[\fB\-b\fR\ \fIdn\fR]
|
||||
[\fB\-c\fR\ \fIconf_file\fR]
|
||||
[\fB\-d\fR\ \fIdeftypes\fR]
|
||||
@@ -277,6 +277,14 @@ Defaults to a starting point of 1.
|
||||
A starting point of 0 will disable the generation of sudoOrder
|
||||
attributes in the resulting LDIF file.
|
||||
.TP 12n
|
||||
\fB\-p\fR, \fB\--prune-matches\fR
|
||||
When the
|
||||
\fB\-m\fR
|
||||
option is also specified,
|
||||
\fBcvtsudoers\fR
|
||||
will prune out non-matching users, groups and hosts from
|
||||
matching entries.
|
||||
.TP 12n
|
||||
\fB\-s\fR \fIsections\fR, \fB\--suppress\fR=\fIsections\fR
|
||||
Suppress the output of specific
|
||||
\fIsections\fR
|
||||
@@ -340,6 +348,11 @@ See the description of the
|
||||
\fB\-f\fR
|
||||
command line option.
|
||||
.TP 6n
|
||||
\fBprune_matches =\fR \fIyes\fR | \fIno\fR
|
||||
See the description of the
|
||||
\fB\-p\fR
|
||||
command line option.
|
||||
.TP 6n
|
||||
\fBsudoers_base =\fR \fIdn\fR
|
||||
See the description of the
|
||||
\fB\-b\fR
|
||||
|
@@ -14,7 +14,7 @@
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd March 30, 2018
|
||||
.Dd April 4, 2018
|
||||
.Dt CVTSUDOERS 1
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@@ -22,7 +22,7 @@
|
||||
.Nd convert between sudoers file formats
|
||||
.Sh SYNOPSIS
|
||||
.Nm cvtsudoers
|
||||
.Op Fl ehMV
|
||||
.Op Fl ehMpV
|
||||
.Op Fl b Ar dn
|
||||
.Op Fl c Ar conf_file
|
||||
.Op Fl d Ar deftypes
|
||||
@@ -228,6 +228,13 @@ option for details.
|
||||
Defaults to a starting point of 1.
|
||||
A starting point of 0 will disable the generation of sudoOrder
|
||||
attributes in the resulting LDIF file.
|
||||
.It Fl p , Fl -prune-matches
|
||||
When the
|
||||
.Fl m
|
||||
option is also specified,
|
||||
.Nm
|
||||
will prune out non-matching users, groups and hosts from
|
||||
matching entries.
|
||||
.It Fl s Ar sections , Fl -suppress Ns = Ns Ar sections
|
||||
Suppress the output of specific
|
||||
.Ar sections
|
||||
@@ -284,6 +291,10 @@ command line option.
|
||||
See the description of the
|
||||
.Fl f
|
||||
command line option.
|
||||
.It Sy prune_matches = Ar yes | no
|
||||
See the description of the
|
||||
.Fl p
|
||||
command line option.
|
||||
.It Sy sudoers_base = Ar dn
|
||||
See the description of the
|
||||
.Fl b
|
||||
|
@@ -56,7 +56,7 @@
|
||||
struct cvtsudoers_filter *filters;
|
||||
struct sudo_user sudo_user;
|
||||
struct passwd *list_pw;
|
||||
static const char short_opts[] = "b:c:d:ef:hi:I:m:Mo:O:s:V";
|
||||
static const char short_opts[] = "b:c:d:ef:hi:I:m:Mo:O:ps:V";
|
||||
static struct option long_opts[] = {
|
||||
{ "base", required_argument, NULL, 'b' },
|
||||
{ "config", required_argument, NULL, 'c' },
|
||||
@@ -68,6 +68,7 @@ static struct option long_opts[] = {
|
||||
{ "increment", required_argument, NULL, 'I' },
|
||||
{ "match", required_argument, NULL, 'm' },
|
||||
{ "match-local", no_argument, NULL, 'M' },
|
||||
{ "prune-matches", no_argument, NULL, 'p' },
|
||||
{ "order-start", required_argument, NULL, 'O' },
|
||||
{ "output", required_argument, NULL, 'o' },
|
||||
{ "suppress", required_argument, NULL, 's' },
|
||||
@@ -85,7 +86,7 @@ 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_userspecs(struct cvtsudoers_config *conf);
|
||||
static void filter_defaults(struct cvtsudoers_config *conf);
|
||||
static void alias_remove_unused(void);
|
||||
|
||||
@@ -207,6 +208,9 @@ main(int argc, char *argv[])
|
||||
usage(1);
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
conf->prune_matches = true;
|
||||
break;
|
||||
case 's':
|
||||
conf->supstr = optarg;
|
||||
break;
|
||||
@@ -317,7 +321,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Apply filters. */
|
||||
filter_userspecs();
|
||||
filter_userspecs(conf);
|
||||
filter_defaults(conf);
|
||||
if (filters != NULL || conf->defaults != CVT_DEFAULTS_ALL)
|
||||
alias_remove_unused();
|
||||
@@ -355,7 +359,8 @@ static struct cvtsudoers_conf_table cvtsudoers_conf_vars[] = {
|
||||
{ "match", CONF_STR, &cvtsudoers_config.filter },
|
||||
{ "defaults", CONF_STR, &cvtsudoers_config.defstr },
|
||||
{ "suppress", CONF_STR, &cvtsudoers_config.supstr },
|
||||
{ "expand_aliases", CONF_BOOL, &cvtsudoers_config.expand_aliases }
|
||||
{ "expand_aliases", CONF_BOOL, &cvtsudoers_config.expand_aliases },
|
||||
{ "prune_matches", CONF_BOOL, &cvtsudoers_config.prune_matches }
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -669,16 +674,20 @@ open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
|
||||
}
|
||||
|
||||
static bool
|
||||
userlist_matches_filter(struct member_list *userlist)
|
||||
userlist_matches_filter(struct member_list *users, bool remove_nonmatching)
|
||||
{
|
||||
struct cvtsudoers_string *s;
|
||||
bool matches = false;
|
||||
struct member *m, *next;
|
||||
bool ret = false;
|
||||
debug_decl(userlist_matches_filter, SUDOERS_DEBUG_UTIL)
|
||||
|
||||
if (filters == NULL ||
|
||||
(STAILQ_EMPTY(&filters->users) && STAILQ_EMPTY(&filters->groups)))
|
||||
debug_return_bool(true);
|
||||
|
||||
TAILQ_FOREACH_REVERSE_SAFE(m, users, member_list, entries, next) {
|
||||
bool matched = false;
|
||||
|
||||
if (STAILQ_EMPTY(&filters->users)) {
|
||||
struct passwd pw;
|
||||
|
||||
@@ -690,12 +699,15 @@ userlist_matches_filter(struct member_list *userlist)
|
||||
pw.pw_name = "_nobody";
|
||||
pw.pw_uid = (uid_t)-1;
|
||||
pw.pw_gid = (gid_t)-1;
|
||||
if (userlist_matches(&pw, userlist) == true)
|
||||
matches = true;
|
||||
}
|
||||
|
||||
if (user_matches(&pw, m) == true) {
|
||||
matched = true;
|
||||
ret = true;
|
||||
}
|
||||
} else {
|
||||
STAILQ_FOREACH(s, &filters->users, entries) {
|
||||
struct passwd *pw = NULL;
|
||||
|
||||
if (s->str[0] == '#') {
|
||||
const char *errstr;
|
||||
uid_t uid = sudo_strtoid(s->str + 1, NULL, NULL, &errstr);
|
||||
@@ -706,49 +718,100 @@ userlist_matches_filter(struct member_list *userlist)
|
||||
pw = sudo_getpwnam(s->str);
|
||||
if (pw == NULL)
|
||||
continue;
|
||||
if (userlist_matches(pw, userlist) == true)
|
||||
matches = true;
|
||||
|
||||
if (user_matches(pw, m) == true)
|
||||
matched = true;
|
||||
sudo_pw_delref(pw);
|
||||
if (matches)
|
||||
|
||||
/* Only need one user in the filter to match. */
|
||||
if (matched) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug_return_bool(matches);
|
||||
if (!matched && remove_nonmatching) {
|
||||
TAILQ_REMOVE(users, m, entries);
|
||||
free_member(m);
|
||||
}
|
||||
}
|
||||
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
|
||||
static bool
|
||||
hostlist_matches_filter(struct member_list *hostlist)
|
||||
hostlist_matches_filter(struct member_list *hostlist, bool remove_nonmatching)
|
||||
{
|
||||
struct cvtsudoers_string *s;
|
||||
bool matches = false;
|
||||
struct member *m, *next;
|
||||
char *lhost, *shost;
|
||||
bool ret = false;
|
||||
char **shosts;
|
||||
int n = 0;
|
||||
debug_decl(hostlist_matches_filter, SUDOERS_DEBUG_UTIL)
|
||||
|
||||
if (filters == NULL || STAILQ_EMPTY(&filters->hosts))
|
||||
debug_return_bool(true);
|
||||
|
||||
/* Create an array of short host names. */
|
||||
STAILQ_FOREACH(s, &filters->hosts, entries) {
|
||||
user_runhost = s->str;
|
||||
if ((user_srunhost = strchr(user_runhost, '.')) != NULL) {
|
||||
user_srunhost = strndup(user_runhost,
|
||||
(size_t)(user_srunhost - user_runhost));
|
||||
if (user_srunhost == NULL) {
|
||||
n++;
|
||||
}
|
||||
shosts = reallocarray(NULL, n, sizeof(char *));
|
||||
if (shosts == NULL)
|
||||
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
n = 0;
|
||||
STAILQ_FOREACH(s, &filters->hosts, entries) {
|
||||
lhost = s->str;
|
||||
if ((shost = strchr(lhost, '.')) != NULL) {
|
||||
shost = strndup(lhost, (size_t)(shost - lhost));
|
||||
if (shost == NULL) {
|
||||
sudo_fatalx(U_("%s: %s"), __func__,
|
||||
U_("unable to allocate memory"));
|
||||
}
|
||||
} else {
|
||||
user_srunhost = user_runhost;
|
||||
shost = lhost;
|
||||
}
|
||||
shosts[n++] = shost;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH_REVERSE_SAFE(m, hostlist, member_list, entries, next) {
|
||||
bool matched = false;
|
||||
n = 0;
|
||||
STAILQ_FOREACH(s, &filters->hosts, entries) {
|
||||
lhost = s->str;
|
||||
shost = shosts[n++];
|
||||
|
||||
/* XXX - can't use netgroup_tuple with NULL pw */
|
||||
if (hostlist_matches(NULL, hostlist) == true)
|
||||
matches = true;
|
||||
if (user_srunhost != user_runhost)
|
||||
free(user_srunhost);
|
||||
user_runhost = user_host;
|
||||
user_srunhost = user_shost;
|
||||
if (matches)
|
||||
if (host_matches(NULL, lhost, shost, m) == true)
|
||||
matched = true;
|
||||
|
||||
/* Only need one host in the filter to match. */
|
||||
if (matched) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
debug_return_bool(matches);
|
||||
}
|
||||
|
||||
/* Short-circuit unless removing non-matches. */
|
||||
if (!matched && remove_nonmatching) {
|
||||
TAILQ_REMOVE(hostlist, m, entries);
|
||||
free_member(m);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free shosts array and its contents. */
|
||||
n = 0;
|
||||
STAILQ_FOREACH(s, &filters->hosts, entries) {
|
||||
lhost = s->str;
|
||||
shost = shosts[n++];
|
||||
if (shost != lhost)
|
||||
free(shost);
|
||||
}
|
||||
free(shosts);
|
||||
|
||||
debug_return_bool(ret == true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -811,7 +874,7 @@ convert_sudoers_output(const char *buf)
|
||||
* Apply filters to userspecs, removing non-matching entries.
|
||||
*/
|
||||
static void
|
||||
filter_userspecs(void)
|
||||
filter_userspecs(struct cvtsudoers_config *conf)
|
||||
{
|
||||
struct userspec *us, *next_us;
|
||||
struct privilege *priv, *next_priv;
|
||||
@@ -826,13 +889,13 @@ filter_userspecs(void)
|
||||
* In the future, we may want to add a prune option.
|
||||
*/
|
||||
TAILQ_FOREACH_SAFE(us, &userspecs, entries, next_us) {
|
||||
if (!userlist_matches_filter(&us->users)) {
|
||||
if (!userlist_matches_filter(&us->users, conf->prune_matches)) {
|
||||
TAILQ_REMOVE(&userspecs, us, entries);
|
||||
free_userspec(us);
|
||||
continue;
|
||||
}
|
||||
TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, next_priv) {
|
||||
if (!hostlist_matches_filter(&priv->hostlist)) {
|
||||
if (!hostlist_matches_filter(&priv->hostlist, conf->prune_matches)) {
|
||||
TAILQ_REMOVE(&us->privileges, priv, entries);
|
||||
free_privilege(priv);
|
||||
}
|
||||
@@ -869,7 +932,7 @@ filter_defaults(struct cvtsudoers_config *conf)
|
||||
break;
|
||||
case DEFAULTS_USER:
|
||||
if (!ISSET(conf->defaults, CVT_DEFAULTS_USER) ||
|
||||
!userlist_matches_filter(def->binding))
|
||||
!userlist_matches_filter(def->binding, conf->prune_matches))
|
||||
keep = false;
|
||||
break;
|
||||
case DEFAULTS_RUNAS:
|
||||
@@ -878,7 +941,7 @@ filter_defaults(struct cvtsudoers_config *conf)
|
||||
break;
|
||||
case DEFAULTS_HOST:
|
||||
if (!ISSET(conf->defaults, CVT_DEFAULTS_HOST) ||
|
||||
!hostlist_matches_filter(def->binding))
|
||||
!hostlist_matches_filter(def->binding, conf->prune_matches))
|
||||
keep = false;
|
||||
break;
|
||||
case DEFAULTS_CMND:
|
||||
@@ -998,7 +1061,7 @@ done:
|
||||
static void
|
||||
usage(int fatal)
|
||||
{
|
||||
(void) fprintf(fatal ? stderr : stdout, "usage: %s [-ehMV] [-b dn] "
|
||||
(void) fprintf(fatal ? stderr : stdout, "usage: %s [-ehMpV] [-b dn] "
|
||||
"[-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());
|
||||
@@ -1023,6 +1086,7 @@ help(void)
|
||||
" -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"
|
||||
" -p, --prune-matches prune non-matching users, groups and hosts\n"
|
||||
" -s, --suppress=sections suppress output of certain sections\n"
|
||||
" -V, --version display version information and exit"));
|
||||
exit(0);
|
||||
|
@@ -58,6 +58,7 @@ struct cvtsudoers_config {
|
||||
short suppress;
|
||||
bool expand_aliases;
|
||||
bool store_options;
|
||||
bool prune_matches;
|
||||
char *sudoers_base;
|
||||
char *input_format;
|
||||
char *output_format;
|
||||
@@ -67,7 +68,7 @@ struct cvtsudoers_config {
|
||||
};
|
||||
|
||||
/* Initial config settings for above. */
|
||||
#define INITIAL_CONFIG { 1, 1, CVT_DEFAULTS_ALL, 0, false, true }
|
||||
#define INITIAL_CONFIG { 1, 1, CVT_DEFAULTS_ALL, 0, false, true, false }
|
||||
|
||||
#define CONF_BOOL 0
|
||||
#define CONF_UINT 1
|
||||
|
@@ -90,18 +90,16 @@ static bool digest_matches(int fd, const char *file, const struct sudo_digest *s
|
||||
#define has_meta(s) (strpbrk(s, "\\?*[]") != NULL)
|
||||
|
||||
/*
|
||||
* Check for user described by pw in a list of members.
|
||||
* Check whether user described by pw matches member.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
*/
|
||||
int
|
||||
userlist_matches(const struct passwd *pw, const struct member_list *list)
|
||||
user_matches(const struct passwd *pw, const struct member *m)
|
||||
{
|
||||
struct member *m;
|
||||
struct alias *a;
|
||||
int rc, matched = UNSPEC;
|
||||
debug_decl(userlist_matches, SUDOERS_DEBUG_MATCH)
|
||||
int matched = UNSPEC;
|
||||
debug_decl(user_matches, SUDOERS_DEBUG_MATCH)
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
matched = !m->negated;
|
||||
@@ -118,7 +116,7 @@ userlist_matches(const struct passwd *pw, const struct member_list *list)
|
||||
break;
|
||||
case ALIAS:
|
||||
if ((a = alias_get(m->name, USERALIAS)) != NULL) {
|
||||
rc = userlist_matches(pw, &a->members);
|
||||
int rc = userlist_matches(pw, &a->members);
|
||||
if (rc != UNSPEC)
|
||||
matched = m->negated ? !rc : rc;
|
||||
alias_put(a);
|
||||
@@ -130,7 +128,22 @@ userlist_matches(const struct passwd *pw, const struct member_list *list)
|
||||
matched = !m->negated;
|
||||
break;
|
||||
}
|
||||
if (matched != UNSPEC)
|
||||
debug_return_int(matched);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for user described by pw in a list of members.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
*/
|
||||
int
|
||||
userlist_matches(const struct passwd *pw, const struct member_list *list)
|
||||
{
|
||||
struct member *m;
|
||||
int matched = UNSPEC;
|
||||
debug_decl(userlist_matches, SUDOERS_DEBUG_MATCH)
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
if ((matched = user_matches(pw, m)) != UNSPEC)
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -256,24 +269,53 @@ runaslist_matches(const struct member_list *user_list,
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for host and shost in a list of members.
|
||||
* Check for lhost and shost in a list of members.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
*/
|
||||
static int
|
||||
hostlist_matches_int(const struct passwd *pw, const char *lhost,
|
||||
const char *shost, const struct member_list *list)
|
||||
{
|
||||
struct member *m;
|
||||
int matched = UNSPEC;
|
||||
debug_decl(hostlist_matches, SUDOERS_DEBUG_MATCH)
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
matched = host_matches(pw, lhost, shost, m);
|
||||
if (matched != UNSPEC)
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for user_runhost and user_srunhost in a list of members.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
*/
|
||||
int
|
||||
hostlist_matches(const struct passwd *pw, const struct member_list *list)
|
||||
{
|
||||
struct member *m;
|
||||
struct alias *a;
|
||||
int rc, matched = UNSPEC;
|
||||
debug_decl(hostlist_matches, SUDOERS_DEBUG_MATCH)
|
||||
return hostlist_matches_int(pw, user_runhost, user_srunhost, list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether host or shost matches member.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
*/
|
||||
int
|
||||
host_matches(const struct passwd *pw, const char *lhost, const char *shost,
|
||||
const struct member *m)
|
||||
{
|
||||
struct alias *a;
|
||||
int matched = UNSPEC;
|
||||
debug_decl(host_matches, SUDOERS_DEBUG_MATCH)
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
matched = !m->negated;
|
||||
break;
|
||||
case NETGROUP:
|
||||
if (netgr_matches(m->name, user_runhost, user_srunhost,
|
||||
if (netgr_matches(m->name, lhost, shost,
|
||||
def_netgroup_tuple ? pw->pw_name : NULL))
|
||||
matched = !m->negated;
|
||||
break;
|
||||
@@ -283,7 +325,7 @@ hostlist_matches(const struct passwd *pw, const struct member_list *list)
|
||||
break;
|
||||
case ALIAS:
|
||||
if ((a = alias_get(m->name, HOSTALIAS)) != NULL) {
|
||||
rc = hostlist_matches(pw, &a->members);
|
||||
int rc = hostlist_matches_int(pw, lhost, shost, &a->members);
|
||||
if (rc != UNSPEC)
|
||||
matched = m->negated ? !rc : rc;
|
||||
alias_put(a);
|
||||
@@ -291,13 +333,10 @@ hostlist_matches(const struct passwd *pw, const struct member_list *list)
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WORD:
|
||||
if (hostname_matches(user_srunhost, user_runhost, m->name))
|
||||
if (hostname_matches(shost, lhost, m->name))
|
||||
matched = !m->negated;
|
||||
break;
|
||||
}
|
||||
if (matched != UNSPEC)
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
}
|
||||
|
||||
|
@@ -286,8 +286,10 @@ bool usergr_matches(const char *group, const char *user, const struct passwd *pw
|
||||
bool userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw);
|
||||
int cmnd_matches(const struct member *m);
|
||||
int cmndlist_matches(const struct member_list *list);
|
||||
int host_matches(const struct passwd *pw, const char *host, const char *shost, const struct member *m);
|
||||
int hostlist_matches(const struct passwd *pw, const struct member_list *list);
|
||||
int runaslist_matches(const struct member_list *user_list, const struct member_list *group_list, struct member **matching_user, struct member **matching_group);
|
||||
int user_matches(const struct passwd *pw, const struct member *m);
|
||||
int userlist_matches(const struct passwd *pw, const struct member_list *list);
|
||||
const char *sudo_getdomainname(void);
|
||||
|
||||
|
Reference in New Issue
Block a user