diff --git a/NEWS b/NEWS index 852948120..788385b9c 100644 --- a/NEWS +++ b/NEWS @@ -76,6 +76,8 @@ What's new in Sudo 1.7.5? * NETWORK_TIMEOUT is now an alias for BIND_TIMELIMIT in ldap.conf for compatibility with OpenLDAP configuration files. + * The LDAP API TIMEOUT parameter is now honored in ldap.conf. + What's new in Sudo 1.7.4p4? * A potential security issue has been fixed with respect to the handling diff --git a/config.h.in b/config.h.in index b9adebc62..d2ea6c43b 100644 --- a/config.h.in +++ b/config.h.in @@ -283,6 +283,9 @@ /* Define to 1 if you have the `ldap_search_ext_s' function. */ #undef HAVE_LDAP_SEARCH_EXT_S +/* Define to 1 if you have the `ldap_search_st' function. */ +#undef HAVE_LDAP_SEARCH_ST + /* Define to 1 if you have the `ldap_ssl_client_init' function. */ #undef HAVE_LDAP_SSL_CLIENT_INIT diff --git a/configure b/configure index 8254b6598..5e0b3a3e9 100755 --- a/configure +++ b/configure @@ -18194,7 +18194,7 @@ fi done - for ac_func in ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength ldap_search_ext_s ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s ldap_ssl_client_init ldap_start_tls_s_np + for ac_func in ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s ldap_ssl_client_init ldap_start_tls_s_np do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -18204,6 +18204,19 @@ eval as_val=\$$as_ac_var #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF +fi +done + + for ac_func in ldap_search_ext_s ldap_search_st +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + break fi done diff --git a/configure.in b/configure.in index 099a56182..ef3845945 100644 --- a/configure.in +++ b/configure.in @@ -2668,7 +2668,8 @@ if test ${with_ldap-'no'} != "no"; then AC_CHECK_HEADERS([sasl/sasl.h] [sasl.h], [AC_CHECK_FUNCS(ldap_sasl_interactive_bind_s)], [break]) AC_CHECK_HEADERS([ldap_ssl.h] [mps/ldap_ssl.h], [break], [], [#include ]) - AC_CHECK_FUNCS(ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength ldap_search_ext_s ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s ldap_ssl_client_init ldap_start_tls_s_np) + AC_CHECK_FUNCS(ldap_initialize ldap_start_tls_s ldapssl_init ldapssl_set_strength ldap_unbind_ext_s ldap_str2dn ldap_create ldap_sasl_bind_s ldap_ssl_client_init ldap_start_tls_s_np) + AC_CHECK_FUNCS(ldap_search_ext_s ldap_search_st, [break]) if test X"$check_gss_krb5_ccache_name" = X"yes"; then AC_CHECK_LIB(gssapi, gss_krb5_ccache_name, diff --git a/doc/sudoers.ldap.cat b/doc/sudoers.ldap.cat index 3ac69cea2..5ee611f0d 100644 --- a/doc/sudoers.ldap.cat +++ b/doc/sudoers.ldap.cat @@ -341,6 +341,10 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) The TTIIMMEELLIIMMIITT parameter specifies the amount of time, in seconds, to wait for a response to an LDAP query. + TTIIMMEEOOUUTT seconds + The TTIIMMEEOOUUTT parameter specifies the amount of time, in seconds, to + wait for a response from the various LDAP APIs. + SSUUDDOOEERRSS__BBAASSEE base The base DN to use when performing ssuuddoo LDAP queries. Typically this is of the form ou=SUDOers,dc=example,dc=com for the domain @@ -384,10 +388,6 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) SSSSLL on/true/yes/off/false/no If the SSSSLL parameter is set to on, true or yes, TLS (SSL) - encryption is always used when communicating with the LDAP server. - Typically, this involves connecting to the server on port 636 - (ldaps). - @@ -400,6 +400,10 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) + encryption is always used when communicating with the LDAP server. + Typically, this involves connecting to the server on port 636 + (ldaps). + SSSSLL start_tls If the SSSSLL parameter is set to start_tls, the LDAP server connection is initiated normally and TLS encryption is begun before @@ -451,10 +455,6 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) When using Netscape-derived libraries, this file may also contain Certificate Authority certificates. - TTLLSS__KKEEYY file name - The path to a file containing the private key which matches the - certificate specified by TTLLSS__CCEERRTT. The private key must not be - 1.8.0b3 January 10, 2011 7 @@ -466,6 +466,9 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) + TTLLSS__KKEEYY file name + The path to a file containing the private key which matches the + certificate specified by TTLLSS__CCEERRTT. The private key must not be password-protected. The key type depends on the LDAP libraries used. @@ -517,9 +520,6 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) Sudo looks for a line beginning with sudoers: and uses this to determine the search order. Note that ssuuddoo does not stop searching after the first match and later matches take precedence over earlier - ones. - - The following sources are recognized: @@ -532,6 +532,10 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) + ones. + + The following sources are recognized: + files read sudoers from F ldap read sudoers from LDAP @@ -583,10 +587,6 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) sudoers = files -FFIILLEESS - _/_e_t_c_/_l_d_a_p_._c_o_n_f LDAP configuration file - - 1.8.0b3 January 10, 2011 9 @@ -598,6 +598,9 @@ FFIILLEESS SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) +FFIILLEESS + _/_e_t_c_/_l_d_a_p_._c_o_n_f LDAP configuration file + _/_e_t_c_/_n_s_s_w_i_t_c_h_._c_o_n_f determines sudoers source order _/_e_t_c_/_n_e_t_s_v_c_._c_o_n_f determines sudoers source order on AIX @@ -649,9 +652,6 @@ EEXXAAMMPPLLEESS # Define if you want to use port 389 and switch to # encryption before the bind credentials are sent. # Only supported by LDAP servers that support the start_tls - # extension such as OpenLDAP. - #ssl start_tls - # @@ -664,6 +664,9 @@ EEXXAAMMPPLLEESS SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) + # extension such as OpenLDAP. + #ssl start_tls + # # Additional TLS options follow that allow tweaking of the # SSL/TLS connection. # @@ -715,9 +718,6 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) #tls_cert /var/ldap #tls_key /var/ldap # - # If using SASL authentication for LDAP (OpenSSL) - # use_sasl yes - # sasl_auth_id @@ -730,6 +730,9 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) + # If using SASL authentication for LDAP (OpenSSL) + # use_sasl yes + # sasl_auth_id # rootuse_sasl yes # rootsasl_auth_id # sasl_secprops none @@ -781,9 +784,6 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) attributetype ( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' - EQUALITY caseExactIA5Match - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) - @@ -796,6 +796,9 @@ SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + attributetype ( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' @@ -847,12 +850,75 @@ DDIISSCCLLAAIIMMEERR including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. See the LICENSE file distributed with ssuuddoo or - http://www.sudo.ws/sudo/license.html for complete details. - - 1.8.0b3 January 10, 2011 13 + + + +SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) + + + http://www.sudo.ws/sudo/license.html for complete details. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1.8.0b3 January 10, 2011 14 + + diff --git a/doc/sudoers.ldap.man.in b/doc/sudoers.ldap.man.in index 1c776e4b0..8971748f8 100644 --- a/doc/sudoers.ldap.man.in +++ b/doc/sudoers.ldap.man.in @@ -431,6 +431,10 @@ An alias for \fB\s-1BIND_TIMELIMIT\s0\fR. .IX Item "TIMELIMIT seconds" The \fB\s-1TIMELIMIT\s0\fR parameter specifies the amount of time, in seconds, to wait for a response to an \s-1LDAP\s0 query. +.IP "\fB\s-1TIMEOUT\s0\fR seconds" 4 +.IX Item "TIMEOUT seconds" +The \fB\s-1TIMEOUT\s0\fR parameter specifies the amount of time, in seconds, +to wait for a response from the various \s-1LDAP\s0 APIs. .IP "\fB\s-1SUDOERS_BASE\s0\fR base" 4 .IX Item "SUDOERS_BASE base" The base \s-1DN\s0 to use when performing \fBsudo\fR \s-1LDAP\s0 queries. Typically diff --git a/doc/sudoers.ldap.pod b/doc/sudoers.ldap.pod index 89409cb7b..b7918071c 100644 --- a/doc/sudoers.ldap.pod +++ b/doc/sudoers.ldap.pod @@ -335,6 +335,11 @@ An alias for B. The B parameter specifies the amount of time, in seconds, to wait for a response to an LDAP query. +=item B seconds + +The B parameter specifies the amount of time, in seconds, +to wait for a response from the various LDAP APIs. + =item B base The base DN to use when performing B LDAP queries. Typically diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index 85020fded..04a66eeff 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -97,8 +97,13 @@ #endif #ifndef HAVE_LDAP_SEARCH_EXT_S -#define ldap_search_ext_s(a, b, c, d, e, f, g, h, i, j, k) \ +# ifdef HAVE_LDAP_SEARCH_ST +# define ldap_search_ext_s(a, b, c, d, e, f, g, h, i, j, k) \ + ldap_search_st(a, b, c, d, e, f, i, k) +# else +# define ldap_search_ext_s(a, b, c, d, e, f, g, h, i, j, k) \ ldap_search_s(a, b, c, d, e, f, k) +# endif #endif #define LDAP_FOREACH(var, ld, res) \ @@ -184,6 +189,7 @@ static struct ldap_config { int ldap_debug; int tls_checkpeer; int timelimit; + int timeout; int bind_timelimit; int use_sasl; int rootuse_sasl; @@ -270,6 +276,10 @@ static struct ldap_config_table ldap_conf_table[] = { &ldap_conf.bind_timelimit }, #endif { "timelimit", CONF_INT, TRUE, LDAP_OPT_TIMELIMIT, &ldap_conf.timelimit }, +#ifdef LDAP_OPT_TIMEOUT + { "timeout", CONF_INT, TRUE, -1 /* needs timeval, set manually */, + &ldap_conf.timeout }, +#endif { "binddn", CONF_STR, FALSE, -1, &ldap_conf.binddn }, { "bindpw", CONF_STR, FALSE, -1, &ldap_conf.bindpw }, { "rootbinddn", CONF_STR, FALSE, -1, &ldap_conf.rootbinddn }, @@ -1075,6 +1085,7 @@ sudo_ldap_read_config(void) ldap_conf.port = -1; ldap_conf.tls_checkpeer = -1; ldap_conf.timelimit = -1; + ldap_conf.timeout = -1; ldap_conf.bind_timelimit = -1; ldap_conf.use_sasl = -1; ldap_conf.rootuse_sasl = -1; @@ -1137,9 +1148,6 @@ sudo_ldap_read_config(void) if (!ldap_conf.host) ldap_conf.host = estrdup("localhost"); - if (ldap_conf.bind_timelimit > 0) - ldap_conf.bind_timelimit *= 1000; /* convert to ms */ - if (ldap_conf.debug > 1) { sudo_printf(SUDO_CONV_ERROR_MSG, "LDAP Config Summary\n"); sudo_printf(SUDO_CONV_ERROR_MSG, "===================\n"); @@ -1232,6 +1240,9 @@ sudo_ldap_read_config(void) if (!ldap_conf.base) return(FALSE); /* if no base is defined, ignore LDAP */ + if (ldap_conf.bind_timelimit > 0) + ldap_conf.bind_timelimit *= 1000; /* convert to ms */ + /* * Interpret SSL option */ @@ -1344,6 +1355,7 @@ sudo_ldap_display_defaults(struct sudo_nss *nss, struct passwd *pw, struct lbuf *lbuf) { struct berval **bv, **p; + struct timeval tv, *tvp = NULL; struct ldap_config_list_str *base; struct sudo_ldap_handle *handle = nss->handle; LDAP *ld; @@ -1356,9 +1368,14 @@ sudo_ldap_display_defaults(struct sudo_nss *nss, struct passwd *pw, ld = handle->ld; for (base = ldap_conf.base; base != NULL; base = base->next) { + if (ldap_conf.timeout > 0) { + tv.tv_sec = ldap_conf.timeout; + tv.tv_usec = 0; + tvp = &tv; + } result = NULL; rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, - "cn=defaults", NULL, 0, NULL, NULL, NULL, 0, &result); + "cn=defaults", NULL, 0, NULL, NULL, tvp, 0, &result); if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) { bv = ldap_get_values_len(ld, entry, "sudoOption"); if (bv != NULL) { @@ -1705,6 +1722,22 @@ sudo_ldap_set_options(LDAP *ld) } } +#ifdef LDAP_OPT_TIMEOUT + /* Convert timeout to a timeval */ + if (ldap_conf.timeout > 0) { + struct timeval tv; + tv.tv_sec = ldap_conf.timeout; + tv.tv_usec = 0; + rc = ldap_set_option(ld, LDAP_OPT_TIMEOUT, &tv); + if (rc != LDAP_OPT_SUCCESS) { + warningx("ldap_set_option(TIMEOUT, %ld): %s", + (long)tv.tv_sec, ldap_err2string(rc)); + return(-1); + } + DPRINTF(("ldap_set_option(LDAP_OPT_TIMEOUT, %ld)", + (long)tv.tv_sec), 1); + } +#endif #ifdef LDAP_OPT_NETWORK_TIMEOUT /* Convert bind_timelimit to a timeval */ if (ldap_conf.bind_timelimit > 0) { @@ -1968,6 +2001,7 @@ sudo_ldap_setdefs(struct sudo_nss *nss) { struct ldap_config_list_str *base; struct sudo_ldap_handle *handle = nss->handle; + struct timeval tv, *tvp = NULL; LDAP *ld; LDAPMessage *entry, *result; int rc; @@ -1977,6 +2011,11 @@ sudo_ldap_setdefs(struct sudo_nss *nss) ld = handle->ld; for (base = ldap_conf.base; base != NULL; base = base->next) { + if (ldap_conf.timeout > 0) { + tv.tv_sec = ldap_conf.timeout; + tv.tv_usec = 0; + tvp = &tv; + } result = NULL; rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, "cn=defaults", NULL, 0, NULL, NULL, NULL, 0, &result); @@ -2219,6 +2258,7 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw) struct sudo_ldap_handle *handle = nss->handle; struct ldap_config_list_str *base; struct ldap_result *lres; + struct timeval tv, *tvp = NULL; LDAPMessage *entry, *result; LDAP *ld = handle->ld; int do_netgr, rc; @@ -2264,6 +2304,11 @@ sudo_ldap_result_get(struct sudo_nss *nss, struct passwd *pw) DPRINTF(("ldap search '%s'", filt), 1); for (base = ldap_conf.base; base != NULL; base = base->next) { DPRINTF(("searching from base '%s'", base->val), 1); + if (ldap_conf.timeout > 0) { + tv.tv_sec = ldap_conf.timeout; + tv.tv_usec = 0; + tvp = &tv; + } result = NULL; rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt, NULL, 0, NULL, NULL, NULL, 0, &result);