OpenLDAP 2.1.15 Engineering
Fixed slapd saslauthz null backend crash
- Fixed liblutil getpeereid replacement function
- Fixed liblber 64bit len/tag bug
+ Fixed libldap IPv6 SASL host bug (ITS#2347)
+ Fixed liblber 64bit len/tag bug (ITS#2344)
+ Fixed liblutil getpeereid replacement function (ITS#2333)
+ Fixed slapd illegal schema crash (ITS#2342)
+ Updated slaptools default backend (ITS#2343)
Updated liblber ber_get_stringbv handling
+ Removed lint
Build Environment
Updated NT build environment w/ slurpd support
Updated test suite
dnl ----------------------------------------------------------------
dnl PF_INET6 support requires getaddrinfo and INET6_ADDRSTRLEN
dnl PF_LOCAL may use getaddrinfo in available
-AC_CHECK_FUNCS( getaddrinfo gai_strerror inet_ntop )
+AC_CHECK_FUNCS( getaddrinfo getnameinfo gai_strerror inet_ntop )
ol_link_ipv6=no
if test $ac_cv_func_getaddrinfo = no -o $ac_cv_func_inet_ntop = no ; then
else
have_krb5=no
- AC_MSG_WARN([Unrecongized Kerberos5 Implementation])
+ AC_MSG_WARN([Unrecognized Kerberos5 Implementation])
fi
if test $have_krb5 = yes ; then
LDAP_LUTIL_F( int ) getpeereid( int s, uid_t *, gid_t * );
#endif
+/* DNS RFC defines max host name as 255. New systems seem to use 1024 */
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 256
+#endif
+
#endif /* _AC_SOCKET_H_ */
LDAPControl **sctrls,
LDAPControl **cctrls ));
+/*
+ * in passwd.c
+ */
+
+LDAP_F( int )
+ldap_parse_passwd LDAP_P((
+ LDAP *ld,
+ LDAPMessage *res,
+ struct berval *newpasswd ));
+
+LDAP_F( int )
+ldap_passwd LDAP_P(( LDAP *ld,
+ struct berval *user,
+ struct berval *oldpw,
+ struct berval *newpw,
+ LDAPControl **sctrls,
+ LDAPControl **cctrls,
+ int *msgidp ));
+
+LDAP_F( int )
+ldap_passwd_s LDAP_P((
+ LDAP *ld,
+ struct berval *user,
+ struct berval *oldpw,
+ struct berval *newpw,
+ struct berval *newpasswd,
+ LDAPControl **sctrls,
+ LDAPControl **cctrls ));
+
LDAP_END_DECL
#endif /* _LDAP_H */
struct hostent **result,
int *herrno_ptr ));
+struct sockaddr;
+
+LDAP_F( int )
+ldap_pvt_get_hname LDAP_P((
+ const struct sockaddr * sa,
+ int salen,
+ char *name,
+ int namelen,
+ char **herr ));
+
/* charray.c */
while (ber->ber_rwptr > (char *)&ber->ber_tag && ber->ber_rwptr <
(char *)&ber->ber_len + LENSIZE*2) {
ber_slen_t sblen;
- char buf[LENSIZE-1];
+ char buf[sizeof(ber->ber_len)-1];
ber_len_t tlen = 0;
sblen=ber_int_sb_read( sb, ber->ber_rwptr,
}
/* Are there leftover data bytes inside ber->ber_len? */
- if (ber->ber_ptr < (char *)&ber->ber_len+LENSIZE) {
- if (ber->ber_rwptr < (char *)&ber->ber_len+LENSIZE)
+ if (ber->ber_ptr < (char *)&ber->ber_usertag) {
+ if (ber->ber_rwptr < (char *)&ber->ber_usertag)
sblen = ber->ber_rwptr - ber->ber_ptr;
else
- sblen = ((char *)&ber->ber_len+LENSIZE) - ber->ber_ptr;
+ sblen = (char *)&ber->ber_usertag - ber->ber_ptr;
AC_MEMCPY(buf, ber->ber_ptr, sblen);
ber->ber_ptr += sblen;
} else {
char *
ldap_host_connected_to( Sockbuf *sb )
{
- struct hostent *hp;
socklen_t len;
#ifdef LDAP_PF_INET6
struct sockaddr_storage sabuf;
struct sockaddr sabuf;
#endif
struct sockaddr *sa = (struct sockaddr *) &sabuf;
- char *addr;
- char *host;
-
- /* buffers for gethostbyaddr_r */
- struct hostent he_buf;
- int local_h_errno;
- char *ha_buf=NULL;
+ char *host = NULL, *herr;
+ char hbuf[NI_MAXHOST];
+ int rc;
ber_socket_t sd;
(void)memset( (char *)sa, '\0', sizeof sabuf );
#endif
#ifdef LDAP_PF_INET6
case AF_INET6:
- addr = (char *) &((struct sockaddr_in6 *)sa)->sin6_addr;
- len = sizeof( struct in6_addr );
+ {
+ struct in6_addr localhost = IN6ADDR_LOOPBACK_INIT;
+ if( memcmp ( &((struct sockaddr_in6 *)sa)->sin6_addr,
+ &localhost, sizeof(localhost)) == 0 )
+ {
+ return LDAP_STRDUP( ldap_int_hostname );
+ }
+ }
break;
#endif
case AF_INET:
- addr = (char *) &((struct sockaddr_in *)sa)->sin_addr;
- len = sizeof( struct in_addr );
-
{
- struct sockaddr_in localhost;
- localhost.sin_addr.s_addr = htonl( INADDR_ANY );
+ struct in_addr localhost;
+ localhost.s_addr = htonl( INADDR_ANY );
- if( memcmp ( &localhost.sin_addr,
- &((struct sockaddr_in *)sa)->sin_addr,
- sizeof(localhost.sin_addr) ) == 0 )
+ if( memcmp ( &((struct sockaddr_in *)sa)->sin_addr,
+ &localhost, sizeof(localhost) ) == 0 )
{
return LDAP_STRDUP( ldap_int_hostname );
}
#ifdef INADDR_LOOPBACK
- localhost.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
+ localhost.s_addr = htonl( INADDR_LOOPBACK );
- if( memcmp ( &localhost.sin_addr,
- &((struct sockaddr_in *)sa)->sin_addr,
- sizeof(localhost.sin_addr) ) == 0 )
+ if( memcmp ( &((struct sockaddr_in *)sa)->sin_addr,
+ &localhost, sizeof(localhost) ) == 0 )
{
return LDAP_STRDUP( ldap_int_hostname );
}
break;
}
- host = NULL;
- if ((ldap_pvt_gethostbyaddr_a( addr, len, sa->sa_family,
- &he_buf, &ha_buf, &hp, &local_h_errno ) == 0 ) &&
- (hp != NULL) && ( hp->h_name != NULL ) )
+ hbuf[0] = 0;
+ if (ldap_pvt_get_hname( sa, len, hbuf, sizeof(hbuf), &herr ) == 0 &&
+ hbuf[0] )
{
- host = LDAP_STRDUP( hp->h_name );
+ host = LDAP_STRDUP( hbuf );
}
- LDAP_FREE( ha_buf );
return host;
}
#endif
!defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && \
defined(HAVE_SENDMSG) && defined(HAVE_MSGHDR_MSG_ACCRIGHTS)
#define DO_SENDMSG
+static const char abandonPDU[] = {LDAP_TAG_MESSAGE, 6,
+ LDAP_TAG_MSGID, 1, 0, LDAP_REQ_ABANDON, 1, 0};
#endif
static int
sendcred:
{
int fds[2];
- /* Abandon, noop, has no reply */
- char txt[] = {LDAP_TAG_MESSAGE, 6,
- LDAP_TAG_MSGID, 1, 0, LDAP_REQ_ABANDON, 1, 0};
- struct iovec iov = {txt, sizeof(txt)};
- struct msghdr msg = {0};
if (pipe(fds) == 0) {
+ /* Abandon, noop, has no reply */
+ struct iovec iov = {abandonPDU, sizeof(abandonPDU)};
+ struct msghdr msg = {0};
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_accrights = (char *)fds;
return -1;
#endif
}
-
+
+#ifndef GETNAMEINFO
+static const char *
+hp_strerror( int err )
+{
+ switch (err) {
+ case HOST_NOT_FOUND: return "Host not found (authoritative)";
+ case TRY_AGAIN: return "Host not found (server fail?)";
+ case NO_RECOVERY: return "Non-recoverable failure";
+ case NO_DATA: return "No data of requested type";
+#ifdef NETDB_INTERNAL
+ case NETDB_INTERNAL: return STRERROR( errno );
+#endif
+ default: break;
+ }
+ return "Unknown resolver error";
+}
+#endif
+
+int ldap_pvt_get_hname(
+ const struct sockaddr *sa,
+ int len,
+ char *name,
+ int namelen,
+ char **err )
+{
+ int rc;
+#if defined( HAVE_GETNAMEINFO )
+
+#if defined( LDAP_R_COMPILE )
+ ldap_pvt_thread_mutex_lock( &ldap_int_resolv_mutex );
+#endif
+ rc = getnameinfo( sa, len, name, namelen, NULL, 0, 0 );
+#if defined( LDAP_R_COMPILE )
+ ldap_pvt_thread_mutex_unlock( &ldap_int_resolv_mutex );
+#endif
+ if ( rc ) *err = AC_GAI_STRERROR( rc );
+ return rc;
+
+#else /* !HAVE_GETNAMEINFO */
+ char *addr;
+ int alen;
+ struct hostent *hp = NULL;
+#ifdef HAVE_GETHOSTBYADDR_R
+ struct hostent hb;
+ int buflen=BUFSTART, h_errno;
+ char *buf=NULL;
+#endif
+
+#ifdef LDAP_PF_INET6
+ if (sa->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
+ addr = (char *)&sin->sin6_addr;
+ alen = sizeof(sin->sin6_addr);
+ } else
+#endif
+ if (sa->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ addr = (char *)&sin->sin_addr;
+ alen = sizeof(sin->sin_addr);
+ } else {
+ rc = NO_RECOVERY;
+ *err = (char *)hp_strerror( rc );
+ return rc;
+ }
+#if defined( HAVE_GETHOSTBYADDR_R )
+ for(;buflen<BUFMAX;) {
+ if (safe_realloc( &buf, buflen )==NULL) {
+ *err = (char *)STRERROR( ENOMEM );
+ return ENOMEM;
+ }
+#if (GETHOSTBYADDR_R_NARGS < 8)
+ hp=gethostbyaddr_r( addr, alen, sa->sa_family,
+ &hb, buf, buflen, &h_errno );
+ rc = (hp == NULL) ? -1 : 0;
+#else
+ rc = gethostbyaddr_r( addr, alen, sa->sa_family,
+ &hb, buf, buflen,
+ &hp, &h_errno );
+#endif
+#ifdef NETDB_INTERNAL
+ if ((rc<0) &&
+ (h_errno==NETDB_INTERNAL) &&
+ (errno==ERANGE))
+ {
+ buflen*=2;
+ continue;
+ }
+#endif
+ break;
+ }
+ if (hp) {
+ strncpy( name, hp->h_name, namelen );
+ } else {
+ *err = (char *)hp_strerror( h_errno );
+ }
+ LDAP_FREE(buf);
+#else /* HAVE_GETHOSTBYADDR_R */
+
+#if defined( LDAP_R_COMPILE )
+ ldap_pvt_thread_mutex_lock( &ldap_int_resolv_mutex );
+#endif
+ hp = gethostbyaddr( addr, alen, sa->sa_family );
+ if (hp) {
+ strncpy( name, hp->h_name, namelen );
+ rc = 0;
+ } else {
+ rc = h_errno;
+ *err = (char *)hp_strerror( h_errno );
+ }
+#if defined( LDAP_R_COMPILE )
+ ldap_pvt_thread_mutex_unlock( &ldap_int_resolv_mutex );
+#endif
+
+#endif /* !HAVE_GETHOSTBYADDR_R */
+ return rc;
+#endif /* !HAVE_GETNAMEINFO */
+}
+
int ldap_pvt_gethostbyaddr_a(
const char *addr,
int len,
}
#elif defined( DO_SENDMSG )
int dummy, fd[2];
- struct iovec iov = {(char *)&dummy, 1};
+ struct iovec iov;
struct msghdr msg = {0};
struct stat st;
+
+ iov.iov_base = (char*) &dummy;
+ iov.iov_len = 1;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_accrights = (char *)fd;
fname, lineno );
return( 1 );
}
- bdb->bi_idl_cache_max_size = atoi( argv[1] );
+ if ( !( slapMode & SLAP_TOOL_MODE ) )
+ bdb->bi_idl_cache_max_size = atoi( argv[1] );
#endif
/* anything else */
#include "slap.h"
#include "../back-ldap/back-ldap.h"
+#undef ldap_debug /* silence a warning in ldap-int.h */
#include "../../../libraries/libldap/ldap-int.h"
#include "back-meta.h"
be = &backendDB[i];
/* Subordinates are not exposed as their own naming context */
- if ( be->be_flags & SLAP_BFLAG_GLUE_SUBORDINATE ) {
+ if ( SLAP_GLUE_SUBORDINATE( be ) ) {
continue;
}
for ( j = 0; backends[i].be_nsuffix != NULL &&
backends[i].be_nsuffix[j].bv_val != NULL; j++ )
{
- if (( backends[i].be_flags & SLAP_BFLAG_GLUE_SUBORDINATE )
+ if ( ( SLAP_GLUE_SUBORDINATE( &backends[i] ) )
&& noSubs )
{
continue;
* backends and connect them to their superior.
*/
for (i = nBackendDB - 1, b1=&backendDB[i]; cont && i>=0; b1--,i--) {
- if (b1->be_flags & SLAP_BFLAG_GLUE_SUBORDINATE) {
+ if (SLAP_GLUE_SUBORDINATE ( b1 ) ) {
/* The last database cannot be a subordinate of noone */
if (i == nBackendDB - 1) {
b1->be_flags ^= SLAP_BFLAG_GLUE_SUBORDINATE;
}
gi = NULL;
for (j = i-1, be=&backendDB[j]; j>=0; be--,j--) {
- if (!(be->be_flags & SLAP_BFLAG_GLUE_SUBORDINATE)) {
+ if ( ! SLAP_GLUE_SUBORDINATE( be ) ) {
continue;
}
/* We will only link it once */
- if (be->be_flags & SLAP_BFLAG_GLUE_LINKED) {
+ if ( SLAP_GLUE_LINKED( be ) ) {
continue;
}
if (!dnIsSuffix(&be->be_nsuffix[0], &b1->be_nsuffix[0])) {
slap_ssf_t ssf = 0;
char *authid = NULL;
#ifdef SLAPD_RLOOKUPS
- char *hebuf = NULL;
+ char hbuf[NI_MAXHOST];
#endif
char *dnsname = NULL;
) {
#ifdef SLAPD_RLOOKUPS
if ( use_reverse_lookup ) {
- struct hostent he;
- int herr;
- struct hostent *hp = NULL;
-# ifdef LDAP_PF_INET6
- if ( from.sa_addr.sa_family == AF_INET6 )
- ldap_pvt_gethostbyaddr_a(
- (char *)&(from.sa_in6_addr.sin6_addr),
- sizeof(from.sa_in6_addr.sin6_addr),
- AF_INET6, &he, &hebuf,
- &hp, &herr );
- else
-# endif /* LDAP_PF_INET6 */
- ldap_pvt_gethostbyaddr_a(
- (char *) &(from.sa_in_addr.sin_addr),
- sizeof(from.sa_in_addr.sin_addr),
- AF_INET, &he, &hebuf, &hp, &herr );
- dnsname = hp ? ldap_pvt_str2lower( hp->h_name ) : NULL;
+ char *herr;
+ if (ldap_pvt_get_hname( &from, len, hbuf,
+ sizeof(hbuf), &herr ) == 0) {
+ ldap_pvt_str2lower( hbuf );
+ dnsname = hbuf;
+ }
}
#else
dnsname = NULL;
authid );
if( authid ) ch_free(authid);
-#ifdef SLAPD_RLOOKUPS
- if( hebuf ) ldap_memfree(hebuf);
-#endif
if( id < 0 ) {
#ifdef NEW_LOGGING
}
#endif
}
-#endif
if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
char abuf[BUFSIZ/2], *ptr = abuf;
op->o_connid, op->o_opid, abuf, 0, 0 );
}
}
+#endif /* LDAP_DEBUG */
manageDSAit = get_manageDSAit( op );
return LDAP_OTHER;
continue;
}
- if ( backends[i].be_flags & SLAP_BFLAG_GLUE_SUBORDINATE ) {
+ if ( SLAP_GLUE_SUBORDINATE( &backends[i] ) ) {
continue;
}
for ( j = 0; backends[i].be_suffix[j].bv_val != NULL; j++ ) {
#define SLAP_BFLAG_DYNAMIC 0x2000U
slap_mask_t be_flags;
#define SLAP_LASTMOD(be) (!((be)->be_flags & SLAP_BFLAG_NOLASTMOD))
+#define SLAP_GLUE_INSTANCE(be) ((be)->be_flags & SLAP_BFLAG_GLUE_INSTANCE)
+#define SLAP_GLUE_SUBORDINATE(be) \
+ ((be)->be_flags & SLAP_BFLAG_GLUE_SUBORDINATE)
+#define SLAP_GLUE_LINKED(be) ((be)->be_flags & SLAP_BFLAG_GLUE_LINKED)
#define SLAP_ALIASES(be) ((be)->be_flags & SLAP_BFLAG_ALIASES)
#define SLAP_REFERRALS(be) ((be)->be_flags & SLAP_BFLAG_REFERRALS)
#define SLAP_SUBENTRIES(be) ((be)->be_flags & SLAP_BFLAG_SUBENTRIES)
fprintf( stderr, (fmt), (connid), (opid), (arg1), (arg2), (arg3) );\
} while (0)
#define StatslogTest( level ) (ldap_debug & (level))
-#elif defined(LDAP_SYSLOG)
-#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) \
- do { \
- if ( ldap_syslog & (level) ) \
- syslog( ldap_syslog_level, (fmt), (connid), (opid), (arg1), \
- (arg2), (arg3) ); \
- } while (0)
-#define StatslogTest( level ) (ldap_syslog & (level))
#else
#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 )
#define StatslogTest( level ) (0)
/* If the named base is a glue master, operate on the
* entire context
*/
- if (be->be_flags & SLAP_BFLAG_GLUE_INSTANCE)
+ if (SLAP_GLUE_INSTANCE(be)) {
nosubordinates = 1;
+ }
} else if ( dbnum == -1 ) {
+ if ( nbackends <= 0 ) {
+ fprintf( stderr, "No available databases\n" );
+ exit( EXIT_FAILURE );
+ }
+
be = &backends[dbnum=0];
/* If just doing the first by default and it is a
* glue subordinate, find the master.
*/
- while (be->be_flags & SLAP_BFLAG_GLUE_SUBORDINATE) {
- nosubordinates = 1;
+ while (SLAP_GLUE_SUBORDINATE(be) || SLAP_MONITOR(be)) {
+ if (SLAP_GLUE_SUBORDINATE(be)) {
+ nosubordinates = 1;
+ }
be++;
+ dbnum++;
+ }
+
+
+ if ( dbnum >= nbackends ) {
+ fprintf( stderr, "Available database(s) "
+ "do not allow %s\n", name );
+ exit( EXIT_FAILURE );
+ }
+
+ if ( nosubordinates == 0 && dbnum > 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACKEND, ERR,
+"The first database does not allow %s; using the first available one (%d)\n",
+ name, dbnum + 1, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+"The first database does not allow %s; using the first available one (%d)\n",
+ name, dbnum + 1, 0 );
+#endif
}
} else if ( dbnum < 0 || dbnum > (nbackends-1) ) {
static void
-do_modrdn( char *uri, char *host, int port, char *manager, char *passwd, char *entry, int maxloop )
+do_modrdn( char *uri, char *host, int port, char *manager,
+ char *passwd, char *entry, int maxloop )
{
LDAP *ld = NULL;
int i;
pid_t pid = getpid();
- char *DNs[2] = { entry, NULL };
+ char *DNs[2];
char *rdns[2];
+ DNs[0] = entry;
DNs[1] = strdup( entry );
/* reverse the RDN, make new DN */