X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fconfig.c;h=056838f10b9d4b9261e6aa1ecb7b8730a7a33d95;hb=f57a216f1cb425e208b5609e1b0451e988583ce1;hp=f89acce44c2a34bfbdebc0883b77cf6f7c1984d1;hpb=acba6fde99c87f26f91997e79d61ae2f22d13c43;p=openldap diff --git a/servers/slapd/config.c b/servers/slapd/config.c index f89acce44c..056838f10b 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -41,10 +42,6 @@ #define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) #endif -#ifdef HAVE_UNISTD_H -#include -#endif - #include "slap.h" #ifdef LDAP_SLAPI #include "slapi/slapi.h" @@ -128,6 +125,7 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) { int rc, arg_user, arg_type, arg_syn, iarg; unsigned uiarg; long larg; + unsigned long ularg; ber_len_t barg; if(Conf->arg_type == ARG_IGNORED) { @@ -260,6 +258,16 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) { return(ARG_BAD_CONF); } break; + case ARG_ULONG: + if ( lutil_atoulx( &ularg, c->argv[1], 0 ) != 0 ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), + "<%s> unable to parse \"%s\" as unsigned long", + c->argv[0], c->argv[1] ); + Debug(LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", + c->log, c->cr_msg, 0); + return(ARG_BAD_CONF); + } + break; case ARG_BER_LEN_T: { unsigned long l; if ( lutil_atoulx( &l, c->argv[1], 0 ) != 0 ) { @@ -295,8 +303,8 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) { break; } j = (arg_type & ARG_NONZERO) ? 1 : 0; - if(iarg < j && larg < j && barg < j ) { - larg = larg ? larg : (barg ? barg : iarg); + if(iarg < j && larg < j && barg < (unsigned)j ) { + larg = larg ? larg : (barg ? (long)barg : iarg); snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value", c->argv[0] ); Debug(LDAP_DEBUG_ANY|LDAP_DEBUG_NONE, "%s: %s\n", @@ -308,6 +316,7 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) { case ARG_INT: c->value_int = iarg; break; case ARG_UINT: c->value_uint = uiarg; break; case ARG_LONG: c->value_long = larg; break; + case ARG_ULONG: c->value_ulong = ularg; break; case ARG_BER_LEN_T: c->value_ber_t = barg; break; } } @@ -359,6 +368,7 @@ int config_set_vals(ConfigTable *Conf, ConfigArgs *c) { case ARG_INT: *(int*)ptr = c->value_int; break; case ARG_UINT: *(unsigned*)ptr = c->value_uint; break; case ARG_LONG: *(long*)ptr = c->value_long; break; + case ARG_ULONG: *(unsigned long*)ptr = c->value_ulong; break; case ARG_BER_LEN_T: *(ber_len_t*)ptr = c->value_ber_t; break; case ARG_STRING: { char *cc = *(char**)ptr; @@ -404,6 +414,7 @@ config_del_vals(ConfigTable *cf, ConfigArgs *c) /* If there is no handler, just ignore it */ if ( cf->arg_type & ARG_MAGIC ) { + c->argv[0] = cf->ad->ad_cname.bv_val; c->op = LDAP_MOD_DELETE; c->type = cf->arg_type & ARGS_USERLAND; rc = (*((ConfigDriver*)cf->arg_item))(c); @@ -449,6 +460,7 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c) case ARG_INT: c->value_int = *(int *)ptr; break; case ARG_UINT: c->value_uint = *(unsigned *)ptr; break; case ARG_LONG: c->value_long = *(long *)ptr; break; + case ARG_ULONG: c->value_ulong = *(unsigned long *)ptr; break; case ARG_BER_LEN_T: c->value_ber_t = *(ber_len_t *)ptr; break; case ARG_STRING: if ( *(char **)ptr ) @@ -467,6 +479,7 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c) case ARG_INT: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%d", c->value_int); break; case ARG_UINT: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%u", c->value_uint); break; case ARG_LONG: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_long); break; + case ARG_ULONG: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%lu", c->value_ulong); break; case ARG_BER_LEN_T: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%ld", c->value_ber_t); break; case ARG_ON_OFF: bv.bv_len = snprintf(bv.bv_val, sizeof( c->log ), "%s", c->value_int ? "TRUE" : "FALSE"); break; @@ -1197,8 +1210,118 @@ static slap_verbmasks versionkey[] = { { BER_BVNULL, 0 } }; +static int +slap_keepalive_parse( + struct berval *val, + void *bc, + slap_cf_aux_table *tab0, + const char *tabmsg, + int unparse ) +{ + if ( unparse ) { + slap_keepalive *sk = (slap_keepalive *)bc; + int rc = snprintf( val->bv_val, val->bv_len, "%d:%d:%d", + sk->sk_idle, sk->sk_probes, sk->sk_interval ); + if ( rc < 0 ) { + return -1; + } + + if ( (unsigned)rc >= val->bv_len ) { + return -1; + } + + val->bv_len = rc; + + } else { + char *s = val->bv_val; + char *next; + slap_keepalive *sk = (slap_keepalive *)bc; + slap_keepalive sk2; + + if ( s[0] == ':' ) { + sk2.sk_idle = 0; + s++; + + } else { + sk2.sk_idle = strtol( s, &next, 10 ); + if ( next == s || next[0] != ':' ) { + return -1; + } + + if ( sk2.sk_idle < 0 ) { + return -1; + } + + s = ++next; + } + + if ( s[0] == ':' ) { + sk2.sk_probes = 0; + s++; + + } else { + sk2.sk_probes = strtol( s, &next, 10 ); + if ( next == s || next[0] != ':' ) { + return -1; + } + + if ( sk2.sk_probes < 0 ) { + return -1; + } + + s = ++next; + } + + if ( s == '\0' ) { + sk2.sk_interval = 0; + s++; + + } else { + sk2.sk_interval = strtol( s, &next, 10 ); + if ( next == s || next[0] != '\0' ) { + return -1; + } + + if ( sk2.sk_interval < 0 ) { + return -1; + } + } + + *sk = sk2; + + ber_memfree( val->bv_val ); + BER_BVZERO( val ); + } + + return 0; +} + +static int +slap_sb_uri( + struct berval *val, + void *bcp, + slap_cf_aux_table *tab0, + const char *tabmsg, + int unparse ) +{ + slap_bindconf *bc = bcp; + if ( unparse ) { + if ( bc->sb_uri.bv_len >= val->bv_len ) + return -1; + val->bv_len = bc->sb_uri.bv_len; + AC_MEMCPY( val->bv_val, bc->sb_uri.bv_val, val->bv_len ); + } else { + bc->sb_uri = *val; +#ifdef HAVE_TLS + if ( ldap_is_ldaps_url( val->bv_val )) + bc->sb_tls_do_init = 1; +#endif + } + return 0; +} + static slap_cf_aux_table bindkey[] = { - { BER_BVC("uri="), offsetof(slap_bindconf, sb_uri), 'b', 1, NULL }, + { BER_BVC("uri="), 0, 'x', 1, slap_sb_uri }, { BER_BVC("version="), offsetof(slap_bindconf, sb_version), 'i', 0, versionkey }, { BER_BVC("bindmethod="), offsetof(slap_bindconf, sb_method), 'i', 0, methkey }, { BER_BVC("timeout="), offsetof(slap_bindconf, sb_timeout_api), 'i', 0, NULL }, @@ -1210,22 +1333,22 @@ static slap_cf_aux_table bindkey[] = { { BER_BVC("realm="), offsetof(slap_bindconf, sb_realm), 'b', 0, NULL }, { BER_BVC("authcID="), offsetof(slap_bindconf, sb_authcId), 'b', 1, NULL }, { BER_BVC("authzID="), offsetof(slap_bindconf, sb_authzId), 'b', 1, (slap_verbmasks *)authzNormalize }, + { BER_BVC("keepalive="), offsetof(slap_bindconf, sb_keepalive), 'x', 0, (slap_verbmasks *)slap_keepalive_parse }, #ifdef HAVE_TLS - { BER_BVC("starttls="), offsetof(slap_bindconf, sb_tls), 'i', 0, tlskey }, - /* NOTE: replace "13" with the actual index * of the first TLS-related line */ #define aux_TLS (bindkey+13) /* beginning of TLS keywords */ + { BER_BVC("starttls="), offsetof(slap_bindconf, sb_tls), 'i', 0, tlskey }, { BER_BVC("tls_cert="), offsetof(slap_bindconf, sb_tls_cert), 's', 1, NULL }, { BER_BVC("tls_key="), offsetof(slap_bindconf, sb_tls_key), 's', 1, NULL }, { BER_BVC("tls_cacert="), offsetof(slap_bindconf, sb_tls_cacert), 's', 1, NULL }, { BER_BVC("tls_cacertdir="), offsetof(slap_bindconf, sb_tls_cacertdir), 's', 1, NULL }, - { BER_BVC("tls_reqcert="), offsetof(slap_bindconf, sb_tls_reqcert), 's', 1, NULL }, - { BER_BVC("tls_cipher_suite="), offsetof(slap_bindconf, sb_tls_cipher_suite), 's', 1, NULL }, - { BER_BVC("tls_protocol_min="), offsetof(slap_bindconf, sb_tls_protocol_min), 's', 1, NULL }, + { BER_BVC("tls_reqcert="), offsetof(slap_bindconf, sb_tls_reqcert), 's', 0, NULL }, + { BER_BVC("tls_cipher_suite="), offsetof(slap_bindconf, sb_tls_cipher_suite), 's', 0, NULL }, + { BER_BVC("tls_protocol_min="), offsetof(slap_bindconf, sb_tls_protocol_min), 's', 0, NULL }, #ifdef HAVE_OPENSSL_CRL - { BER_BVC("tls_crlcheck="), offsetof(slap_bindconf, sb_tls_crlcheck), 's', 1, NULL }, + { BER_BVC("tls_crlcheck="), offsetof(slap_bindconf, sb_tls_crlcheck), 's', 0, NULL }, #endif #endif { BER_BVNULL, 0, 0, 0, NULL } @@ -1317,6 +1440,20 @@ slap_cf_aux_table_parse( const char *word, void *dst, slap_cf_aux_table *tab0, L rc = lutil_atoulx( ulptr, val, 0 ); break; + + case 'x': + if ( tab->aux != NULL ) { + struct berval value; + slap_cf_aux_table_parse_x *func = (slap_cf_aux_table_parse_x *)tab->aux; + + ber_str2bv( val, 0, 1, &value ); + + rc = func( &value, (void *)((char *)dst + tab->off), tab, tabmsg, 0 ); + + } else { + rc = 1; + } + break; } if ( rc ) { @@ -1407,6 +1544,34 @@ slap_cf_aux_table_unparse( void *src, struct berval *bv, slap_cf_aux_table *tab0 ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%lu", *ulptr ); break; + case 'x': + { + char *saveptr=ptr; + *ptr++ = ' '; + ptr = lutil_strcopy( ptr, tab->key.bv_val ); + if ( tab->quote ) *ptr++ = '"'; + if ( tab->aux != NULL ) { + struct berval value; + slap_cf_aux_table_parse_x *func = (slap_cf_aux_table_parse_x *)tab->aux; + int rc; + + value.bv_val = ptr; + value.bv_len = buf + sizeof( buf ) - ptr; + + rc = func( &value, (void *)((char *)src + tab->off), tab, "(unparse)", 1 ); + if ( rc == 0 ) { + if (value.bv_len) { + ptr += value.bv_len; + } else { + ptr = saveptr; + break; + } + } + } + if ( tab->quote ) *ptr++ = '"'; + } + break; + default: assert( 0 ); } @@ -1721,6 +1886,18 @@ slap_client_connect( LDAP **ldp, slap_bindconf *sb ) ldap_set_option( ld, LDAP_OPT_NETWORK_TIMEOUT, &tv ); } + if ( sb->sb_keepalive.sk_idle ) { + ldap_set_option( ld, LDAP_OPT_X_KEEPALIVE_IDLE, &sb->sb_keepalive.sk_idle ); + } + + if ( sb->sb_keepalive.sk_probes ) { + ldap_set_option( ld, LDAP_OPT_X_KEEPALIVE_PROBES, &sb->sb_keepalive.sk_probes ); + } + + if ( sb->sb_keepalive.sk_interval ) { + ldap_set_option( ld, LDAP_OPT_X_KEEPALIVE_INTERVAL, &sb->sb_keepalive.sk_interval ); + } + #ifdef HAVE_TLS if ( sb->sb_tls_do_init ) { rc = bindconf_tls_set( sb, ld ); @@ -2111,3 +2288,66 @@ int config_generic_wrapper( Backend *be, const char *fname, int lineno, } return rc; } + +/* See if the given URL (in plain and parsed form) matches + * any of the server's listener addresses. Return matching + * Listener or NULL for no match. + */ +Listener *config_check_my_url( const char *url, LDAPURLDesc *lud ) +{ + Listener **l = slapd_get_listeners(); + int i, isMe; + + /* Try a straight compare with Listener strings */ + for ( i=0; l && l[i]; i++ ) { + if ( !strcasecmp( url, l[i]->sl_url.bv_val )) { + return l[i]; + } + } + + isMe = 0; + /* If hostname is empty, or is localhost, or matches + * our hostname, this url refers to this host. + * Compare it against listeners and ports. + */ + if ( !lud->lud_host || !lud->lud_host[0] || + !strncasecmp("localhost", lud->lud_host, + STRLENOF("localhost")) || + !strcasecmp( global_host, lud->lud_host )) { + + for ( i=0; l && l[i]; i++ ) { + LDAPURLDesc *lu2; + ldap_url_parse( l[i]->sl_url.bv_val, &lu2 ); + do { + if ( strcasecmp( lud->lud_scheme, + lu2->lud_scheme )) + break; + if ( lud->lud_port != lu2->lud_port ) + break; + /* Listener on ANY address */ + if ( !lu2->lud_host || !lu2->lud_host[0] ) { + isMe = 1; + break; + } + /* URL on ANY address */ + if ( !lud->lud_host || !lud->lud_host[0] ) { + isMe = 1; + break; + } + /* Listener has specific host, must + * match it + */ + if ( !strcasecmp( lud->lud_host, + lu2->lud_host )) { + isMe = 1; + break; + } + } while(0); + ldap_free_urldesc( lu2 ); + if ( isMe ) { + return l[i]; + } + } + } + return NULL; +}