Add verbose version of "sudo -l command" by using an extra -l.
The output of "sudo -ll command" consists of the matching sudoers rule (in long form) with the addition of a "Matched" entry that shows the fully-qualfied path along with any arguments.
This commit is contained in:
@@ -537,7 +537,7 @@ bad:
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
display_cmnd_check(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
|
display_cmnd_check(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
|
||||||
time_t now)
|
time_t now, struct sudoers_match_info *match_info)
|
||||||
{
|
{
|
||||||
int host_match, runas_match, cmnd_match = UNSPEC;
|
int host_match, runas_match, cmnd_match = UNSPEC;
|
||||||
char *saved_user_cmnd, *saved_user_base;
|
char *saved_user_cmnd, *saved_user_base;
|
||||||
@@ -576,8 +576,13 @@ display_cmnd_check(struct sudoers_parse_tree *parse_tree, struct passwd *pw,
|
|||||||
if (runas_match == ALLOW) {
|
if (runas_match == ALLOW) {
|
||||||
cmnd_match = cmnd_matches(parse_tree, cs->cmnd,
|
cmnd_match = cmnd_matches(parse_tree, cs->cmnd,
|
||||||
cs->runchroot, NULL);
|
cs->runchroot, NULL);
|
||||||
if (cmnd_match != UNSPEC)
|
if (cmnd_match != UNSPEC) {
|
||||||
|
match_info->parse_tree = parse_tree;
|
||||||
|
match_info->us = us;
|
||||||
|
match_info->priv = priv;
|
||||||
|
match_info->cs = cs;
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -594,8 +599,10 @@ done:
|
|||||||
* Returns true if the command is allowed, false if not or -1 on error.
|
* Returns true if the command is allowed, false if not or -1 on error.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
display_cmnd(struct sudo_nss_list *snl, struct passwd *pw)
|
display_cmnd(struct sudo_nss_list *snl, struct passwd *pw, bool verbose)
|
||||||
{
|
{
|
||||||
|
struct sudoers_match_info match_info = { NULL };
|
||||||
|
struct sudo_lbuf lbuf;
|
||||||
struct sudo_nss *nss;
|
struct sudo_nss *nss;
|
||||||
int m, match = UNSPEC;
|
int m, match = UNSPEC;
|
||||||
int ret = false;
|
int ret = false;
|
||||||
@@ -604,13 +611,14 @@ display_cmnd(struct sudo_nss_list *snl, struct passwd *pw)
|
|||||||
|
|
||||||
/* Iterate over each source, checking for the command. */
|
/* Iterate over each source, checking for the command. */
|
||||||
time(&now);
|
time(&now);
|
||||||
|
sudo_lbuf_init(&lbuf, output, 0, NULL, 0);
|
||||||
TAILQ_FOREACH(nss, snl, entries) {
|
TAILQ_FOREACH(nss, snl, entries) {
|
||||||
if (nss->query(nss, pw) == -1) {
|
if (nss->query(nss, pw) == -1) {
|
||||||
/* The query function should have printed an error message. */
|
/* The query function should have printed an error message. */
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m = display_cmnd_check(nss->parse_tree, pw, now);
|
m = display_cmnd_check(nss->parse_tree, pw, now, &match_info);
|
||||||
if (m != UNSPEC)
|
if (m != UNSPEC)
|
||||||
match = m;
|
match = m;
|
||||||
|
|
||||||
@@ -618,9 +626,17 @@ display_cmnd(struct sudo_nss_list *snl, struct passwd *pw)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (match == ALLOW) {
|
if (match == ALLOW) {
|
||||||
const int len = sudo_printf(SUDO_CONV_INFO_MSG, "%s%s%s\n",
|
if (verbose) {
|
||||||
|
/* Append matching sudoers rule (long form). */
|
||||||
|
display_cmndspec_long(match_info.parse_tree, pw, match_info.us,
|
||||||
|
match_info.priv, match_info.cs, NULL, &lbuf);
|
||||||
|
sudo_lbuf_append(&lbuf, " Matched: ");
|
||||||
|
}
|
||||||
|
sudo_lbuf_append(&lbuf, "%s%s%s\n",
|
||||||
list_cmnd, user_args ? " " : "", user_args ? user_args : "");
|
list_cmnd, user_args ? " " : "", user_args ? user_args : "");
|
||||||
ret = len < 0 ? -1 : true;
|
sudo_lbuf_print(&lbuf);
|
||||||
|
ret = sudo_lbuf_error(&lbuf) ? -1 : true;
|
||||||
|
sudo_lbuf_destroy(&lbuf);
|
||||||
}
|
}
|
||||||
debug_return_int(ret);
|
debug_return_int(ret);
|
||||||
}
|
}
|
||||||
|
@@ -99,8 +99,8 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw, time_t now,
|
|||||||
int user_match = userlist_matches(nss->parse_tree, pw, &us->users);
|
int user_match = userlist_matches(nss->parse_tree, pw, &us->users);
|
||||||
if (user_match != ALLOW) {
|
if (user_match != ALLOW) {
|
||||||
if (callback != NULL && user_match != UNSPEC) {
|
if (callback != NULL && user_match != UNSPEC) {
|
||||||
callback(us, user_match, NULL, UNSPEC, NULL, UNSPEC,
|
callback(nss->parse_tree, us, user_match, NULL, UNSPEC,
|
||||||
UNSPEC, UNSPEC, cb_data);
|
NULL, UNSPEC, UNSPEC, UNSPEC, cb_data);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -110,8 +110,8 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw, time_t now,
|
|||||||
&priv->hostlist);
|
&priv->hostlist);
|
||||||
if (host_match != ALLOW) {
|
if (host_match != ALLOW) {
|
||||||
if (callback != NULL) {
|
if (callback != NULL) {
|
||||||
callback(us, user_match, priv, host_match, NULL, UNSPEC,
|
callback(nss->parse_tree, us, user_match, priv,
|
||||||
UNSPEC, UNSPEC, cb_data);
|
host_match, NULL, UNSPEC, UNSPEC, UNSPEC, cb_data);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -183,8 +183,9 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw, time_t now,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (callback != NULL) {
|
if (callback != NULL) {
|
||||||
callback(us, user_match, priv, host_match, cs,
|
callback(nss->parse_tree, us, user_match, priv,
|
||||||
date_match, runas_match, cmnd_match, cb_data);
|
host_match, cs, date_match, runas_match,
|
||||||
|
cmnd_match, cb_data);
|
||||||
}
|
}
|
||||||
if (cmnd_match != UNSPEC) {
|
if (cmnd_match != UNSPEC) {
|
||||||
/*
|
/*
|
||||||
@@ -243,8 +244,8 @@ sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw,
|
|||||||
int user_match = userlist_matches(nss->parse_tree, pw, &us->users);
|
int user_match = userlist_matches(nss->parse_tree, pw, &us->users);
|
||||||
if (user_match != ALLOW) {
|
if (user_match != ALLOW) {
|
||||||
if (callback != NULL && user_match != UNSPEC) {
|
if (callback != NULL && user_match != UNSPEC) {
|
||||||
callback(us, user_match, NULL, UNSPEC, NULL, UNSPEC,
|
callback(nss->parse_tree, us, user_match, NULL, UNSPEC, NULL,
|
||||||
UNSPEC, UNSPEC, cb_data);
|
UNSPEC, UNSPEC, UNSPEC, cb_data);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -256,8 +257,8 @@ sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw,
|
|||||||
CLR(*validated, FLAG_NO_HOST);
|
CLR(*validated, FLAG_NO_HOST);
|
||||||
} else {
|
} else {
|
||||||
if (callback != NULL) {
|
if (callback != NULL) {
|
||||||
callback(us, user_match, priv, host_match, NULL, UNSPEC,
|
callback(nss->parse_tree, us, user_match, priv, host_match,
|
||||||
UNSPEC, UNSPEC, cb_data);
|
NULL, UNSPEC, UNSPEC, UNSPEC, cb_data);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -283,8 +284,8 @@ sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (callback != NULL) {
|
if (callback != NULL) {
|
||||||
callback(us, user_match, priv, host_match, cs, date_match,
|
callback(nss->parse_tree, us, user_match, priv, host_match,
|
||||||
runas_match, cmnd_match, cb_data);
|
cs, date_match, runas_match, cmnd_match, cb_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmnd_match != UNSPEC) {
|
if (cmnd_match != UNSPEC) {
|
||||||
|
@@ -298,6 +298,13 @@ struct defaults {
|
|||||||
int column; /* column number of Defaults entry */
|
int column; /* column number of Defaults entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sudoers_match_info {
|
||||||
|
struct sudoers_parse_tree *parse_tree;
|
||||||
|
struct userspec *us; /* matching userspec */
|
||||||
|
struct privilege *priv; /* matching privilege */
|
||||||
|
struct cmndspec *cs; /* matching cmndspec */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parsed sudoers policy.
|
* Parsed sudoers policy.
|
||||||
*/
|
*/
|
||||||
@@ -324,7 +331,7 @@ struct cmnd_info {
|
|||||||
/*
|
/*
|
||||||
* Optional callback for sudoers_lookup().
|
* Optional callback for sudoers_lookup().
|
||||||
*/
|
*/
|
||||||
typedef void (*sudoers_lookup_callback_fn_t)(struct userspec *us, int user_match, struct privilege *priv, int host_match, struct cmndspec *cs, int date_match, int runas_match, int cmnd_match, void *closure);
|
typedef void (*sudoers_lookup_callback_fn_t)(struct sudoers_parse_tree *parse_tree, struct userspec *us, int user_match, struct privilege *priv, int host_match, struct cmndspec *cs, int date_match, int runas_match, int cmnd_match, void *closure);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse configuration settings, passed to init_parser().
|
* Parse configuration settings, passed to init_parser().
|
||||||
@@ -481,7 +488,7 @@ unsigned int sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, time_t
|
|||||||
|
|
||||||
/* display.c */
|
/* display.c */
|
||||||
int display_privs(struct sudo_nss_list *snl, struct passwd *pw, bool verbose);
|
int display_privs(struct sudo_nss_list *snl, struct passwd *pw, bool verbose);
|
||||||
int display_cmnd(struct sudo_nss_list *snl, struct passwd *pw);
|
int display_cmnd(struct sudo_nss_list *snl, struct passwd *pw, bool verbose);
|
||||||
|
|
||||||
/* parse_ldif.c */
|
/* parse_ldif.c */
|
||||||
bool sudoers_parse_ldif(struct sudoers_parse_tree *parse_tree, FILE *fp, const char *sudoers_base, bool store_options);
|
bool sudoers_parse_ldif(struct sudoers_parse_tree *parse_tree, FILE *fp, const char *sudoers_base, bool store_options);
|
||||||
|
@@ -815,7 +815,7 @@ sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, time_t now,
|
|||||||
|
|
||||||
/* STUB */
|
/* STUB */
|
||||||
int
|
int
|
||||||
display_cmnd(struct sudo_nss_list *snl, struct passwd *pw)
|
display_cmnd(struct sudo_nss_list *snl, struct passwd *pw, bool verbose)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -325,16 +325,10 @@ done:
|
|||||||
debug_return_str(iolog_path);
|
debug_return_str(iolog_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sudoers_match_info {
|
|
||||||
struct privilege *priv; /* matching privilege */
|
|
||||||
struct userspec *us; /* matching userspec */
|
|
||||||
struct cmndspec *cs; /* matching cmndspec */
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cb_lookup(struct userspec *us, int user_match, struct privilege *priv,
|
cb_lookup(struct sudoers_parse_tree *parse_tree, struct userspec *us,
|
||||||
int host_match, struct cmndspec *cs, int date_match, int runas_match,
|
int user_match, struct privilege *priv, int host_match, struct cmndspec *cs,
|
||||||
int cmnd_match, void *closure)
|
int date_match, int runas_match, int cmnd_match, void *closure)
|
||||||
{
|
{
|
||||||
struct sudoers_match_info *info = closure;
|
struct sudoers_match_info *info = closure;
|
||||||
|
|
||||||
@@ -950,7 +944,7 @@ sudoers_list(int argc, char * const argv[], const char *list_user, bool verbose)
|
|||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (ISSET(sudo_mode, MODE_CHECK))
|
if (ISSET(sudo_mode, MODE_CHECK))
|
||||||
ret = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
|
ret = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw, verbose);
|
||||||
else
|
else
|
||||||
ret = display_privs(snl, list_pw ? list_pw : sudo_user.pw, verbose);
|
ret = display_privs(snl, list_pw ? list_pw : sudo_user.pw, verbose);
|
||||||
|
|
||||||
|
@@ -74,7 +74,7 @@ static bool cb_runas_default(const char *file, int line, int column, const union
|
|||||||
static int testsudoers_error(const char * restrict buf);
|
static int testsudoers_error(const char * restrict buf);
|
||||||
static int testsudoers_output(const char * restrict buf);
|
static int testsudoers_output(const char * restrict buf);
|
||||||
sudo_noreturn static void usage(void);
|
sudo_noreturn static void usage(void);
|
||||||
static void cb_lookup(struct userspec *us, int user_match, struct privilege *priv, int host_match, struct cmndspec *cs, int date_match, int runas_match, int cmnd_match, void *closure);
|
static void cb_lookup(struct sudoers_parse_tree *parse_tree, struct userspec *us, int user_match, struct privilege *priv, int host_match, struct cmndspec *cs, int date_match, int runas_match, int cmnd_match, void *closure);
|
||||||
static int testsudoers_query(const struct sudo_nss *nss, struct passwd *pw);
|
static int testsudoers_query(const struct sudo_nss *nss, struct passwd *pw);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -626,9 +626,9 @@ set_cmnd_path(const char *runchroot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cb_lookup(struct userspec *us, int user_match, struct privilege *priv,
|
cb_lookup(struct sudoers_parse_tree *parse_tree, struct userspec *us,
|
||||||
int host_match, struct cmndspec *cs, int date_match, int runas_match,
|
int user_match, struct privilege *priv, int host_match, struct cmndspec *cs,
|
||||||
int cmnd_match, void *closure)
|
int date_match, int runas_match, int cmnd_match, void *closure)
|
||||||
{
|
{
|
||||||
static struct privilege *prev_priv;
|
static struct privilege *prev_priv;
|
||||||
struct sudo_lbuf lbuf;
|
struct sudo_lbuf lbuf;
|
||||||
|
Reference in New Issue
Block a user