version 1.1.1.5, 2013/10/14 07:56:34
|
version 1.1.1.6, 2014/06/15 16:12:54
|
Line 1
|
Line 1
|
/* |
/* |
* Copyright (c) 2003-2013 Todd C. Miller <Todd.Miller@courtesan.com> | * Copyright (c) 2003-2014 Todd C. Miller <Todd.Miller@courtesan.com> |
* |
* |
* This code is derived from software contributed by Aaron Spangler. |
* This code is derived from software contributed by Aaron Spangler. |
* |
* |
Line 39
|
Line 39
|
#ifdef HAVE_UNISTD_H |
#ifdef HAVE_UNISTD_H |
# include <unistd.h> |
# include <unistd.h> |
#endif /* HAVE_UNISTD_H */ |
#endif /* HAVE_UNISTD_H */ |
#if TIME_WITH_SYS_TIME | #ifdef TIME_WITH_SYS_TIME |
# include <time.h> |
# include <time.h> |
#endif |
#endif |
#include <ctype.h> |
#include <ctype.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <pwd.h> |
#include <pwd.h> |
#include <grp.h> |
#include <grp.h> |
|
#include <signal.h> |
#include <netinet/in.h> |
#include <netinet/in.h> |
#include <arpa/inet.h> |
#include <arpa/inet.h> |
#ifdef HAVE_LBER_H |
#ifdef HAVE_LBER_H |
Line 63
|
Line 64
|
# else |
# else |
# include <sasl.h> |
# include <sasl.h> |
# endif |
# endif |
# ifdef HAVE_DLOPEN |
|
# include <dlfcn.h> |
|
# else |
|
# include "compat/dlfcn.h" |
|
# endif |
|
#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */ |
#endif /* HAVE_LDAP_SASL_INTERACTIVE_BIND_S */ |
|
|
#include "sudoers.h" |
#include "sudoers.h" |
#include "parse.h" |
#include "parse.h" |
#include "lbuf.h" |
#include "lbuf.h" |
|
#include "sudo_dso.h" |
|
|
/* Older Netscape LDAP SDKs don't prototype ldapssl_set_strength() */ |
/* Older Netscape LDAP SDKs don't prototype ldapssl_set_strength() */ |
#if defined(HAVE_LDAPSSL_SET_STRENGTH) && !defined(HAVE_LDAP_SSL_H) && !defined(HAVE_MPS_LDAP_SSL_H) |
#if defined(HAVE_LDAPSSL_SET_STRENGTH) && !defined(HAVE_LDAP_SSL_H) && !defined(HAVE_MPS_LDAP_SSL_H) |
Line 148 extern int ldapssl_set_strength(LDAP *ldap, int streng
|
Line 145 extern int ldapssl_set_strength(LDAP *ldap, int streng
|
#define SUDO_LDAP_SSL 1 |
#define SUDO_LDAP_SSL 1 |
#define SUDO_LDAP_STARTTLS 2 |
#define SUDO_LDAP_STARTTLS 2 |
|
|
|
/* Default search filter. */ |
|
#define DEFAULT_SEARCH_FILTER "(objectClass=sudoRole)" |
|
|
/* The TIMEFILTER_LENGTH is the length of the filter when timed entries |
/* The TIMEFILTER_LENGTH is the length of the filter when timed entries |
are used. The length is computed as follows: |
are used. The length is computed as follows: |
81 for the filter itself |
81 for the filter itself |
Line 159 extern int ldapssl_set_strength(LDAP *ldap, int streng
|
Line 159 extern int ldapssl_set_strength(LDAP *ldap, int streng
|
* The ldap_search structure implements a linked list of ldap and |
* The ldap_search structure implements a linked list of ldap and |
* search result pointers, which allows us to remove them after |
* search result pointers, which allows us to remove them after |
* all search results have been combined in memory. |
* all search results have been combined in memory. |
* XXX - should probably be a tailq since we do appends |
|
*/ |
*/ |
struct ldap_search_list { | struct ldap_search_result { |
| STAILQ_ENTRY(ldap_search_result) entries; |
LDAP *ldap; |
LDAP *ldap; |
LDAPMessage *searchresult; |
LDAPMessage *searchresult; |
struct ldap_search_list *next; |
|
}; |
}; |
|
STAILQ_HEAD(ldap_search_list, ldap_search_result); |
|
|
/* |
/* |
* The ldap_entry_wrapper structure is used to implement sorted result entries. |
* The ldap_entry_wrapper structure is used to implement sorted result entries. |
Line 184 struct ldap_entry_wrapper {
|
Line 184 struct ldap_entry_wrapper {
|
* well as an array of all result entries sorted by the sudoOrder attribute. |
* well as an array of all result entries sorted by the sudoOrder attribute. |
*/ |
*/ |
struct ldap_result { |
struct ldap_result { |
struct ldap_search_list *searches; | struct ldap_search_list searches; |
struct ldap_entry_wrapper *entries; |
struct ldap_entry_wrapper *entries; |
int allocated_entries; |
int allocated_entries; |
int nentries; |
int nentries; |
Line 200 struct ldap_config_table {
|
Line 200 struct ldap_config_table {
|
void *valp; /* pointer into ldap_conf */ |
void *valp; /* pointer into ldap_conf */ |
}; |
}; |
|
|
struct ldap_config_list_str { | struct ldap_config_str { |
struct ldap_config_list_str *next; | STAILQ_ENTRY(ldap_config_str) entries; |
char val[1]; |
char val[1]; |
}; |
}; |
|
|
|
STAILQ_HEAD(ldap_config_str_list, ldap_config_str); |
|
|
/* LDAP configuration structure */ |
/* LDAP configuration structure */ |
static struct ldap_config { |
static struct ldap_config { |
int port; |
int port; |
Line 221 static struct ldap_config {
|
Line 223 static struct ldap_config {
|
int timed; |
int timed; |
int deref; |
int deref; |
char *host; |
char *host; |
struct ldap_config_list_str *uri; | struct ldap_config_str_list uri; |
char *binddn; |
char *binddn; |
char *bindpw; |
char *bindpw; |
char *rootbinddn; |
char *rootbinddn; |
struct ldap_config_list_str *base; | struct ldap_config_str_list base; |
char *search_filter; |
char *search_filter; |
char *ssl; |
char *ssl; |
char *tls_cacertfile; |
char *tls_cacertfile; |
Line 371 struct sudo_ldap_handle {
|
Line 373 struct sudo_ldap_handle {
|
}; |
}; |
|
|
struct sudo_nss sudo_nss_ldap = { |
struct sudo_nss sudo_nss_ldap = { |
&sudo_nss_ldap, | { NULL, NULL }, |
NULL, | |
sudo_ldap_open, |
sudo_ldap_open, |
sudo_ldap_close, |
sudo_ldap_close, |
sudo_ldap_parse, |
sudo_ldap_parse, |
Line 396 sudo_ldap_conf_add_ports(void)
|
Line 397 sudo_ldap_conf_add_ports(void)
|
|
|
char *host, *port, defport[13]; |
char *host, *port, defport[13]; |
char hostbuf[LINE_MAX * 2]; |
char hostbuf[LINE_MAX * 2]; |
|
int len; |
debug_decl(sudo_ldap_conf_add_ports, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_conf_add_ports, SUDO_DEBUG_LDAP) |
|
|
hostbuf[0] = '\0'; |
hostbuf[0] = '\0'; |
if (snprintf(defport, sizeof(defport), ":%d", ldap_conf.port) >= sizeof(defport)) | len = snprintf(defport, sizeof(defport), ":%d", ldap_conf.port); |
fatalx(_("sudo_ldap_conf_add_ports: port too large")); | if (len <= 0 || (size_t)len >= sizeof(defport)) |
| fatalx(U_("sudo_ldap_conf_add_ports: port too large")); |
|
|
for ((host = strtok(ldap_conf.host, " \t")); host; (host = strtok(NULL, " \t"))) { |
for ((host = strtok(ldap_conf.host, " \t")); host; (host = strtok(NULL, " \t"))) { |
if (hostbuf[0] != '\0') { |
if (hostbuf[0] != '\0') { |
Line 423 sudo_ldap_conf_add_ports(void)
|
Line 426 sudo_ldap_conf_add_ports(void)
|
debug_return; |
debug_return; |
|
|
toobig: |
toobig: |
fatalx(_("sudo_ldap_conf_add_ports: out of space expanding hostbuf")); | fatalx(U_("sudo_ldap_conf_add_ports: out of space expanding hostbuf")); |
} |
} |
#endif |
#endif |
|
|
Line 432 toobig:
|
Line 435 toobig:
|
* For each uri, convert to host:port pairs. For ldaps:// enable SSL |
* For each uri, convert to host:port pairs. For ldaps:// enable SSL |
* Accepts: uris of the form ldap:/// or ldap://hostname:portnum/ |
* Accepts: uris of the form ldap:/// or ldap://hostname:portnum/ |
* where the trailing slash is optional. |
* where the trailing slash is optional. |
|
* Returns LDAP_SUCCESS on success, else non-zero. |
*/ |
*/ |
static int |
static int |
sudo_ldap_parse_uri(const struct ldap_config_list_str *uri_list) | sudo_ldap_parse_uri(const struct ldap_config_str_list *uri_list) |
{ |
{ |
|
const struct ldap_config_str *entry; |
char *buf, *uri, *host, *cp, *port; |
char *buf, *uri, *host, *cp, *port; |
char hostbuf[LINE_MAX]; |
char hostbuf[LINE_MAX]; |
int nldap = 0, nldaps = 0; |
int nldap = 0, nldaps = 0; |
int rc = -1; |
int rc = -1; |
debug_decl(sudo_ldap_parse_uri, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_parse_uri, SUDO_DEBUG_LDAP) |
|
|
do { | hostbuf[0] = '\0'; |
buf = estrdup(uri_list->val); | STAILQ_FOREACH(entry, uri_list, entries) { |
hostbuf[0] = '\0'; | buf = estrdup(entry->val); |
for ((uri = strtok(buf, " \t")); uri != NULL; (uri = strtok(NULL, " \t"))) { |
for ((uri = strtok(buf, " \t")); uri != NULL; (uri = strtok(NULL, " \t"))) { |
if (strncasecmp(uri, "ldap://", 7) == 0) { |
if (strncasecmp(uri, "ldap://", 7) == 0) { |
nldap++; |
nldap++; |
Line 453 sudo_ldap_parse_uri(const struct ldap_config_list_str
|
Line 458 sudo_ldap_parse_uri(const struct ldap_config_list_str
|
nldaps++; |
nldaps++; |
host = uri + 8; |
host = uri + 8; |
} else { |
} else { |
warningx(_("unsupported LDAP uri type: %s"), uri); | warningx(U_("unsupported LDAP uri type: %s"), uri); |
goto done; |
goto done; |
} |
} |
|
|
Line 481 sudo_ldap_parse_uri(const struct ldap_config_list_str
|
Line 486 sudo_ldap_parse_uri(const struct ldap_config_list_str
|
goto toobig; |
goto toobig; |
} |
} |
} |
} |
if (hostbuf[0] == '\0') { |
|
warningx(_("invalid uri: %s"), uri_list->val); |
|
goto done; |
|
} |
|
|
|
if (nldaps != 0) { |
if (nldaps != 0) { |
if (nldap != 0) { |
if (nldap != 0) { |
warningx(_("unable to mix ldap and ldaps URIs")); | warningx(U_("unable to mix ldap and ldaps URIs")); |
goto done; |
goto done; |
} |
} |
if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) { | if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) |
warningx(_("unable to mix ldaps and starttls")); | warningx(U_("starttls not supported when using ldaps")); |
goto done; | |
} | |
ldap_conf.ssl_mode = SUDO_LDAP_SSL; |
ldap_conf.ssl_mode = SUDO_LDAP_SSL; |
} |
} |
|
|
efree(ldap_conf.host); |
|
ldap_conf.host = estrdup(hostbuf); |
|
efree(buf); |
efree(buf); |
} while ((uri_list = uri_list->next)); | } |
| |
buf = NULL; |
buf = NULL; |
rc = 0; |
|
|
|
|
/* Store parsed URI(s) in host for ldap_create() or ldap_init(). */ |
|
efree(ldap_conf.host); |
|
ldap_conf.host = estrdup(hostbuf); |
|
|
|
rc = LDAP_SUCCESS; |
|
|
done: |
done: |
efree(buf); |
efree(buf); |
debug_return_int(rc); |
debug_return_int(rc); |
|
|
toobig: |
toobig: |
fatalx(_("sudo_ldap_parse_uri: out of space building hostbuf")); | fatalx(U_("sudo_ldap_parse_uri: out of space building hostbuf")); |
} |
} |
#else |
#else |
static char * |
static char * |
sudo_ldap_join_uri(struct ldap_config_list_str *uri_list) | sudo_ldap_join_uri(struct ldap_config_str_list *uri_list) |
{ |
{ |
struct ldap_config_list_str *uri; | struct ldap_config_str *uri; |
size_t len = 0; |
size_t len = 0; |
char *buf, *cp; |
char *buf, *cp; |
debug_decl(sudo_ldap_join_uri, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_join_uri, SUDO_DEBUG_LDAP) |
|
|
/* Usually just a single entry. */ | STAILQ_FOREACH(uri, uri_list, entries) { |
if (uri_list->next == NULL) | if (ldap_conf.ssl_mode == SUDO_LDAP_STARTTLS) { |
debug_return_str(estrdup(uri_list->val)); | if (strncasecmp(uri->val, "ldaps://", 8) == 0) { |
| warningx(U_("starttls not supported when using ldaps")); |
for (uri = uri_list; uri != NULL; uri = uri->next) { | ldap_conf.ssl_mode = SUDO_LDAP_SSL; |
| } |
| } |
len += strlen(uri->val) + 1; |
len += strlen(uri->val) + 1; |
} |
} |
buf = cp = emalloc(len); |
buf = cp = emalloc(len); |
buf[0] = '\0'; |
buf[0] = '\0'; |
for (uri = uri_list; uri != NULL; uri = uri->next) { | STAILQ_FOREACH(uri, uri_list, entries) { |
cp += strlcpy(cp, uri->val, len - (cp - buf)); |
cp += strlcpy(cp, uri->val, len - (cp - buf)); |
*cp++ = ' '; |
*cp++ = ' '; |
} |
} |
Line 540 sudo_ldap_join_uri(struct ldap_config_list_str *uri_li
|
Line 542 sudo_ldap_join_uri(struct ldap_config_list_str *uri_li
|
} |
} |
#endif /* HAVE_LDAP_INITIALIZE */ |
#endif /* HAVE_LDAP_INITIALIZE */ |
|
|
|
/* |
|
* Wrapper for ldap_create() or ldap_init() that handles |
|
* SSL/TLS initialization as well. |
|
* Returns LDAP_SUCCESS on success, else non-zero. |
|
*/ |
static int |
static int |
sudo_ldap_init(LDAP **ldp, const char *host, int port) |
sudo_ldap_init(LDAP **ldp, const char *host, int port) |
{ |
{ |
LDAP *ld = NULL; | LDAP *ld; |
int rc = LDAP_CONNECT_ERROR; |
int rc = LDAP_CONNECT_ERROR; |
debug_decl(sudo_ldap_init, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_init, SUDO_DEBUG_LDAP) |
|
|
Line 585 sudo_ldap_init(LDAP **ldp, const char *host, int port)
|
Line 592 sudo_ldap_init(LDAP **ldp, const char *host, int port)
|
} |
} |
} |
} |
if (rc != LDAP_SUCCESS) { |
if (rc != LDAP_SUCCESS) { |
warningx(_("unable to initialize SSL cert and key db: %s"), | warningx(U_("unable to initialize SSL cert and key db: %s"), |
ldapssl_err2string(rc)); |
ldapssl_err2string(rc)); |
if (ldap_conf.tls_certfile == NULL) |
if (ldap_conf.tls_certfile == NULL) |
warningx(_("you must set TLS_CERT in %s to use SSL"), | warningx(U_("you must set TLS_CERT in %s to use SSL"), |
path_ldap_conf); |
path_ldap_conf); |
goto done; |
goto done; |
} |
} |
Line 605 sudo_ldap_init(LDAP **ldp, const char *host, int port)
|
Line 612 sudo_ldap_init(LDAP **ldp, const char *host, int port)
|
if (rc != LDAP_SUCCESS) { |
if (rc != LDAP_SUCCESS) { |
warningx("ldap_ssl_client_init(): %s (SSL reason code %d)", |
warningx("ldap_ssl_client_init(): %s (SSL reason code %d)", |
ldap_err2string(rc), sslrc); |
ldap_err2string(rc), sslrc); |
debug_return_int(-1); | goto done; |
} |
} |
DPRINTF2("ldap_ssl_init(%s, %d, NULL)", host, port); |
DPRINTF2("ldap_ssl_init(%s, %d, NULL)", host, port); |
if ((ld = ldap_ssl_init((char *)host, port, NULL)) != NULL) |
if ((ld = ldap_ssl_init((char *)host, port, NULL)) != NULL) |
Line 621 sudo_ldap_init(LDAP **ldp, const char *host, int port)
|
Line 628 sudo_ldap_init(LDAP **ldp, const char *host, int port)
|
rc = ldap_set_option(ld, LDAP_OPT_HOST_NAME, host); |
rc = ldap_set_option(ld, LDAP_OPT_HOST_NAME, host); |
#else |
#else |
DPRINTF2("ldap_init(%s, %d)", host, port); |
DPRINTF2("ldap_init(%s, %d)", host, port); |
if ((ld = ldap_init((char *)host, port)) != NULL) | if ((ld = ldap_init((char *)host, port)) == NULL) |
rc = LDAP_SUCCESS; | goto done; |
| rc = LDAP_SUCCESS; |
#endif |
#endif |
} |
} |
|
|
done: |
|
*ldp = ld; |
*ldp = ld; |
|
done: |
debug_return_int(rc); |
debug_return_int(rc); |
} |
} |
|
|
Line 1078 sudo_ldap_timefilter(char *buffer, size_t buffersize)
|
Line 1086 sudo_ldap_timefilter(char *buffer, size_t buffersize)
|
/* Make sure we have a formatted timestamp for __now__. */ |
/* Make sure we have a formatted timestamp for __now__. */ |
time(&now); |
time(&now); |
if ((tp = gmtime(&now)) == NULL) { |
if ((tp = gmtime(&now)) == NULL) { |
warning(_("unable to get GMT time")); | warning(U_("unable to get GMT time")); |
goto done; |
goto done; |
} |
} |
|
|
/* Format the timestamp according to the RFC. */ |
/* Format the timestamp according to the RFC. */ |
if (strftime(timebuffer, sizeof(timebuffer), "%Y%m%d%H%M%S.0Z", tp) == 0) { |
if (strftime(timebuffer, sizeof(timebuffer), "%Y%m%d%H%M%S.0Z", tp) == 0) { |
warningx(_("unable to format timestamp")); | warningx(U_("unable to format timestamp")); |
goto done; |
goto done; |
} |
} |
|
|
/* Build filter. */ |
/* Build filter. */ |
bytes = snprintf(buffer, buffersize, "(&(|(!(sudoNotAfter=*))(sudoNotAfter>=%s))(|(!(sudoNotBefore=*))(sudoNotBefore<=%s)))", |
bytes = snprintf(buffer, buffersize, "(&(|(!(sudoNotAfter=*))(sudoNotAfter>=%s))(|(!(sudoNotBefore=*))(sudoNotBefore<=%s)))", |
timebuffer, timebuffer); |
timebuffer, timebuffer); |
if (bytes < 0 || bytes >= buffersize) { | if (bytes <= 0 || (size_t)bytes >= buffersize) { |
warning(_("unable to build time filter")); | warning(U_("unable to build time filter")); |
bytes = 0; |
bytes = 0; |
} |
} |
|
|
Line 1311 sudo_ldap_build_pass1(struct passwd *pw)
|
Line 1319 sudo_ldap_build_pass1(struct passwd *pw)
|
|
|
/* Add ALL to list and end the global OR */ |
/* Add ALL to list and end the global OR */ |
if (strlcat(buf, "(sudoUser=ALL)", sz) >= sz) |
if (strlcat(buf, "(sudoUser=ALL)", sz) >= sz) |
fatalx(_("sudo_ldap_build_pass1 allocation mismatch")); | fatalx(U_("sudo_ldap_build_pass1 allocation mismatch")); |
|
|
/* Add the time restriction, or simply end the global OR. */ |
/* Add the time restriction, or simply end the global OR. */ |
if (ldap_conf.timed) { |
if (ldap_conf.timed) { |
Line 1336 sudo_ldap_build_pass2(void)
|
Line 1344 sudo_ldap_build_pass2(void)
|
char *filt, timebuffer[TIMEFILTER_LENGTH + 1]; |
char *filt, timebuffer[TIMEFILTER_LENGTH + 1]; |
debug_decl(sudo_ldap_build_pass2, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_build_pass2, SUDO_DEBUG_LDAP) |
|
|
|
/* Short circuit if no non-Unix group support. */ |
|
if (!def_use_netgroups && !def_group_plugin) { |
|
debug_return_str(NULL); |
|
} |
|
|
if (ldap_conf.timed) |
if (ldap_conf.timed) |
sudo_ldap_timefilter(timebuffer, sizeof(timebuffer)); |
sudo_ldap_timefilter(timebuffer, sizeof(timebuffer)); |
|
|
Line 1345 sudo_ldap_build_pass2(void)
|
Line 1358 sudo_ldap_build_pass2(void)
|
* those get ANDed in to the expression. |
* those get ANDed in to the expression. |
*/ |
*/ |
if (def_group_plugin) { |
if (def_group_plugin) { |
easprintf(&filt, "%s%s(|(sudoUser=+*)(sudoUser=%%:*))%s%s", | easprintf(&filt, "%s%s(|(sudoUser=%s*)(sudoUser=%%:*))%s%s", |
(ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "", |
(ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "", |
ldap_conf.search_filter ? ldap_conf.search_filter : "", |
ldap_conf.search_filter ? ldap_conf.search_filter : "", |
|
def_use_netgroups ? "+" : "", |
ldap_conf.timed ? timebuffer : "", |
ldap_conf.timed ? timebuffer : "", |
(ldap_conf.timed || ldap_conf.search_filter) ? ")" : ""); |
(ldap_conf.timed || ldap_conf.search_filter) ? ")" : ""); |
} else { |
} else { |
easprintf(&filt, "%s%s(sudoUser=+*)%s%s", | easprintf(&filt, "%s%s(sudoUser=*)(sudoUser=+*)%s%s", |
(ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "", |
(ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "", |
ldap_conf.search_filter ? ldap_conf.search_filter : "", |
ldap_conf.search_filter ? ldap_conf.search_filter : "", |
ldap_conf.timed ? timebuffer : "", |
ldap_conf.timed ? timebuffer : "", |
Line 1393 sudo_ldap_parse_keyword(const char *keyword, const cha
|
Line 1407 sudo_ldap_parse_keyword(const char *keyword, const cha
|
struct ldap_config_table *table) |
struct ldap_config_table *table) |
{ |
{ |
struct ldap_config_table *cur; |
struct ldap_config_table *cur; |
|
const char *errstr; |
debug_decl(sudo_ldap_parse_keyword, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_parse_keyword, SUDO_DEBUG_LDAP) |
|
|
/* Look up keyword in config tables */ |
/* Look up keyword in config tables */ |
Line 1413 sudo_ldap_parse_keyword(const char *keyword, const cha
|
Line 1428 sudo_ldap_parse_keyword(const char *keyword, const cha
|
*(int *)(cur->valp) = atobool(value) == true; |
*(int *)(cur->valp) = atobool(value) == true; |
break; |
break; |
case CONF_INT: |
case CONF_INT: |
*(int *)(cur->valp) = atoi(value); | *(int *)(cur->valp) = strtonum(value, INT_MIN, INT_MAX, &errstr); |
| if (errstr != NULL) { |
| warningx(U_("%s: %s: %s: %s"), |
| path_ldap_conf, keyword, value, U_(errstr)); |
| } |
break; |
break; |
case CONF_STR: |
case CONF_STR: |
efree(*(char **)(cur->valp)); |
efree(*(char **)(cur->valp)); |
*(char **)(cur->valp) = estrdup(value); | *(char **)(cur->valp) = *value ? estrdup(value) : NULL; |
break; |
break; |
case CONF_LIST_STR: |
case CONF_LIST_STR: |
{ |
{ |
struct ldap_config_list_str **p; | struct ldap_config_str_list *head; |
| struct ldap_config_str *str; |
size_t len = strlen(value); |
size_t len = strlen(value); |
|
|
if (len > 0) { |
if (len > 0) { |
p = (struct ldap_config_list_str **)cur->valp; | head = (struct ldap_config_str_list *)cur->valp; |
while (*p != NULL) | str = emalloc(sizeof(*str) + len); |
p = &(*p)->next; | memcpy(str->val, value, len + 1); |
*p = emalloc(sizeof(struct ldap_config_list_str) + len); | STAILQ_INSERT_TAIL(head, str, entries); |
memcpy((*p)->val, value, len + 1); | |
(*p)->next = NULL; | |
} |
} |
} |
} |
break; |
break; |
Line 1465 sudo_krb5_ccname_path(const char *old_ccname)
|
Line 1483 sudo_krb5_ccname_path(const char *old_ccname)
|
"ccache %s -> %s", old_ccname, ccname); |
"ccache %s -> %s", old_ccname, ccname); |
|
|
/* Credential cache must be a fully-qualified path name. */ |
/* Credential cache must be a fully-qualified path name. */ |
debug_return_str(*ccname == '/' ? ccname : NULL); | debug_return_const_str(*ccname == '/' ? ccname : NULL); |
} |
} |
|
|
static bool |
static bool |
Line 1514 sudo_ldap_read_config(void)
|
Line 1532 sudo_ldap_read_config(void)
|
ldap_conf.use_sasl = -1; |
ldap_conf.use_sasl = -1; |
ldap_conf.rootuse_sasl = -1; |
ldap_conf.rootuse_sasl = -1; |
ldap_conf.deref = -1; |
ldap_conf.deref = -1; |
|
ldap_conf.search_filter = estrdup(DEFAULT_SEARCH_FILTER); |
|
STAILQ_INIT(&ldap_conf.uri); |
|
STAILQ_INIT(&ldap_conf.base); |
|
|
if ((fp = fopen(path_ldap_conf, "r")) == NULL) |
if ((fp = fopen(path_ldap_conf, "r")) == NULL) |
debug_return_bool(false); |
debug_return_bool(false); |
Line 1546 sudo_ldap_read_config(void)
|
Line 1567 sudo_ldap_read_config(void)
|
|
|
DPRINTF1("LDAP Config Summary"); |
DPRINTF1("LDAP Config Summary"); |
DPRINTF1("==================="); |
DPRINTF1("==================="); |
if (ldap_conf.uri) { | if (!STAILQ_EMPTY(&ldap_conf.uri)) { |
struct ldap_config_list_str *uri = ldap_conf.uri; | struct ldap_config_str *uri; |
|
|
do { | STAILQ_FOREACH(uri, &ldap_conf.uri, entries) { |
DPRINTF1("uri %s", uri->val); |
DPRINTF1("uri %s", uri->val); |
} while ((uri = uri->next) != NULL); | } |
} else { |
} else { |
DPRINTF1("host %s", |
DPRINTF1("host %s", |
ldap_conf.host ? ldap_conf.host : "(NONE)"); |
ldap_conf.host ? ldap_conf.host : "(NONE)"); |
Line 1559 sudo_ldap_read_config(void)
|
Line 1580 sudo_ldap_read_config(void)
|
} |
} |
DPRINTF1("ldap_version %d", ldap_conf.version); |
DPRINTF1("ldap_version %d", ldap_conf.version); |
|
|
if (ldap_conf.base) { | if (!STAILQ_EMPTY(&ldap_conf.base)) { |
struct ldap_config_list_str *base = ldap_conf.base; | struct ldap_config_str *base; |
do { | STAILQ_FOREACH(base, &ldap_conf.base, entries) { |
DPRINTF1("sudoers_base %s", base->val); |
DPRINTF1("sudoers_base %s", base->val); |
} while ((base = base->next) != NULL); | } |
} else { |
} else { |
DPRINTF1("sudoers_base %s", "(NONE: LDAP disabled)"); |
DPRINTF1("sudoers_base %s", "(NONE: LDAP disabled)"); |
} |
} |
Line 1623 sudo_ldap_read_config(void)
|
Line 1644 sudo_ldap_read_config(void)
|
#endif |
#endif |
DPRINTF1("==================="); |
DPRINTF1("==================="); |
|
|
if (!ldap_conf.base) | if (STAILQ_EMPTY(&ldap_conf.base)) |
debug_return_bool(false); /* if no base is defined, ignore LDAP */ |
debug_return_bool(false); /* if no base is defined, ignore LDAP */ |
|
|
if (ldap_conf.bind_timelimit > 0) |
if (ldap_conf.bind_timelimit > 0) |
Line 1648 sudo_ldap_read_config(void)
|
Line 1669 sudo_ldap_read_config(void)
|
|
|
#ifndef HAVE_LDAP_INITIALIZE |
#ifndef HAVE_LDAP_INITIALIZE |
/* Convert uri list to host list if no ldap_initialize(). */ |
/* Convert uri list to host list if no ldap_initialize(). */ |
if (ldap_conf.uri) { | if (!STAILQ_EMPTY(&ldap_conf.uri)) { |
struct ldap_config_list_str *uri = ldap_conf.uri; | struct ldap_config_str *uri; |
if (sudo_ldap_parse_uri(uri) != 0) | |
| if (sudo_ldap_parse_uri(&ldap_conf.uri) != LDAP_SUCCESS) |
debug_return_bool(false); |
debug_return_bool(false); |
do { | while ((uri = STAILQ_FIRST(&ldap_conf.uri)) != NULL) { |
ldap_conf.uri = uri->next; | STAILQ_REMOVE_HEAD(&ldap_conf.uri, entries); |
efree(uri); |
efree(uri); |
} while ((uri = ldap_conf.uri)); | } |
ldap_conf.port = LDAP_PORT; |
ldap_conf.port = LDAP_PORT; |
} |
} |
#endif |
#endif |
|
|
if (!ldap_conf.uri) { | if (STAILQ_EMPTY(&ldap_conf.uri)) { |
/* Use port 389 for plaintext LDAP and port 636 for SSL LDAP */ |
/* Use port 389 for plaintext LDAP and port 636 for SSL LDAP */ |
if (ldap_conf.port < 0) |
if (ldap_conf.port < 0) |
ldap_conf.port = |
ldap_conf.port = |
Line 1745 sudo_ldap_display_defaults(struct sudo_nss *nss, struc
|
Line 1767 sudo_ldap_display_defaults(struct sudo_nss *nss, struc
|
{ |
{ |
struct berval **bv, **p; |
struct berval **bv, **p; |
struct timeval tv, *tvp = NULL; |
struct timeval tv, *tvp = NULL; |
struct ldap_config_list_str *base; | struct ldap_config_str *base; |
struct sudo_ldap_handle *handle = nss->handle; |
struct sudo_ldap_handle *handle = nss->handle; |
LDAP *ld; |
LDAP *ld; |
LDAPMessage *entry, *result; |
LDAPMessage *entry, *result; |
Line 1758 sudo_ldap_display_defaults(struct sudo_nss *nss, struc
|
Line 1780 sudo_ldap_display_defaults(struct sudo_nss *nss, struc
|
ld = handle->ld; |
ld = handle->ld; |
|
|
filt = sudo_ldap_build_default_filter(); |
filt = sudo_ldap_build_default_filter(); |
for (base = ldap_conf.base; base != NULL; base = base->next) { | STAILQ_FOREACH(base, &ldap_conf.base, entries) { |
if (ldap_conf.timeout > 0) { |
if (ldap_conf.timeout > 0) { |
tv.tv_sec = ldap_conf.timeout; |
tv.tv_sec = ldap_conf.timeout; |
tv.tv_usec = 0; |
tv.tv_usec = 0; |
Line 2035 sudo_set_krb5_ccache_name(const char *name, const char
|
Line 2057 sudo_set_krb5_ccache_name(const char *name, const char
|
debug_decl(sudo_set_krb5_ccache_name, SUDO_DEBUG_LDAP) |
debug_decl(sudo_set_krb5_ccache_name, SUDO_DEBUG_LDAP) |
|
|
if (!initialized) { |
if (!initialized) { |
sudo_gss_krb5_ccache_name = dlsym(RTLD_DEFAULT, "gss_krb5_ccache_name"); | sudo_gss_krb5_ccache_name = |
| sudo_dso_findsym(SUDO_DSO_DEFAULT, "gss_krb5_ccache_name"); |
initialized = true; |
initialized = true; |
} |
} |
|
|
Line 2163 sudo_ldap_sasl_interact(LDAP *ld, unsigned int flags,
|
Line 2186 sudo_ldap_sasl_interact(LDAP *ld, unsigned int flags,
|
|
|
/* |
/* |
* Set LDAP options from the specified options table |
* Set LDAP options from the specified options table |
|
* Returns LDAP_SUCCESS on success, else non-zero. |
*/ |
*/ |
static int |
static int |
sudo_ldap_set_options_table(LDAP *ld, struct ldap_config_table *table) |
sudo_ldap_set_options_table(LDAP *ld, struct ldap_config_table *table) |
Line 2204 sudo_ldap_set_options_table(LDAP *ld, struct ldap_conf
|
Line 2228 sudo_ldap_set_options_table(LDAP *ld, struct ldap_conf
|
break; |
break; |
} |
} |
} |
} |
debug_return_int(errors ? -1 : 0); | debug_return_int(errors ? -1 : LDAP_SUCCESS); |
} |
} |
|
|
/* |
/* |
* Set LDAP options based on the global config table. |
* Set LDAP options based on the global config table. |
|
* Returns LDAP_SUCCESS on success, else non-zero. |
*/ |
*/ |
static int |
static int |
sudo_ldap_set_options_global(void) |
sudo_ldap_set_options_global(void) |
Line 2224 sudo_ldap_set_options_global(void)
|
Line 2249 sudo_ldap_set_options_global(void)
|
|
|
/* Parse global LDAP options table. */ |
/* Parse global LDAP options table. */ |
rc = sudo_ldap_set_options_table(NULL, ldap_conf_global); |
rc = sudo_ldap_set_options_table(NULL, ldap_conf_global); |
if (rc == -1) | debug_return_int(rc); |
debug_return_int(-1); | |
debug_return_int(0); | |
} |
} |
|
|
/* |
/* |
* Set LDAP options based on the per-connection config table. |
* Set LDAP options based on the per-connection config table. |
|
* Returns LDAP_SUCCESS on success, else non-zero. |
*/ |
*/ |
static int |
static int |
sudo_ldap_set_options_conn(LDAP *ld) |
sudo_ldap_set_options_conn(LDAP *ld) |
Line 2288 sudo_ldap_set_options_conn(LDAP *ld)
|
Line 2312 sudo_ldap_set_options_conn(LDAP *ld)
|
} |
} |
} |
} |
#endif |
#endif |
debug_return_int(0); | debug_return_int(LDAP_SUCCESS); |
} |
} |
|
|
/* |
/* |
Line 2300 sudo_ldap_result_alloc(void)
|
Line 2324 sudo_ldap_result_alloc(void)
|
struct ldap_result *result; |
struct ldap_result *result; |
debug_decl(sudo_ldap_result_alloc, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_result_alloc, SUDO_DEBUG_LDAP) |
|
|
debug_return_ptr(ecalloc(1, sizeof(*result))); | result = ecalloc(1, sizeof(*result)); |
| STAILQ_INIT(&result->searches); |
| |
| debug_return_ptr(result); |
} |
} |
|
|
/* |
/* |
Line 2309 sudo_ldap_result_alloc(void)
|
Line 2336 sudo_ldap_result_alloc(void)
|
static void |
static void |
sudo_ldap_result_free(struct ldap_result *lres) |
sudo_ldap_result_free(struct ldap_result *lres) |
{ |
{ |
struct ldap_search_list *s; | struct ldap_search_result *s; |
debug_decl(sudo_ldap_result_free, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_result_free, SUDO_DEBUG_LDAP) |
|
|
if (lres != NULL) { |
if (lres != NULL) { |
Line 2317 sudo_ldap_result_free(struct ldap_result *lres)
|
Line 2344 sudo_ldap_result_free(struct ldap_result *lres)
|
efree(lres->entries); |
efree(lres->entries); |
lres->entries = NULL; |
lres->entries = NULL; |
} |
} |
if (lres->searches) { | while ((s = STAILQ_FIRST(&lres->searches)) != NULL) { |
while ((s = lres->searches) != NULL) { | STAILQ_REMOVE_HEAD(&lres->searches, entries); |
ldap_msgfree(s->searchresult); | ldap_msgfree(s->searchresult); |
lres->searches = s->next; | efree(s); |
efree(s); | |
} | |
} |
} |
efree(lres); |
efree(lres); |
} |
} |
Line 2332 sudo_ldap_result_free(struct ldap_result *lres)
|
Line 2357 sudo_ldap_result_free(struct ldap_result *lres)
|
/* |
/* |
* Add a search result to the ldap_result structure. |
* Add a search result to the ldap_result structure. |
*/ |
*/ |
static struct ldap_search_list * | static struct ldap_search_result * |
sudo_ldap_result_add_search(struct ldap_result *lres, LDAP *ldap, |
sudo_ldap_result_add_search(struct ldap_result *lres, LDAP *ldap, |
LDAPMessage *searchresult) |
LDAPMessage *searchresult) |
{ |
{ |
struct ldap_search_list *s, *news; | struct ldap_search_result *news; |
debug_decl(sudo_ldap_result_add_search, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_result_add_search, SUDO_DEBUG_LDAP) |
|
|
news = ecalloc(1, sizeof(struct ldap_search_list)); | /* Create new entry and add it to the end of the chain. */ |
| news = ecalloc(1, sizeof(*news)); |
news->ldap = ldap; |
news->ldap = ldap; |
news->searchresult = searchresult; |
news->searchresult = searchresult; |
/* news->next = NULL; */ | STAILQ_INSERT_TAIL(&lres->searches, news, entries); |
|
|
/* Add entry to the end of the chain (XXX - tailq instead?). */ |
|
if (lres->searches) { |
|
for (s = lres->searches; s->next != NULL; s = s->next) |
|
continue; |
|
s->next = news; |
|
} else { |
|
lres->searches = news; |
|
} |
|
debug_return_ptr(news); |
debug_return_ptr(news); |
} |
} |
|
|
/* |
/* |
* Connect to the LDAP server specified by ld | * Connect to the LDAP server specified by ld. |
| * Returns LDAP_SUCCESS on success, else non-zero. |
*/ |
*/ |
static int |
static int |
sudo_ldap_bind_s(LDAP *ld) |
sudo_ldap_bind_s(LDAP *ld) |
Line 2411 sudo_ldap_bind_s(LDAP *ld)
|
Line 2430 sudo_ldap_bind_s(LDAP *ld)
|
if (rc != LDAP_SUCCESS) { |
if (rc != LDAP_SUCCESS) { |
warningx("ldap_sasl_interactive_bind_s(): %s", |
warningx("ldap_sasl_interactive_bind_s(): %s", |
ldap_err2string(rc)); |
ldap_err2string(rc)); |
debug_return_int(-1); | goto done; |
} |
} |
DPRINTF1("ldap_sasl_interactive_bind_s() ok"); |
DPRINTF1("ldap_sasl_interactive_bind_s() ok"); |
} else |
} else |
Line 2427 sudo_ldap_bind_s(LDAP *ld)
|
Line 2446 sudo_ldap_bind_s(LDAP *ld)
|
NULL, NULL, NULL); |
NULL, NULL, NULL); |
if (rc != LDAP_SUCCESS) { |
if (rc != LDAP_SUCCESS) { |
warningx("ldap_sasl_bind_s(): %s", ldap_err2string(rc)); |
warningx("ldap_sasl_bind_s(): %s", ldap_err2string(rc)); |
debug_return_int(-1); | goto done; |
} |
} |
DPRINTF1("ldap_sasl_bind_s() ok"); |
DPRINTF1("ldap_sasl_bind_s() ok"); |
} |
} |
Line 2436 sudo_ldap_bind_s(LDAP *ld)
|
Line 2455 sudo_ldap_bind_s(LDAP *ld)
|
rc = ldap_simple_bind_s(ld, ldap_conf.binddn, ldap_conf.bindpw); |
rc = ldap_simple_bind_s(ld, ldap_conf.binddn, ldap_conf.bindpw); |
if (rc != LDAP_SUCCESS) { |
if (rc != LDAP_SUCCESS) { |
warningx("ldap_simple_bind_s(): %s", ldap_err2string(rc)); |
warningx("ldap_simple_bind_s(): %s", ldap_err2string(rc)); |
debug_return_int(-1); | goto done; |
} |
} |
DPRINTF1("ldap_simple_bind_s() ok"); |
DPRINTF1("ldap_simple_bind_s() ok"); |
} |
} |
#endif |
#endif |
debug_return_int(0); | done: |
| debug_return_int(rc); |
} |
} |
|
|
/* |
/* |
Line 2452 static int
|
Line 2472 static int
|
sudo_ldap_open(struct sudo_nss *nss) |
sudo_ldap_open(struct sudo_nss *nss) |
{ |
{ |
LDAP *ld; |
LDAP *ld; |
int rc; | int rc = -1; |
| sigaction_t sa, saved_sa_pipe; |
bool ldapnoinit = false; |
bool ldapnoinit = false; |
struct sudo_ldap_handle *handle; |
struct sudo_ldap_handle *handle; |
debug_decl(sudo_ldap_open, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_open, SUDO_DEBUG_LDAP) |
|
|
|
/* Ignore SIGPIPE if we cannot bind to the server. */ |
|
memset(&sa, 0, sizeof(sa)); |
|
sigemptyset(&sa.sa_mask); |
|
sa.sa_handler = SIG_IGN; |
|
(void) sigaction(SIGPIPE, &sa, &saved_sa_pipe); |
|
|
if (!sudo_ldap_read_config()) |
if (!sudo_ldap_read_config()) |
debug_return_int(-1); | goto done; |
|
|
/* Prevent reading of user ldaprc and system defaults. */ |
/* Prevent reading of user ldaprc and system defaults. */ |
if (sudo_getenv("LDAPNOINIT") == NULL) { |
if (sudo_getenv("LDAPNOINIT") == NULL) { |
Line 2467 sudo_ldap_open(struct sudo_nss *nss)
|
Line 2494 sudo_ldap_open(struct sudo_nss *nss)
|
} |
} |
|
|
/* Set global LDAP options */ |
/* Set global LDAP options */ |
if (sudo_ldap_set_options_global() < 0) | if (sudo_ldap_set_options_global() != LDAP_SUCCESS) |
debug_return_int(-1); | goto done; |
|
|
/* Connect to LDAP server */ |
/* Connect to LDAP server */ |
#ifdef HAVE_LDAP_INITIALIZE |
#ifdef HAVE_LDAP_INITIALIZE |
if (ldap_conf.uri != NULL) { | if (!STAILQ_EMPTY(&ldap_conf.uri)) { |
char *buf = sudo_ldap_join_uri(ldap_conf.uri); | char *buf = sudo_ldap_join_uri(&ldap_conf.uri); |
DPRINTF2("ldap_initialize(ld, %s)", buf); | if (buf != NULL) { |
rc = ldap_initialize(&ld, buf); | DPRINTF2("ldap_initialize(ld, %s)", buf); |
efree(buf); | rc = ldap_initialize(&ld, buf); |
if (rc != LDAP_SUCCESS) | efree(buf); |
warningx(_("unable to initialize LDAP: %s"), ldap_err2string(rc)); | if (rc != LDAP_SUCCESS) { |
| warningx(U_("unable to initialize LDAP: %s"), |
| ldap_err2string(rc)); |
| } |
| } |
} else |
} else |
#endif |
#endif |
rc = sudo_ldap_init(&ld, ldap_conf.host, ldap_conf.port); |
rc = sudo_ldap_init(&ld, ldap_conf.host, ldap_conf.port); |
if (rc != LDAP_SUCCESS) |
if (rc != LDAP_SUCCESS) |
debug_return_int(-1); | goto done; |
|
|
/* Set LDAP per-connection options */ |
/* Set LDAP per-connection options */ |
if (sudo_ldap_set_options_conn(ld) < 0) | rc = sudo_ldap_set_options_conn(ld); |
debug_return_int(-1); | if (rc != LDAP_SUCCESS) |
| goto done; |
|
|
if (ldapnoinit) |
if (ldapnoinit) |
sudo_unsetenv("LDAPNOINIT"); |
sudo_unsetenv("LDAPNOINIT"); |
Line 2497 sudo_ldap_open(struct sudo_nss *nss)
|
Line 2529 sudo_ldap_open(struct sudo_nss *nss)
|
rc = ldap_start_tls_s(ld, NULL, NULL); |
rc = ldap_start_tls_s(ld, NULL, NULL); |
if (rc != LDAP_SUCCESS) { |
if (rc != LDAP_SUCCESS) { |
warningx("ldap_start_tls_s(): %s", ldap_err2string(rc)); |
warningx("ldap_start_tls_s(): %s", ldap_err2string(rc)); |
debug_return_int(-1); | goto done; |
} |
} |
DPRINTF1("ldap_start_tls_s() ok"); |
DPRINTF1("ldap_start_tls_s() ok"); |
#elif defined(HAVE_LDAP_SSL_CLIENT_INIT) && defined(HAVE_LDAP_START_TLS_S_NP) |
#elif defined(HAVE_LDAP_SSL_CLIENT_INIT) && defined(HAVE_LDAP_START_TLS_S_NP) |
Line 2507 sudo_ldap_open(struct sudo_nss *nss)
|
Line 2539 sudo_ldap_open(struct sudo_nss *nss)
|
if (rc != LDAP_SUCCESS) { |
if (rc != LDAP_SUCCESS) { |
warningx("ldap_ssl_client_init(): %s (SSL reason code %d)", |
warningx("ldap_ssl_client_init(): %s (SSL reason code %d)", |
ldap_err2string(rc), sslrc); |
ldap_err2string(rc), sslrc); |
debug_return_int(-1); | goto done; |
} |
} |
rc = ldap_start_tls_s_np(ld, NULL); |
rc = ldap_start_tls_s_np(ld, NULL); |
if (rc != LDAP_SUCCESS) { |
if (rc != LDAP_SUCCESS) { |
warningx("ldap_start_tls_s_np(): %s", ldap_err2string(rc)); |
warningx("ldap_start_tls_s_np(): %s", ldap_err2string(rc)); |
debug_return_int(-1); | goto done; |
} |
} |
DPRINTF1("ldap_start_tls_s_np() ok"); |
DPRINTF1("ldap_start_tls_s_np() ok"); |
#else |
#else |
warningx(_("start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()")); | warningx(U_("start_tls specified but LDAP libs do not support ldap_start_tls_s() or ldap_start_tls_s_np()")); |
#endif /* !HAVE_LDAP_START_TLS_S && !HAVE_LDAP_START_TLS_S_NP */ |
#endif /* !HAVE_LDAP_START_TLS_S && !HAVE_LDAP_START_TLS_S_NP */ |
} |
} |
|
|
/* Actually connect */ |
/* Actually connect */ |
if (sudo_ldap_bind_s(ld) != 0) | rc = sudo_ldap_bind_s(ld); |
debug_return_int(-1); | if (rc != LDAP_SUCCESS) |
| goto done; |
|
|
/* Create a handle container. */ |
/* Create a handle container. */ |
handle = ecalloc(1, sizeof(struct sudo_ldap_handle)); |
handle = ecalloc(1, sizeof(struct sudo_ldap_handle)); |
Line 2532 sudo_ldap_open(struct sudo_nss *nss)
|
Line 2565 sudo_ldap_open(struct sudo_nss *nss)
|
/* handle->grlist = NULL; */ |
/* handle->grlist = NULL; */ |
nss->handle = handle; |
nss->handle = handle; |
|
|
debug_return_int(0); | done: |
| (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL); |
| debug_return_int(rc == LDAP_SUCCESS ? 0 : -1); |
} |
} |
|
|
static int |
static int |
sudo_ldap_setdefs(struct sudo_nss *nss) |
sudo_ldap_setdefs(struct sudo_nss *nss) |
{ |
{ |
struct ldap_config_list_str *base; | struct ldap_config_str *base; |
struct sudo_ldap_handle *handle = nss->handle; |
struct sudo_ldap_handle *handle = nss->handle; |
struct timeval tv, *tvp = NULL; |
struct timeval tv, *tvp = NULL; |
LDAP *ld; |
LDAP *ld; |
Line 2554 sudo_ldap_setdefs(struct sudo_nss *nss)
|
Line 2589 sudo_ldap_setdefs(struct sudo_nss *nss)
|
filt = sudo_ldap_build_default_filter(); |
filt = sudo_ldap_build_default_filter(); |
DPRINTF1("Looking for cn=defaults: %s", filt); |
DPRINTF1("Looking for cn=defaults: %s", filt); |
|
|
for (base = ldap_conf.base; base != NULL; base = base->next) { | STAILQ_FOREACH(base, &ldap_conf.base, entries) { |
if (ldap_conf.timeout > 0) { |
if (ldap_conf.timeout > 0) { |
tv.tv_sec = ldap_conf.timeout; |
tv.tv_sec = ldap_conf.timeout; |
tv.tv_usec = 0; |
tv.tv_usec = 0; |
Line 2714 ldap_entry_compare(const void *a, const void *b)
|
Line 2749 ldap_entry_compare(const void *a, const void *b)
|
} |
} |
|
|
/* |
/* |
* Find the last entry in the list of searches, usually the | * Return the last entry in the list of searches, usually the |
* one currently being used to add entries. |
* one currently being used to add entries. |
* XXX - use a tailq instead? |
|
*/ |
*/ |
static struct ldap_search_list * | static struct ldap_search_result * |
sudo_ldap_result_last_search(struct ldap_result *lres) |
sudo_ldap_result_last_search(struct ldap_result *lres) |
{ |
{ |
struct ldap_search_list *result = lres->searches; |
|
debug_decl(sudo_ldap_result_last_search, SUDO_DEBUG_LDAP) |
debug_decl(sudo_ldap_result_last_search, SUDO_DEBUG_LDAP) |
|
|
if (result) { | debug_return_ptr(STAILQ_LAST(&lres->searches, ldap_search_result, entries)); |
while (result->next) | |
result = result->next; | |
} | |
debug_return_ptr(result); | |
} |
} |
|
|
/* |
/* |
Line 2737 sudo_ldap_result_last_search(struct ldap_result *lres)
|
Line 2766 sudo_ldap_result_last_search(struct ldap_result *lres)
|
static struct ldap_entry_wrapper * |
static struct ldap_entry_wrapper * |
sudo_ldap_result_add_entry(struct ldap_result *lres, LDAPMessage *entry) |
sudo_ldap_result_add_entry(struct ldap_result *lres, LDAPMessage *entry) |
{ |
{ |
struct ldap_search_list *last; | struct ldap_search_result *last; |
struct berval **bv; |
struct berval **bv; |
double order = 0.0; |
double order = 0.0; |
char *ep; |
char *ep; |
Line 2752 sudo_ldap_result_add_entry(struct ldap_result *lres, L
|
Line 2781 sudo_ldap_result_add_entry(struct ldap_result *lres, L
|
DPRINTF2("order attribute raw: %s", (*bv)->bv_val); |
DPRINTF2("order attribute raw: %s", (*bv)->bv_val); |
order = strtod((*bv)->bv_val, &ep); |
order = strtod((*bv)->bv_val, &ep); |
if (ep == (*bv)->bv_val || *ep != '\0') { |
if (ep == (*bv)->bv_val || *ep != '\0') { |
warningx(_("invalid sudoOrder attribute: %s"), (*bv)->bv_val); | warningx(U_("invalid sudoOrder attribute: %s"), (*bv)->bv_val); |
order = 0.0; |
order = 0.0; |
} |
} |
DPRINTF2("order attribute: %f", order); |
DPRINTF2("order attribute: %f", order); |
Line 2807 static struct ldap_result *
|
Line 2836 static struct ldap_result *
|
sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw) |
sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw) |
{ |
{ |
struct sudo_ldap_handle *handle = nss->handle; |
struct sudo_ldap_handle *handle = nss->handle; |
struct ldap_config_list_str *base; | struct ldap_config_str *base; |
struct ldap_result *lres; |
struct ldap_result *lres; |
struct timeval tv, *tvp = NULL; |
struct timeval tv, *tvp = NULL; |
LDAPMessage *entry, *result; |
LDAPMessage *entry, *result; |
Line 2854 sudo_ldap_result_get(struct sudo_nss *nss, struct pass
|
Line 2883 sudo_ldap_result_get(struct sudo_nss *nss, struct pass
|
lres = sudo_ldap_result_alloc(); |
lres = sudo_ldap_result_alloc(); |
for (pass = 0; pass < 2; pass++) { |
for (pass = 0; pass < 2; pass++) { |
filt = pass ? sudo_ldap_build_pass2() : sudo_ldap_build_pass1(pw); |
filt = pass ? sudo_ldap_build_pass2() : sudo_ldap_build_pass1(pw); |
DPRINTF1("ldap search '%s'", filt); | if (filt != NULL) { |
for (base = ldap_conf.base; base != NULL; base = base->next) { | DPRINTF1("ldap search '%s'", filt); |
DPRINTF1("searching from base '%s'", | STAILQ_FOREACH(base, &ldap_conf.base, entries) { |
base->val); | DPRINTF1("searching from base '%s'", |
if (ldap_conf.timeout > 0) { | base->val); |
tv.tv_sec = ldap_conf.timeout; | if (ldap_conf.timeout > 0) { |
tv.tv_usec = 0; | tv.tv_sec = ldap_conf.timeout; |
tvp = &tv; | tv.tv_usec = 0; |
} | tvp = &tv; |
result = NULL; | } |
rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt, | result = NULL; |
NULL, 0, NULL, NULL, tvp, 0, &result); | rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt, |
if (rc != LDAP_SUCCESS) { | NULL, 0, NULL, NULL, tvp, 0, &result); |
DPRINTF1("nothing found for '%s'", filt); | if (rc != LDAP_SUCCESS) { |
continue; | DPRINTF1("nothing found for '%s'", filt); |
} | continue; |
lres->user_matches = true; | } |
| lres->user_matches = true; |
|
|
/* Add the seach result to list of search results. */ | /* Add the seach result to list of search results. */ |
DPRINTF1("adding search result"); | DPRINTF1("adding search result"); |
sudo_ldap_result_add_search(lres, ld, result); | sudo_ldap_result_add_search(lres, ld, result); |
LDAP_FOREACH(entry, ld, result) { | LDAP_FOREACH(entry, ld, result) { |
if ((!pass || | if ((!pass || |
sudo_ldap_check_non_unix_group(ld, entry, pw)) && | sudo_ldap_check_non_unix_group(ld, entry, pw)) && |
sudo_ldap_check_host(ld, entry)) { | sudo_ldap_check_host(ld, entry)) { |
lres->host_matches = true; | lres->host_matches = true; |
sudo_ldap_result_add_entry(lres, entry); | sudo_ldap_result_add_entry(lres, entry); |
| } |
} |
} |
|
DPRINTF1("result now has %d entries", lres->nentries); |
} |
} |
DPRINTF1("result now has %d entries", lres->nentries); | efree(filt); |
} |
} |
efree(filt); |
|
} |
} |
|
|
/* Sort the entries by the sudoOrder attribute. */ |
/* Sort the entries by the sudoOrder attribute. */ |
Line 2958 sudo_ldap_result_from_search(LDAP *ldap, LDAPMessage *
|
Line 2989 sudo_ldap_result_from_search(LDAP *ldap, LDAPMessage *
|
* Build a new list node for the search result, this creates the |
* Build a new list node for the search result, this creates the |
* list node. |
* list node. |
*/ |
*/ |
struct ldap_search_list *last = sudo_ldap_result_add_search(result, | struct ldap_search_result *last = sudo_ldap_result_add_search(result, |
ldap, searchresult); |
ldap, searchresult); |
|
|
/* |
/* |