#define CONF_BOOL 0
#define CONF_INT 1
#define CONF_STR 2
+#define CONF_LIST_STR 4
#define SUDO_LDAP_SSL 1
#define SUDO_LDAP_STARTTLS 2
void *valp; /* pointer into ldap_conf */
};
+struct ldap_config_list_str {
+ struct ldap_config_list_str *next;
+ char val[1];
+};
+
/* ldap configuration structure */
static struct ldap_config {
int port;
char *binddn;
char *bindpw;
char *rootbinddn;
- char *base;
+ struct ldap_config_list_str *base;
char *ssl;
char *tls_cacertfile;
char *tls_cacertdir;
{ "binddn", CONF_STR, FALSE, -1, &ldap_conf.binddn },
{ "bindpw", CONF_STR, FALSE, -1, &ldap_conf.bindpw },
{ "rootbinddn", CONF_STR, FALSE, -1, &ldap_conf.rootbinddn },
- { "sudoers_base", CONF_STR, FALSE, -1, &ldap_conf.base },
+ { "sudoers_base", CONF_LIST_STR, FALSE, -1, &ldap_conf.base },
#ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S
{ "use_sasl", CONF_BOOL, FALSE, -1, &ldap_conf.use_sasl },
{ "sasl_auth_id", CONF_STR, FALSE, -1, &ldap_conf.sasl_auth_id },
efree(*(char **)(cur->valp));
*(char **)(cur->valp) = estrdup(value);
break;
+ case CONF_LIST_STR:
+ {
+ struct ldap_config_list_str **p;
+ size_t len = strlen(value);
+
+ if (len > 0) {
+ p = (struct ldap_config_list_str **)cur->valp;
+ while (*p != NULL)
+ p = &(*p)->next;
+ *p = emalloc(sizeof(struct ldap_config_list_str) + len);
+ memcpy((*p)->val, value, len + 1);
+ (*p)->next = NULL;
+ }
+ }
+ break;
}
break;
}
fprintf(stderr, "port %d\n", ldap_conf.port);
}
fprintf(stderr, "ldap_version %d\n", ldap_conf.version);
+ if (ldap_conf.base) {
+ struct ldap_config_list_str *base = ldap_conf.base;
- fprintf(stderr, "sudoers_base %s\n", ldap_conf.base ?
- ldap_conf.base : "(NONE) <---Sudo will ignore ldap)");
+ do {
+ fprintf(stderr, "sudoers_base %s\n", base->val);
+ } while ((base = base->next) != NULL);
+ } else {
+ fprintf(stderr, "sudoers_base %s\n",
+ "(NONE) <---Sudo will ignore ldap)");
+ }
fprintf(stderr, "binddn %s\n", ldap_conf.binddn ?
ldap_conf.binddn : "(anonymous)");
fprintf(stderr, "bindpw %s\n", ldap_conf.bindpw ?
struct lbuf *lbuf;
{
struct berval **bv, **p;
+ struct ldap_config_list_str *base;
LDAP *ld = (LDAP *) nss->handle;
- LDAPMessage *entry = NULL, *result = NULL;
- char *prefix = NULL;
+ LDAPMessage *entry, *result;
+ char *prefix;
int rc, count = 0;
if (ld == NULL)
return(-1);
- rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE,
- "cn=defaults", NULL, 0, NULL, NULL, NULL, 0, &result);
- if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) {
- bv = ldap_get_values_len(ld, entry, "sudoOption");
- if (bv != NULL) {
- prefix = " ";
- for (p = bv; *p != NULL; p++) {
- lbuf_append(lbuf, prefix, (*p)->bv_val, NULL);
- prefix = ", ";
- count++;
+ for (base = ldap_conf.base; base != NULL; base = base->next) {
+ result = NULL;
+ rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE,
+ "cn=defaults", NULL, 0, NULL, NULL, NULL, 0, &result);
+ if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) {
+ bv = ldap_get_values_len(ld, entry, "sudoOption");
+ if (bv != NULL) {
+ prefix = " ";
+ for (p = bv; *p != NULL; p++) {
+ lbuf_append(lbuf, prefix, (*p)->bv_val, NULL);
+ prefix = ", ";
+ count++;
+ }
+ ldap_value_free_len(bv);
}
- ldap_value_free_len(bv);
}
+ if (result)
+ ldap_msgfree(result);
}
- if (result)
- ldap_msgfree(result);
return(count);
}
struct passwd *pw;
struct lbuf *lbuf;
{
+ struct ldap_config_list_str *base;
LDAP *ld = (LDAP *) nss->handle;
- LDAPMessage *entry = NULL, *result = NULL;
+ LDAPMessage *entry, *result;
char *filt;
int rc, do_netgr, count = 0;
for (do_netgr = 0; do_netgr < 2; do_netgr++) {
filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
DPRINTF(("ldap search '%s'", filt), 1);
- rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
- NULL, 0, NULL, NULL, NULL, 0, &result);
- efree(filt);
- if (rc != LDAP_SUCCESS)
- continue; /* no entries for this pass */
-
- /* print each matching entry */
- LDAP_FOREACH(entry, ld, result) {
- if ((!do_netgr ||
- sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) &&
- sudo_ldap_check_host(ld, entry)) {
-
- if (long_list)
- count += sudo_ldap_display_entry_long(ld, entry, lbuf);
- else
- count += sudo_ldap_display_entry_short(ld, entry, lbuf);
+ for (base = ldap_conf.base; base != NULL; base = base->next) {
+ result = NULL;
+ rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt,
+ NULL, 0, NULL, NULL, NULL, 0, &result);
+ if (rc != LDAP_SUCCESS)
+ continue; /* no entries for this pass */
+
+ /* print each matching entry */
+ LDAP_FOREACH(entry, ld, result) {
+ if ((!do_netgr ||
+ sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) &&
+ sudo_ldap_check_host(ld, entry)) {
+
+ if (long_list)
+ count += sudo_ldap_display_entry_long(ld, entry, lbuf);
+ else
+ count += sudo_ldap_display_entry_short(ld, entry, lbuf);
+ }
}
+ ldap_msgfree(result);
}
- ldap_msgfree(result);
- result = NULL;
+ efree(filt);
}
return(count);
}
struct sudo_nss *nss;
struct passwd *pw;
{
+ struct ldap_config_list_str *base;
LDAP *ld = (LDAP *) nss->handle;
- LDAPMessage *entry = NULL, *result = NULL; /* used for searches */
+ LDAPMessage *entry, *result; /* used for searches */
char *filt; /* used to parse attributes */
int rc, found, do_netgr; /* temp/final return values */
for (found = FALSE, do_netgr = 0; !found && do_netgr < 2; do_netgr++) {
filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
DPRINTF(("ldap search '%s'", filt), 1);
- rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
- NULL, 0, NULL, NULL, NULL, 0, &result);
- efree(filt);
- if (rc != LDAP_SUCCESS)
- continue; /* no entries for this pass */
+ for (base = ldap_conf.base; base != NULL; base = base->next) {
+ result = NULL;
+ rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt,
+ NULL, 0, NULL, NULL, NULL, 0, &result);
+ if (rc != LDAP_SUCCESS)
+ continue; /* no entries for this pass */
- LDAP_FOREACH(entry, ld, result) {
- if ((!do_netgr ||
- sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) &&
- sudo_ldap_check_host(ld, entry) &&
- sudo_ldap_check_command(ld, entry, NULL) &&
- sudo_ldap_check_runas(ld, entry)) {
+ LDAP_FOREACH(entry, ld, result) {
+ if ((!do_netgr ||
+ sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) &&
+ sudo_ldap_check_host(ld, entry) &&
+ sudo_ldap_check_command(ld, entry, NULL) &&
+ sudo_ldap_check_runas(ld, entry)) {
- found = TRUE;
- break;
+ found = TRUE;
+ break;
+ }
}
+ ldap_msgfree(result);
}
- ldap_msgfree(result);
- result = NULL;
+ efree(filt);
}
if (found)
sudo_ldap_setdefs(nss)
struct sudo_nss *nss;
{
+ struct ldap_config_list_str *base;
LDAP *ld = (LDAP *) nss->handle;
- LDAPMessage *entry = NULL, *result = NULL; /* used for searches */
+ LDAPMessage *entry, *result; /* used for searches */
int rc; /* temp return value */
if (ld == NULL)
return(-1);
- rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE,
- "cn=defaults", NULL, 0, NULL, NULL, NULL, 0, &result);
- if (rc == 0 && (entry = ldap_first_entry(ld, result))) {
- DPRINTF(("found:%s", ldap_get_dn(ld, entry)), 1);
- sudo_ldap_parse_options(ld, entry);
- } else
- DPRINTF(("no default options found!"), 1);
-
- if (result)
- ldap_msgfree(result);
+ for (base = ldap_conf.base; base != NULL; base = base->next) {
+ result = NULL;
+ rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE,
+ "cn=defaults", NULL, 0, NULL, NULL, NULL, 0, &result);
+ if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) {
+ DPRINTF(("found:%s", ldap_get_dn(ld, entry)), 1);
+ sudo_ldap_parse_options(ld, entry);
+ } else
+ DPRINTF(("no default options found in %s", base->val), 1);
+
+ if (result)
+ ldap_msgfree(result);
+ }
return(0);
}
int ret;
int pwflag;
{
+ struct ldap_config_list_str *base;
LDAP *ld = (LDAP *) nss->handle;
- LDAPMessage *entry = NULL, *result = NULL;
+ LDAPMessage *entry, *result;
char *filt;
int do_netgr, rc, matched;
int setenv_implied;
for (matched = 0, do_netgr = 0; !matched && do_netgr < 2; do_netgr++) {
filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
- rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
- NULL, 0, NULL, NULL, NULL, 0, &result);
- efree(filt);
- if (rc != LDAP_SUCCESS)
- continue;
-
- LDAP_FOREACH(entry, ld, result) {
- /* only verify netgroup matches in pass 2 */
- if (do_netgr && !sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name))
+ for (base = ldap_conf.base; base != NULL; base = base->next) {
+ result = NULL;
+ rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt,
+ NULL, 0, NULL, NULL, NULL, 0, &result);
+ if (rc != LDAP_SUCCESS)
continue;
- ldap_user_matches = TRUE;
- if (sudo_ldap_check_host(ld, entry)) {
- ldap_host_matches = TRUE;
- if ((pwcheck == any && doauth != FALSE) ||
- (pwcheck == all && doauth == FALSE))
- doauth = sudo_ldap_check_bool(ld, entry, "authenticate");
- /* Only check the command when listing another user. */
- if (user_uid == 0 || list_pw == NULL ||
- user_uid == list_pw->pw_uid ||
- sudo_ldap_check_command(ld, entry, NULL)) {
- matched = 1;
- break; /* end foreach */
+ LDAP_FOREACH(entry, ld, result) {
+ /* only verify netgroup matches in pass 2 */
+ if (do_netgr && !sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name))
+ continue;
+
+ ldap_user_matches = TRUE;
+ if (sudo_ldap_check_host(ld, entry)) {
+ ldap_host_matches = TRUE;
+ if ((pwcheck == any && doauth != FALSE) ||
+ (pwcheck == all && doauth == FALSE))
+ doauth = sudo_ldap_check_bool(ld, entry, "authenticate");
+ /* Only check the command when listing another user. */
+ if (user_uid == 0 || list_pw == NULL ||
+ user_uid == list_pw->pw_uid ||
+ sudo_ldap_check_command(ld, entry, NULL)) {
+ matched = 1;
+ break; /* end foreach */
+ }
}
}
+ ldap_msgfree(result);
}
- ldap_msgfree(result);
- result = NULL;
+ efree(filt);
}
if (matched || user_uid == 0) {
SET(ret, VALIDATE_OK);
for (matched = 0, do_netgr = 0; !matched && do_netgr < 2; do_netgr++) {
filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
DPRINTF(("ldap search '%s'", filt), 1);
- rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
- NULL, 0, NULL, NULL, NULL, 0, &result);
- if (rc != LDAP_SUCCESS)
- DPRINTF(("nothing found for '%s'", filt), 1);
- efree(filt);
+ for (base = ldap_conf.base; base != NULL; base = base->next) {
+ result = NULL;
+ rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt,
+ NULL, 0, NULL, NULL, NULL, 0, &result);
+ if (rc != LDAP_SUCCESS) {
+ DPRINTF(("nothing found for '%s'", filt), 1);
+ continue;
+ }
- /* parse each entry returned from this most recent search */
- if (rc == LDAP_SUCCESS) {
+ /* parse each entry returned from this most recent search */
LDAP_FOREACH(entry, ld, result) {
DPRINTF(("found:%s", ldap_get_dn(ld, entry)), 1);
if (
}
}
ldap_msgfree(result);
- result = NULL;
}
+ efree(filt);
}
done: