mirror of
https://github.com/sudo-project/sudo.git
synced 2025-09-02 23:35:36 +00:00
Unify the -l output for file and ldap based sudoers and use lbufs for both.
The ldap output does not currently include options that cannot be represented as tags. This will be remedied in a long list output mode to come.
This commit is contained in:
144
ldap.c
144
ldap.c
@@ -79,6 +79,7 @@
|
|||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
|
#include "lbuf.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__unused static const char rcsid[] = "$Sudo$";
|
__unused static const char rcsid[] = "$Sudo$";
|
||||||
@@ -236,8 +237,10 @@ struct sudo_nss sudo_nss_ldap = {
|
|||||||
sudo_ldap_parse,
|
sudo_ldap_parse,
|
||||||
sudo_ldap_setdefs,
|
sudo_ldap_setdefs,
|
||||||
sudo_ldap_lookup,
|
sudo_ldap_lookup,
|
||||||
sudo_ldap_display_privs,
|
sudo_ldap_display_cmnd,
|
||||||
sudo_ldap_display_cmnd
|
sudo_ldap_display_defaults,
|
||||||
|
sudo_ldap_display_bound_defaults,
|
||||||
|
sudo_ldap_display_privs
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_LDAP_CREATE
|
#ifdef HAVE_LDAP_CREATE
|
||||||
@@ -1101,44 +1104,74 @@ sudo_ldap_get_first_rdn(ld, entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Like sudo_ldap_lookup(), except we just print entries.
|
* Fetch and display the global Options.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
sudo_ldap_display_privs(nss, pw)
|
sudo_ldap_display_defaults(nss, pw, lbuf)
|
||||||
struct sudo_nss *nss;
|
struct sudo_nss *nss;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
struct lbuf *lbuf;
|
||||||
{
|
{
|
||||||
struct berval **bv, **p;
|
struct berval **bv, **p;
|
||||||
LDAP *ld = (LDAP *) nss->handle;
|
LDAP *ld = (LDAP *) nss->handle;
|
||||||
LDAPMessage *entry = NULL, *result = NULL;
|
LDAPMessage *entry = NULL, *result = NULL;
|
||||||
char *filt, *rdn;
|
char *prefix = NULL;
|
||||||
int rc, do_netgr;
|
int rc, count = 0;
|
||||||
|
|
||||||
if (ld == NULL)
|
if (ld == NULL)
|
||||||
return;
|
return(-1);
|
||||||
|
|
||||||
/*
|
|
||||||
* First, get (and display) the global Options.
|
|
||||||
*/
|
|
||||||
rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE,
|
rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE,
|
||||||
"cn=defaults", NULL, 0, NULL, NULL, NULL, -1, &result);
|
"cn=defaults", NULL, 0, NULL, NULL, NULL, -1, &result);
|
||||||
if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) {
|
if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) {
|
||||||
bv = ldap_get_values_len(ld, entry, "sudoOption");
|
bv = ldap_get_values_len(ld, entry, "sudoOption");
|
||||||
if (bv != NULL) {
|
if (bv != NULL) {
|
||||||
fputs("Global LDAP options:\n ", stdout);
|
if (lbuf->len == 0)
|
||||||
|
prefix = " ";
|
||||||
|
else
|
||||||
|
prefix = ", ";
|
||||||
for (p = bv; *p != NULL; p++) {
|
for (p = bv; *p != NULL; p++) {
|
||||||
if (p != bv)
|
lbuf_append(lbuf, prefix, (*p)->bv_val, NULL);
|
||||||
fputs("\n ", stdout);
|
prefix = ", ";
|
||||||
fputs((*p)->bv_val, stdout);
|
count++;
|
||||||
}
|
}
|
||||||
putchar('\n');
|
|
||||||
ldap_value_free_len(bv);
|
ldap_value_free_len(bv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result)
|
||||||
ldap_msgfree(result);
|
ldap_msgfree(result);
|
||||||
result = NULL;
|
return(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* STUB
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sudo_ldap_display_bound_defaults(nss, pw, lbuf)
|
||||||
|
struct sudo_nss *nss;
|
||||||
|
struct passwd *pw;
|
||||||
|
struct lbuf *lbuf;
|
||||||
|
{
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like sudo_ldap_lookup(), except we just print entries.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sudo_ldap_display_privs(nss, pw, lbuf)
|
||||||
|
struct sudo_nss *nss;
|
||||||
|
struct passwd *pw;
|
||||||
|
struct lbuf *lbuf;
|
||||||
|
{
|
||||||
|
struct berval **bv, **p;
|
||||||
|
LDAP *ld = (LDAP *) nss->handle;
|
||||||
|
LDAPMessage *entry = NULL, *result = NULL;
|
||||||
|
char *filt, *rdn;
|
||||||
|
int rc, do_netgr, count = 0;
|
||||||
|
|
||||||
|
if (ld == NULL)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Okay - time to search for anything that matches this user
|
* Okay - time to search for anything that matches this user
|
||||||
@@ -1169,72 +1202,87 @@ sudo_ldap_display_privs(nss, pw)
|
|||||||
sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) &&
|
sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) &&
|
||||||
sudo_ldap_check_host(ld, entry)) {
|
sudo_ldap_check_host(ld, entry)) {
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* extract the dn, only show the first rdn */
|
/* extract the dn, only show the first rdn */
|
||||||
|
/* XXX - how to display the role sudo-style? */
|
||||||
rdn = sudo_ldap_get_first_rdn(ld, entry);
|
rdn = sudo_ldap_get_first_rdn(ld, entry);
|
||||||
printf("\nLDAP Role: %s\n", rdn ? rdn : "UNKNOWN");
|
printf("LDAP Role: %s\n", rdn ? rdn : "UNKNOWN");
|
||||||
if (rdn)
|
if (rdn)
|
||||||
ldap_memfree(rdn);
|
ldap_memfree(rdn);
|
||||||
|
#endif
|
||||||
/* get the Option Values from the entry */
|
lbuf_append(lbuf, " (", NULL);
|
||||||
bv = ldap_get_values_len(ld, entry, "sudoOption");
|
|
||||||
if (bv != NULL) {
|
|
||||||
fputs(" Options:\n ", stdout);
|
|
||||||
for (p = bv; *p != NULL; p++) {
|
|
||||||
if (p != bv)
|
|
||||||
fputs("\n ", stdout);
|
|
||||||
fputs((*p)->bv_val, stdout);
|
|
||||||
}
|
|
||||||
putchar('\n');
|
|
||||||
ldap_value_free_len(bv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the RunAsUser Values from the entry */
|
/* get the RunAsUser Values from the entry */
|
||||||
bv = ldap_get_values_len(ld, entry, "sudoRunAsUser");
|
bv = ldap_get_values_len(ld, entry, "sudoRunAsUser");
|
||||||
if (bv == NULL)
|
if (bv == NULL)
|
||||||
bv = ldap_get_values_len(ld, entry, "sudoRunAs");
|
bv = ldap_get_values_len(ld, entry, "sudoRunAs");
|
||||||
if (bv != NULL) {
|
if (bv != NULL) {
|
||||||
fputs(" RunAsUsers: ", stdout);
|
|
||||||
for (p = bv; *p != NULL; p++) {
|
for (p = bv; *p != NULL; p++) {
|
||||||
if (p != bv)
|
if (p != bv)
|
||||||
fputs(", ", stdout);
|
lbuf_append(lbuf, ", ", NULL);
|
||||||
fputs((*p)->bv_val, stdout);
|
lbuf_append(lbuf, (*p)->bv_val, NULL);
|
||||||
}
|
}
|
||||||
putchar('\n');
|
|
||||||
ldap_value_free_len(bv);
|
ldap_value_free_len(bv);
|
||||||
}
|
} else
|
||||||
|
lbuf_append(lbuf, def_runas_default, NULL);
|
||||||
|
|
||||||
/* get the RunAsGroup Values from the entry */
|
/* get the RunAsGroup Values from the entry */
|
||||||
bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup");
|
bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup");
|
||||||
if (bv != NULL) {
|
if (bv != NULL) {
|
||||||
fputs(" RunAsGroups: ", stdout);
|
lbuf_append(lbuf, " : ", NULL);
|
||||||
for (p = bv; *p != NULL; p++) {
|
for (p = bv; *p != NULL; p++) {
|
||||||
if (p != bv)
|
if (p != bv)
|
||||||
fputs(", ", stdout);
|
lbuf_append(lbuf, ", ", NULL);
|
||||||
fputs((*p)->bv_val, stdout);
|
lbuf_append(lbuf, (*p)->bv_val, NULL);
|
||||||
|
}
|
||||||
|
ldap_value_free_len(bv);
|
||||||
|
}
|
||||||
|
lbuf_append(lbuf, ") ", NULL);
|
||||||
|
|
||||||
|
/* get the Option Values from the entry */
|
||||||
|
bv = ldap_get_values_len(ld, entry, "sudoOption");
|
||||||
|
if (bv != NULL) {
|
||||||
|
char *cp, *tag;
|
||||||
|
|
||||||
|
for (p = bv; *p != NULL; p++) {
|
||||||
|
cp = (*p)->bv_val;
|
||||||
|
if (*cp == '!')
|
||||||
|
cp++;
|
||||||
|
tag = NULL;
|
||||||
|
if (strcmp(cp, "authenticate") == 0)
|
||||||
|
tag = (*p)->bv_val[0] == '!' ?
|
||||||
|
"NOPASSWD: " : "PASSWD: ";
|
||||||
|
else if (strcmp(cp, "noexec") == 0)
|
||||||
|
tag = (*p)->bv_val[0] == '!' ?
|
||||||
|
"EXEC: " : "NOEXEC: ";
|
||||||
|
else if (strcmp(cp, "setenv") == 0)
|
||||||
|
tag = (*p)->bv_val[0] == '!' ?
|
||||||
|
"NOSETENV: " : "SETENV: ";
|
||||||
|
if (tag != NULL)
|
||||||
|
lbuf_append(lbuf, tag, NULL);
|
||||||
|
/* XXX - ignores other options */
|
||||||
}
|
}
|
||||||
putchar('\n');
|
|
||||||
ldap_value_free_len(bv);
|
ldap_value_free_len(bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the Command Values from the entry */
|
/* get the Command Values from the entry */
|
||||||
bv = ldap_get_values_len(ld, entry, "sudoCommand");
|
bv = ldap_get_values_len(ld, entry, "sudoCommand");
|
||||||
if (bv != NULL) {
|
if (bv != NULL) {
|
||||||
fputs(" Commands:\n ", stdout);
|
|
||||||
for (p = bv; *p != NULL; p++) {
|
for (p = bv; *p != NULL; p++) {
|
||||||
if (p != bv)
|
if (p != bv)
|
||||||
fputs("\n ", stdout);
|
lbuf_append(lbuf, ", ", NULL);
|
||||||
fputs((*p)->bv_val, stdout);
|
lbuf_append(lbuf, (*p)->bv_val, NULL);
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
putchar('\n');
|
|
||||||
ldap_value_free_len(bv);
|
ldap_value_free_len(bv);
|
||||||
} else {
|
|
||||||
puts(" Commands: NONE");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lbuf_print(lbuf); /* forces a newline */
|
||||||
}
|
}
|
||||||
ldap_msgfree(result);
|
ldap_msgfree(result);
|
||||||
result = NULL;
|
result = NULL;
|
||||||
}
|
}
|
||||||
|
return(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
159
parse.c
159
parse.c
@@ -64,8 +64,10 @@ struct sudo_nss sudo_nss_file = {
|
|||||||
sudo_file_parse,
|
sudo_file_parse,
|
||||||
sudo_file_setdefs,
|
sudo_file_setdefs,
|
||||||
sudo_file_lookup,
|
sudo_file_lookup,
|
||||||
sudo_file_display_privs,
|
sudo_file_display_cmnd,
|
||||||
sudo_file_display_cmnd
|
sudo_file_display_defaults,
|
||||||
|
sudo_file_display_bound_defaults,
|
||||||
|
sudo_file_display_privs
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -79,8 +81,7 @@ extern int errorlineno, parse_error;
|
|||||||
* Local prototypes.
|
* Local prototypes.
|
||||||
*/
|
*/
|
||||||
static void print_member __P((struct lbuf *, char *, int, int, int));
|
static void print_member __P((struct lbuf *, char *, int, int, int));
|
||||||
static void display_defaults __P((struct passwd *));
|
static int display_bound_defaults __P((int, struct lbuf *));
|
||||||
static void display_bound_defaults __P((int));
|
|
||||||
|
|
||||||
int
|
int
|
||||||
sudo_file_open(nss)
|
sudo_file_open(nss)
|
||||||
@@ -302,23 +303,21 @@ sudo_file_lookup(nss, validated, pwflag)
|
|||||||
#define TAG_CHANGED(t) \
|
#define TAG_CHANGED(t) \
|
||||||
(cs->tags.t != UNSPEC && cs->tags.t != IMPLIED && cs->tags.t != tags.t)
|
(cs->tags.t != UNSPEC && cs->tags.t != IMPLIED && cs->tags.t != tags.t)
|
||||||
|
|
||||||
void
|
int
|
||||||
sudo_file_display_privs(nss, pw)
|
sudo_file_display_privs(nss, pw, lbuf)
|
||||||
struct sudo_nss *nss;
|
struct sudo_nss *nss;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
struct lbuf *lbuf;
|
||||||
{
|
{
|
||||||
struct lbuf lbuf;
|
|
||||||
struct cmndspec *cs;
|
struct cmndspec *cs;
|
||||||
struct member *m;
|
struct member *m;
|
||||||
struct privilege *priv;
|
struct privilege *priv;
|
||||||
struct userspec *us;
|
struct userspec *us;
|
||||||
struct cmndtag tags;
|
struct cmndtag tags;
|
||||||
|
int nfound = 0;
|
||||||
|
|
||||||
display_defaults(pw);
|
if (nss->handle == NULL)
|
||||||
|
return(-1);
|
||||||
lbuf_init(&lbuf, NULL, 8, '\\');
|
|
||||||
printf("User %s may run the following commands on this host:\n",
|
|
||||||
pw->pw_name);
|
|
||||||
|
|
||||||
tq_foreach_fwd(&userspecs, us) {
|
tq_foreach_fwd(&userspecs, us) {
|
||||||
/* XXX - why only check the first privilege here? */
|
/* XXX - why only check the first privilege here? */
|
||||||
@@ -330,69 +329,77 @@ sudo_file_display_privs(nss, pw)
|
|||||||
tags.noexec = def_noexec;
|
tags.noexec = def_noexec;
|
||||||
tags.setenv = def_setenv;
|
tags.setenv = def_setenv;
|
||||||
tags.nopasswd = !def_authenticate;
|
tags.nopasswd = !def_authenticate;
|
||||||
lbuf_append(&lbuf, " ", NULL);
|
lbuf_append(lbuf, " ", NULL);
|
||||||
tq_foreach_fwd(&priv->cmndlist, cs) {
|
tq_foreach_fwd(&priv->cmndlist, cs) {
|
||||||
if (cs != tq_first(&priv->cmndlist))
|
if (cs != tq_first(&priv->cmndlist))
|
||||||
lbuf_append(&lbuf, ", ", NULL);
|
lbuf_append(lbuf, ", ", NULL);
|
||||||
lbuf_append(&lbuf, "(", NULL);
|
lbuf_append(lbuf, "(", NULL);
|
||||||
if (!tq_empty(&cs->runasuserlist)) {
|
if (!tq_empty(&cs->runasuserlist)) {
|
||||||
tq_foreach_fwd(&cs->runasuserlist, m) {
|
tq_foreach_fwd(&cs->runasuserlist, m) {
|
||||||
if (m != tq_first(&cs->runasuserlist))
|
if (m != tq_first(&cs->runasuserlist))
|
||||||
lbuf_append(&lbuf, ", ", NULL);
|
lbuf_append(lbuf, ", ", NULL);
|
||||||
print_member(&lbuf, m->name, m->type, m->negated,
|
print_member(lbuf, m->name, m->type, m->negated,
|
||||||
RUNASALIAS);
|
RUNASALIAS);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lbuf_append(&lbuf, def_runas_default, NULL);
|
lbuf_append(lbuf, def_runas_default, NULL);
|
||||||
}
|
}
|
||||||
if (!tq_empty(&cs->runasgrouplist)) {
|
if (!tq_empty(&cs->runasgrouplist)) {
|
||||||
lbuf_append(&lbuf, " : ", NULL);
|
lbuf_append(lbuf, " : ", NULL);
|
||||||
tq_foreach_fwd(&cs->runasgrouplist, m) {
|
tq_foreach_fwd(&cs->runasgrouplist, m) {
|
||||||
if (m != tq_first(&cs->runasgrouplist))
|
if (m != tq_first(&cs->runasgrouplist))
|
||||||
lbuf_append(&lbuf, ", ", NULL);
|
lbuf_append(lbuf, ", ", NULL);
|
||||||
print_member(&lbuf, m->name, m->type, m->negated,
|
print_member(lbuf, m->name, m->type, m->negated,
|
||||||
RUNASALIAS);
|
RUNASALIAS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lbuf_append(&lbuf, ") ", NULL);
|
lbuf_append(lbuf, ") ", NULL);
|
||||||
if (TAG_CHANGED(setenv)) {
|
if (TAG_CHANGED(setenv)) {
|
||||||
lbuf_append(&lbuf, cs->tags.setenv ? "SETENV: " :
|
lbuf_append(lbuf, cs->tags.setenv ? "SETENV: " :
|
||||||
"NOSETENV: ", NULL);
|
"NOSETENV: ", NULL);
|
||||||
tags.setenv = cs->tags.setenv;
|
tags.setenv = cs->tags.setenv;
|
||||||
}
|
}
|
||||||
if (TAG_CHANGED(noexec)) {
|
if (TAG_CHANGED(noexec)) {
|
||||||
lbuf_append(&lbuf, cs->tags.noexec ? "NOEXEC: " :
|
lbuf_append(lbuf, cs->tags.noexec ? "NOEXEC: " :
|
||||||
"EXEC: ", NULL);
|
"EXEC: ", NULL);
|
||||||
tags.noexec = cs->tags.noexec;
|
tags.noexec = cs->tags.noexec;
|
||||||
}
|
}
|
||||||
if (TAG_CHANGED(nopasswd)) {
|
if (TAG_CHANGED(nopasswd)) {
|
||||||
lbuf_append(&lbuf, cs->tags.nopasswd ? "NOPASSWD: " :
|
lbuf_append(lbuf, cs->tags.nopasswd ? "NOPASSWD: " :
|
||||||
"PASSWD: ", NULL);
|
"PASSWD: ", NULL);
|
||||||
tags.nopasswd = cs->tags.nopasswd;
|
tags.nopasswd = cs->tags.nopasswd;
|
||||||
}
|
}
|
||||||
m = cs->cmnd;
|
m = cs->cmnd;
|
||||||
print_member(&lbuf, m->name, m->type, m->negated,
|
print_member(lbuf, m->name, m->type, m->negated,
|
||||||
CMNDALIAS);
|
CMNDALIAS);
|
||||||
|
nfound++;
|
||||||
}
|
}
|
||||||
lbuf_print(&lbuf);
|
lbuf_print(lbuf); /* forces a newline */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lbuf_destroy(&lbuf);
|
return(nfound);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display matching Defaults entries for the given user on this host.
|
* Display matching Defaults entries for the given user on this host.
|
||||||
*/
|
*/
|
||||||
static void
|
int
|
||||||
display_defaults(pw)
|
sudo_file_display_defaults(nss, pw, lbuf)
|
||||||
|
struct sudo_nss *nss;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
struct lbuf *lbuf;
|
||||||
{
|
{
|
||||||
struct defaults *d;
|
struct defaults *d;
|
||||||
struct lbuf lbuf;
|
|
||||||
char *prefix = NULL;
|
char *prefix = NULL;
|
||||||
int per_runas = 0, per_cmnd = 0;
|
int nfound = 0;
|
||||||
|
|
||||||
lbuf_init(&lbuf, NULL, 4, 0);
|
if (nss->handle == NULL)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if (lbuf->len == 0)
|
||||||
|
prefix = " ";
|
||||||
|
else
|
||||||
|
prefix = ", ";
|
||||||
|
|
||||||
tq_foreach_fwd(&defaults, d) {
|
tq_foreach_fwd(&defaults, d) {
|
||||||
switch (d->type) {
|
switch (d->type) {
|
||||||
@@ -405,55 +412,58 @@ display_defaults(pw)
|
|||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case DEFAULTS_RUNAS:
|
case DEFAULTS_RUNAS:
|
||||||
per_runas = 1;
|
|
||||||
continue;
|
|
||||||
case DEFAULTS_CMND:
|
case DEFAULTS_CMND:
|
||||||
per_cmnd = 1;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (prefix == NULL) {
|
lbuf_append(lbuf, prefix, NULL);
|
||||||
printf("Matching Defaults entries for %s on this host:\n",
|
|
||||||
pw->pw_name);
|
|
||||||
prefix = " ";
|
|
||||||
}
|
|
||||||
lbuf_append(&lbuf, prefix, NULL);
|
|
||||||
if (d->val != NULL) {
|
if (d->val != NULL) {
|
||||||
lbuf_append(&lbuf, d->var, d->op == '+' ? " += " :
|
lbuf_append(lbuf, d->var, d->op == '+' ? "+=" :
|
||||||
d->op == '-' ? " -= " : " = ", NULL);
|
d->op == '-' ? "-=" : "=", NULL);
|
||||||
if (strpbrk(d->val, " \t") != NULL) {
|
if (strpbrk(d->val, " \t") != NULL) {
|
||||||
lbuf_append(&lbuf, "\"", NULL);
|
lbuf_append(lbuf, "\"", NULL);
|
||||||
lbuf_append_quoted(&lbuf, "\"", d->val, NULL);
|
lbuf_append_quoted(lbuf, "\"", d->val, NULL);
|
||||||
lbuf_append(&lbuf, "\"", NULL);
|
lbuf_append(lbuf, "\"", NULL);
|
||||||
} else
|
} else
|
||||||
lbuf_append_quoted(&lbuf, SUDOERS_QUOTED, d->val, NULL);
|
lbuf_append_quoted(lbuf, SUDOERS_QUOTED, d->val, NULL);
|
||||||
} else
|
} else
|
||||||
lbuf_append(&lbuf, d->op == FALSE ? "!" : "", d->var, NULL);
|
lbuf_append(lbuf, d->op == FALSE ? "!" : "", d->var, NULL);
|
||||||
prefix = ", ";
|
prefix = ", ";
|
||||||
|
nfound++;
|
||||||
}
|
}
|
||||||
if (prefix) {
|
|
||||||
lbuf_print(&lbuf);
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
lbuf_destroy(&lbuf);
|
|
||||||
|
|
||||||
if (per_runas)
|
return(nfound);
|
||||||
display_bound_defaults(DEFAULTS_RUNAS);
|
}
|
||||||
if (per_cmnd)
|
|
||||||
display_bound_defaults(DEFAULTS_CMND);
|
/*
|
||||||
|
* Display Defaults entries that are per-runas or per-command
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sudo_file_display_bound_defaults(nss, pw, lbuf)
|
||||||
|
struct sudo_nss *nss;
|
||||||
|
struct passwd *pw;
|
||||||
|
struct lbuf *lbuf;
|
||||||
|
{
|
||||||
|
int nfound = 0;
|
||||||
|
|
||||||
|
/* XXX - should only print ones that match what the user can do. */
|
||||||
|
nfound += display_bound_defaults(DEFAULTS_RUNAS, lbuf);
|
||||||
|
nfound += display_bound_defaults(DEFAULTS_CMND, lbuf);
|
||||||
|
|
||||||
|
return(nfound);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display Defaults entries of the given type.
|
* Display Defaults entries of the given type.
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
display_bound_defaults(dtype)
|
display_bound_defaults(dtype, lbuf)
|
||||||
int dtype;
|
int dtype;
|
||||||
|
struct lbuf *lbuf;
|
||||||
{
|
{
|
||||||
struct lbuf lbuf;
|
|
||||||
struct defaults *d;
|
struct defaults *d;
|
||||||
struct member *m, *binding = NULL;
|
struct member *m, *binding = NULL;
|
||||||
char *dname, *dsep;
|
char *dname, *dsep;
|
||||||
int atype;
|
int atype, nfound = 0;
|
||||||
|
|
||||||
switch (dtype) {
|
switch (dtype) {
|
||||||
case DEFAULTS_HOST:
|
case DEFAULTS_HOST:
|
||||||
@@ -477,34 +487,33 @@ display_bound_defaults(dtype)
|
|||||||
dsep = "!";
|
dsep = "!";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return(-1);
|
||||||
}
|
}
|
||||||
lbuf_init(&lbuf, NULL, 4, 0);
|
/* printf("Per-%s Defaults entries:\n", dname); */
|
||||||
printf("Per-%s Defaults entries:\n", dname);
|
|
||||||
tq_foreach_fwd(&defaults, d) {
|
tq_foreach_fwd(&defaults, d) {
|
||||||
if (d->type != dtype)
|
if (d->type != dtype)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
nfound++;
|
||||||
if (binding != tq_first(&d->binding)) {
|
if (binding != tq_first(&d->binding)) {
|
||||||
binding = tq_first(&d->binding);
|
binding = tq_first(&d->binding);
|
||||||
lbuf_append(&lbuf, " Defaults", dsep, NULL);
|
lbuf_append(lbuf, " Defaults", dsep, NULL);
|
||||||
for (m = binding; m != NULL; m = m->next) {
|
for (m = binding; m != NULL; m = m->next) {
|
||||||
if (m != binding)
|
if (m != binding)
|
||||||
lbuf_append(&lbuf, ",", NULL);
|
lbuf_append(lbuf, ",", NULL);
|
||||||
print_member(&lbuf, m->name, m->type, m->negated, atype);
|
print_member(lbuf, m->name, m->type, m->negated, atype);
|
||||||
lbuf_append(&lbuf, " ", NULL);
|
lbuf_append(lbuf, " ", NULL);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
lbuf_append(&lbuf, ", ", NULL);
|
lbuf_append(lbuf, ", ", NULL);
|
||||||
if (d->val != NULL) {
|
if (d->val != NULL) {
|
||||||
lbuf_append(&lbuf, d->var, d->op == '+' ? "+=" :
|
lbuf_append(lbuf, d->var, d->op == '+' ? "+=" :
|
||||||
d->op == '-' ? "-=" : "=", d->val, NULL);
|
d->op == '-' ? "-=" : "=", d->val, NULL);
|
||||||
} else
|
} else
|
||||||
lbuf_append(&lbuf, d->op == FALSE ? "!" : "", d->var, NULL);
|
lbuf_append(lbuf, d->op == FALSE ? "!" : "", d->var, NULL);
|
||||||
}
|
}
|
||||||
lbuf_print(&lbuf);
|
|
||||||
lbuf_destroy(&lbuf);
|
return(nfound);
|
||||||
putchar('\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
9
sudo.h
9
sudo.h
@@ -169,6 +169,7 @@ struct sudo_user {
|
|||||||
#define TGP_ECHO 0x01 /* leave echo on when reading passwd */
|
#define TGP_ECHO 0x01 /* leave echo on when reading passwd */
|
||||||
#define TGP_STDIN 0x02 /* read from stdin, not /dev/tty */
|
#define TGP_STDIN 0x02 /* read from stdin, not /dev/tty */
|
||||||
|
|
||||||
|
struct lbuf;
|
||||||
struct passwd;
|
struct passwd;
|
||||||
struct timespec;
|
struct timespec;
|
||||||
struct timeval;
|
struct timeval;
|
||||||
@@ -232,8 +233,10 @@ int sudo_ldap_close __P((struct sudo_nss *));
|
|||||||
int sudo_ldap_setdefs __P((struct sudo_nss *));
|
int sudo_ldap_setdefs __P((struct sudo_nss *));
|
||||||
int sudo_ldap_lookup __P((struct sudo_nss *, int, int));
|
int sudo_ldap_lookup __P((struct sudo_nss *, int, int));
|
||||||
int sudo_ldap_parse __P((struct sudo_nss *));
|
int sudo_ldap_parse __P((struct sudo_nss *));
|
||||||
void sudo_ldap_display_privs __P((struct sudo_nss *, struct passwd *));
|
|
||||||
int sudo_ldap_display_cmnd __P((struct sudo_nss *, struct passwd *));
|
int sudo_ldap_display_cmnd __P((struct sudo_nss *, struct passwd *));
|
||||||
|
int sudo_ldap_display_defaults __P((struct sudo_nss *, struct passwd *, struct lbuf *));
|
||||||
|
int sudo_ldap_display_bound_defaults __P((struct sudo_nss *, struct passwd *, struct lbuf *));
|
||||||
|
int sudo_ldap_display_privs __P((struct sudo_nss *, struct passwd *, struct lbuf *));
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
int sudo_file_open __P((struct sudo_nss *));
|
int sudo_file_open __P((struct sudo_nss *));
|
||||||
@@ -241,8 +244,10 @@ int sudo_file_close __P((struct sudo_nss *));
|
|||||||
int sudo_file_setdefs __P((struct sudo_nss *));
|
int sudo_file_setdefs __P((struct sudo_nss *));
|
||||||
int sudo_file_lookup __P((struct sudo_nss *, int, int));
|
int sudo_file_lookup __P((struct sudo_nss *, int, int));
|
||||||
int sudo_file_parse __P((struct sudo_nss *));
|
int sudo_file_parse __P((struct sudo_nss *));
|
||||||
void sudo_file_display_privs __P((struct sudo_nss *, struct passwd *));
|
|
||||||
int sudo_file_display_cmnd __P((struct sudo_nss *, struct passwd *));
|
int sudo_file_display_cmnd __P((struct sudo_nss *, struct passwd *));
|
||||||
|
int sudo_file_display_defaults __P((struct sudo_nss *, struct passwd *, struct lbuf *));
|
||||||
|
int sudo_file_display_bound_defaults __P((struct sudo_nss *, struct passwd *, struct lbuf *));
|
||||||
|
int sudo_file_display_privs __P((struct sudo_nss *, struct passwd *, struct lbuf *));
|
||||||
#endif
|
#endif
|
||||||
void set_perms __P((int));
|
void set_perms __P((int));
|
||||||
void remove_timestamp __P((int));
|
void remove_timestamp __P((int));
|
||||||
|
39
sudo_nss.c
39
sudo_nss.c
@@ -41,6 +41,7 @@
|
|||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
|
#include "lbuf.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__unused static const char rcsid[] = "$Sudo$";
|
__unused static const char rcsid[] = "$Sudo$";
|
||||||
@@ -156,16 +157,44 @@ display_privs(snl, pw)
|
|||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
{
|
{
|
||||||
struct sudo_nss *nss;
|
struct sudo_nss *nss;
|
||||||
|
struct lbuf lbuf;
|
||||||
|
int count;
|
||||||
|
|
||||||
/* Reset group vector so group matching works correctly. */
|
/* Reset group vector so group matching works correctly. */
|
||||||
reset_groups(pw);
|
reset_groups(pw);
|
||||||
|
|
||||||
/* Display privileges from all sources. */
|
lbuf_init(&lbuf, NULL, 4, 0);
|
||||||
tq_foreach_fwd(snl, nss) {
|
|
||||||
if (nss != tq_first(snl))
|
/* Display defaults from all sources. */
|
||||||
putchar('\n');
|
count = 0;
|
||||||
nss->display_privs(nss, pw);
|
tq_foreach_fwd(snl, nss)
|
||||||
|
count += nss->display_defaults(nss, pw, &lbuf);
|
||||||
|
if (count) {
|
||||||
|
/* XXX - defer printing until we find a command the user can run? */
|
||||||
|
printf("Matching Defaults entries for %s on this host:\n", pw->pw_name);
|
||||||
|
lbuf_print(&lbuf);
|
||||||
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Display Runas and Cmnd-specific defaults from all sources. */
|
||||||
|
count = 0;
|
||||||
|
tq_foreach_fwd(snl, nss)
|
||||||
|
count += nss->display_bound_defaults(nss, pw, &lbuf);
|
||||||
|
if (count) {
|
||||||
|
printf("Runas and Command-specific defaults for %s:\n", pw->pw_name);
|
||||||
|
lbuf_print(&lbuf);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("User %s may run the following commands on this host:\n",
|
||||||
|
pw->pw_name);
|
||||||
|
/* Display privileges from all sources. */
|
||||||
|
count = 0;
|
||||||
|
tq_foreach_fwd(snl, nss)
|
||||||
|
count += nss->display_privs(nss, pw, &lbuf);
|
||||||
|
if (count)
|
||||||
|
lbuf_print(&lbuf);
|
||||||
|
lbuf_destroy(&lbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -16,7 +16,9 @@
|
|||||||
* $Sudo$
|
* $Sudo$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct lbuf;
|
||||||
struct passwd;
|
struct passwd;
|
||||||
|
|
||||||
struct sudo_nss {
|
struct sudo_nss {
|
||||||
struct sudo_nss *prev;
|
struct sudo_nss *prev;
|
||||||
struct sudo_nss *next;
|
struct sudo_nss *next;
|
||||||
@@ -25,8 +27,10 @@ struct sudo_nss {
|
|||||||
int (*parse) __P((struct sudo_nss *nss));
|
int (*parse) __P((struct sudo_nss *nss));
|
||||||
int (*setdefs) __P((struct sudo_nss *nss));
|
int (*setdefs) __P((struct sudo_nss *nss));
|
||||||
int (*lookup) __P((struct sudo_nss *nss, int, int));
|
int (*lookup) __P((struct sudo_nss *nss, int, int));
|
||||||
void (*display_privs) __P((struct sudo_nss *nss, struct passwd *));
|
|
||||||
int (*display_cmnd) __P((struct sudo_nss *nss, struct passwd *));
|
int (*display_cmnd) __P((struct sudo_nss *nss, struct passwd *));
|
||||||
|
int (*display_defaults) __P((struct sudo_nss *nss, struct passwd *, struct lbuf *));
|
||||||
|
int (*display_bound_defaults) __P((struct sudo_nss *nss, struct passwd *, struct lbuf *));
|
||||||
|
int (*display_privs) __P((struct sudo_nss *nss, struct passwd *, struct lbuf *));
|
||||||
void *handle;
|
void *handle;
|
||||||
int ret_notfound;
|
int ret_notfound;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user