From: Todd C. Miller Date: Mon, 10 Jan 2011 15:28:59 +0000 (-0500) Subject: Add support for TIMEOUT in ldap.conf, mapping to the OpenLDAP X-Git-Tag: SUDO_1_7_5~76 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9aa8afc6fc63b3e847d95a2f6249c0a882f63515;p=sudo Add support for TIMEOUT in ldap.conf, mapping to the OpenLDAP LDAP_OPT_TIMEOUT. There is no corresponding option for mozilla-derived LDAP SDKs but we can pass the timeout parameter to ldap_search_ext_s() or ldap_search_st() when possible. --HG-- branch : 1.7 --- diff --git a/NEWS b/NEWS index 9d99add0f..0148a961d 100644 --- a/NEWS +++ b/NEWS @@ -68,6 +68,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 8c557943c..90c3a66e8 100644 --- a/config.h.in +++ b/config.h.in @@ -280,6 +280,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 690887f1f..0ec5e6e91 100755 --- a/configure +++ b/configure @@ -18309,7 +18309,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" @@ -18319,6 +18319,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 06618dc07..9b0c70f59 100644 --- a/configure.in +++ b/configure.in @@ -2656,7 +2656,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/ldap.c b/ldap.c index b7a82c48b..58e8cabde 100644 --- a/ldap.c +++ b/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 }, @@ -1143,6 +1153,7 @@ sudo_ldap_read_config() 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; @@ -1205,9 +1216,6 @@ sudo_ldap_read_config() 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) { fprintf(stderr, "LDAP Config Summary\n"); fprintf(stderr, "===================\n"); @@ -1241,6 +1249,8 @@ sudo_ldap_read_config() fprintf(stderr, "bind_timelimit %d\n", ldap_conf.bind_timelimit); if (ldap_conf.timelimit > 0) fprintf(stderr, "timelimit %d\n", ldap_conf.timelimit); + if (ldap_conf.timeout > 0) + fprintf(stderr, "timeout %d\n", ldap_conf.timeout); fprintf(stderr, "ssl %s\n", ldap_conf.ssl ? ldap_conf.ssl : "(no)"); if (ldap_conf.tls_checkpeer != -1) @@ -1278,6 +1288,9 @@ sudo_ldap_read_config() 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 */ @@ -1394,6 +1407,7 @@ sudo_ldap_display_defaults(nss, pw, lbuf) 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; @@ -1406,9 +1420,14 @@ sudo_ldap_display_defaults(nss, pw, lbuf) 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) { @@ -1771,6 +1790,22 @@ sudo_ldap_set_options(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) { @@ -2040,6 +2075,7 @@ sudo_ldap_setdefs(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; @@ -2049,6 +2085,11 @@ sudo_ldap_setdefs(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); @@ -2302,6 +2343,7 @@ sudo_ldap_result_get(nss, 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; @@ -2347,6 +2389,11 @@ sudo_ldap_result_get(nss, 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); diff --git a/sudoers.ldap.cat b/sudoers.ldap.cat index d858eb000..352fc17bb 100644 --- a/sudoers.ldap.cat +++ b/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.7.5b2 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.7.5b2 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 + + + +1.7.5b2 January 10, 2011 13 + + + + + +SUDOERS.LDAP(4) MAINTENANCE COMMANDS SUDOERS.LDAP(4) + + http://www.sudo.ws/sudo/license.html for complete details. -1.7.5b2 January 10, 2011 13 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1.7.5b2 January 10, 2011 14 diff --git a/sudoers.ldap.man.in b/sudoers.ldap.man.in index e04473b6a..343331da5 100644 --- a/sudoers.ldap.man.in +++ b/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/sudoers.ldap.pod b/sudoers.ldap.pod index 89409cb7b..b7918071c 100644 --- a/sudoers.ldap.pod +++ b/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