#include "sudo.h"
#include "parse.h"
+#include "lbuf.h"
#ifndef lint
__unused static const char rcsid[] = "$Sudo$";
sudo_ldap_parse,
sudo_ldap_setdefs,
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
}
/*
- * Like sudo_ldap_lookup(), except we just print entries.
+ * Fetch and display the global Options.
*/
-void
-sudo_ldap_display_privs(nss, pw)
+int
+sudo_ldap_display_defaults(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;
+ char *prefix = NULL;
+ int rc, count = 0;
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,
"cn=defaults", NULL, 0, NULL, NULL, NULL, -1, &result);
if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) {
bv = ldap_get_values_len(ld, entry, "sudoOption");
if (bv != NULL) {
- fputs("Global LDAP options:\n ", stdout);
+ if (lbuf->len == 0)
+ prefix = " ";
+ else
+ prefix = ", ";
for (p = bv; *p != NULL; p++) {
- if (p != bv)
- fputs("\n ", stdout);
- fputs((*p)->bv_val, stdout);
+ lbuf_append(lbuf, prefix, (*p)->bv_val, NULL);
+ prefix = ", ";
+ count++;
}
- putchar('\n');
ldap_value_free_len(bv);
}
}
- if (result) {
+ if (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
sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) &&
sudo_ldap_check_host(ld, entry)) {
+#if 0
/* extract the dn, only show the first rdn */
+ /* XXX - how to display the role sudo-style? */
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)
ldap_memfree(rdn);
-
- /* get the Option Values from the entry */
- 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);
- }
+#endif
+ lbuf_append(lbuf, " (", NULL);
/* get the RunAsUser Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoRunAsUser");
if (bv == NULL)
bv = ldap_get_values_len(ld, entry, "sudoRunAs");
if (bv != NULL) {
- fputs(" RunAsUsers: ", stdout);
for (p = bv; *p != NULL; p++) {
if (p != bv)
- fputs(", ", stdout);
- fputs((*p)->bv_val, stdout);
+ lbuf_append(lbuf, ", ", NULL);
+ lbuf_append(lbuf, (*p)->bv_val, NULL);
}
- putchar('\n');
ldap_value_free_len(bv);
- }
+ } else
+ lbuf_append(lbuf, def_runas_default, NULL);
/* get the RunAsGroup Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup");
if (bv != NULL) {
- fputs(" RunAsGroups: ", stdout);
+ lbuf_append(lbuf, " : ", NULL);
for (p = bv; *p != NULL; p++) {
if (p != bv)
- fputs(", ", stdout);
- fputs((*p)->bv_val, stdout);
+ lbuf_append(lbuf, ", ", NULL);
+ 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);
}
/* get the Command Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoCommand");
if (bv != NULL) {
- fputs(" Commands:\n ", stdout);
for (p = bv; *p != NULL; p++) {
if (p != bv)
- fputs("\n ", stdout);
- fputs((*p)->bv_val, stdout);
+ lbuf_append(lbuf, ", ", NULL);
+ lbuf_append(lbuf, (*p)->bv_val, NULL);
+ count++;
}
- putchar('\n');
ldap_value_free_len(bv);
- } else {
- puts(" Commands: NONE");
}
}
+ lbuf_print(lbuf); /* forces a newline */
}
ldap_msgfree(result);
result = NULL;
}
+ return(count);
}
int
sudo_file_parse,
sudo_file_setdefs,
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
};
/*
* Local prototypes.
*/
static void print_member __P((struct lbuf *, char *, int, int, int));
-static void display_defaults __P((struct passwd *));
-static void display_bound_defaults __P((int));
+static int display_bound_defaults __P((int, struct lbuf *));
int
sudo_file_open(nss)
#define TAG_CHANGED(t) \
(cs->tags.t != UNSPEC && cs->tags.t != IMPLIED && cs->tags.t != tags.t)
-void
-sudo_file_display_privs(nss, pw)
+int
+sudo_file_display_privs(nss, pw, lbuf)
struct sudo_nss *nss;
struct passwd *pw;
+ struct lbuf *lbuf;
{
- struct lbuf lbuf;
struct cmndspec *cs;
struct member *m;
struct privilege *priv;
struct userspec *us;
struct cmndtag tags;
+ int nfound = 0;
- display_defaults(pw);
-
- lbuf_init(&lbuf, NULL, 8, '\\');
- printf("User %s may run the following commands on this host:\n",
- pw->pw_name);
+ if (nss->handle == NULL)
+ return(-1);
tq_foreach_fwd(&userspecs, us) {
/* XXX - why only check the first privilege here? */
tags.noexec = def_noexec;
tags.setenv = def_setenv;
tags.nopasswd = !def_authenticate;
- lbuf_append(&lbuf, " ", NULL);
+ lbuf_append(lbuf, " ", NULL);
tq_foreach_fwd(&priv->cmndlist, cs) {
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)) {
tq_foreach_fwd(&cs->runasuserlist, m) {
if (m != tq_first(&cs->runasuserlist))
- lbuf_append(&lbuf, ", ", NULL);
- print_member(&lbuf, m->name, m->type, m->negated,
+ lbuf_append(lbuf, ", ", NULL);
+ print_member(lbuf, m->name, m->type, m->negated,
RUNASALIAS);
}
} else {
- lbuf_append(&lbuf, def_runas_default, NULL);
+ lbuf_append(lbuf, def_runas_default, NULL);
}
if (!tq_empty(&cs->runasgrouplist)) {
- lbuf_append(&lbuf, " : ", NULL);
+ lbuf_append(lbuf, " : ", NULL);
tq_foreach_fwd(&cs->runasgrouplist, m) {
if (m != tq_first(&cs->runasgrouplist))
- lbuf_append(&lbuf, ", ", NULL);
- print_member(&lbuf, m->name, m->type, m->negated,
+ lbuf_append(lbuf, ", ", NULL);
+ print_member(lbuf, m->name, m->type, m->negated,
RUNASALIAS);
}
}
- lbuf_append(&lbuf, ") ", NULL);
+ lbuf_append(lbuf, ") ", NULL);
if (TAG_CHANGED(setenv)) {
- lbuf_append(&lbuf, cs->tags.setenv ? "SETENV: " :
+ lbuf_append(lbuf, cs->tags.setenv ? "SETENV: " :
"NOSETENV: ", NULL);
tags.setenv = cs->tags.setenv;
}
if (TAG_CHANGED(noexec)) {
- lbuf_append(&lbuf, cs->tags.noexec ? "NOEXEC: " :
+ lbuf_append(lbuf, cs->tags.noexec ? "NOEXEC: " :
"EXEC: ", NULL);
tags.noexec = cs->tags.noexec;
}
if (TAG_CHANGED(nopasswd)) {
- lbuf_append(&lbuf, cs->tags.nopasswd ? "NOPASSWD: " :
+ lbuf_append(lbuf, cs->tags.nopasswd ? "NOPASSWD: " :
"PASSWD: ", NULL);
tags.nopasswd = cs->tags.nopasswd;
}
m = cs->cmnd;
- print_member(&lbuf, m->name, m->type, m->negated,
+ print_member(lbuf, m->name, m->type, m->negated,
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.
*/
-static void
-display_defaults(pw)
+int
+sudo_file_display_defaults(nss, pw, lbuf)
+ struct sudo_nss *nss;
struct passwd *pw;
+ struct lbuf *lbuf;
{
struct defaults *d;
- struct lbuf lbuf;
char *prefix = NULL;
- int per_runas = 0, per_cmnd = 0;
+ int nfound = 0;
+
+ if (nss->handle == NULL)
+ return(-1);
- lbuf_init(&lbuf, NULL, 4, 0);
+ if (lbuf->len == 0)
+ prefix = " ";
+ else
+ prefix = ", ";
tq_foreach_fwd(&defaults, d) {
switch (d->type) {
continue;
break;
case DEFAULTS_RUNAS:
- per_runas = 1;
- continue;
case DEFAULTS_CMND:
- per_cmnd = 1;
continue;
}
- if (prefix == NULL) {
- printf("Matching Defaults entries for %s on this host:\n",
- pw->pw_name);
- prefix = " ";
- }
- lbuf_append(&lbuf, prefix, NULL);
+ lbuf_append(lbuf, prefix, NULL);
if (d->val != NULL) {
- lbuf_append(&lbuf, d->var, d->op == '+' ? " += " :
- d->op == '-' ? " -= " : " = ", NULL);
+ lbuf_append(lbuf, d->var, d->op == '+' ? "+=" :
+ d->op == '-' ? "-=" : "=", NULL);
if (strpbrk(d->val, " \t") != NULL) {
- lbuf_append(&lbuf, "\"", NULL);
- lbuf_append_quoted(&lbuf, "\"", d->val, NULL);
- lbuf_append(&lbuf, "\"", NULL);
+ lbuf_append(lbuf, "\"", NULL);
+ lbuf_append_quoted(lbuf, "\"", d->val, NULL);
+ lbuf_append(lbuf, "\"", NULL);
} else
- lbuf_append_quoted(&lbuf, SUDOERS_QUOTED, d->val, NULL);
+ lbuf_append_quoted(lbuf, SUDOERS_QUOTED, d->val, NULL);
} else
- lbuf_append(&lbuf, d->op == FALSE ? "!" : "", d->var, NULL);
+ lbuf_append(lbuf, d->op == FALSE ? "!" : "", d->var, NULL);
prefix = ", ";
+ nfound++;
}
- if (prefix) {
- lbuf_print(&lbuf);
- putchar('\n');
- }
- lbuf_destroy(&lbuf);
- if (per_runas)
- display_bound_defaults(DEFAULTS_RUNAS);
- if (per_cmnd)
- display_bound_defaults(DEFAULTS_CMND);
+ return(nfound);
+}
+
+/*
+ * 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.
*/
-static void
-display_bound_defaults(dtype)
+static int
+display_bound_defaults(dtype, lbuf)
int dtype;
+ struct lbuf *lbuf;
{
- struct lbuf lbuf;
struct defaults *d;
struct member *m, *binding = NULL;
char *dname, *dsep;
- int atype;
+ int atype, nfound = 0;
switch (dtype) {
case DEFAULTS_HOST:
dsep = "!";
break;
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) {
if (d->type != dtype)
continue;
+ nfound++;
if (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) {
if (m != binding)
- lbuf_append(&lbuf, ",", NULL);
- print_member(&lbuf, m->name, m->type, m->negated, atype);
- lbuf_append(&lbuf, " ", NULL);
+ lbuf_append(lbuf, ",", NULL);
+ print_member(lbuf, m->name, m->type, m->negated, atype);
+ lbuf_append(lbuf, " ", NULL);
}
} else
- lbuf_append(&lbuf, ", ", NULL);
+ lbuf_append(lbuf, ", ", NULL);
if (d->val != NULL) {
- lbuf_append(&lbuf, d->var, d->op == '+' ? "+=" :
+ lbuf_append(lbuf, d->var, d->op == '+' ? "+=" :
d->op == '-' ? "-=" : "=", d->val, NULL);
} 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);
- putchar('\n');
+
+ return(nfound);
}
int