[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re-binding to a failed connection segfaults

Hi list,

I've created a small reproducer, that calls ldap_sasl_interactive_bind_s after
it has been called once and failed, which causes a segfault.

I've traced this bug with gdb:
$ gdb ./reproducer

GNU gdb (GDB) Fedora (
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
Reading symbols from
(gdb) r
Starting program: /home/jsynacek/work/bz784989-openldap-rebinding/reproducer 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
ldap_sasl_interactive_bind: user selected: GSSAPI
ldap_int_sasl_bind: GSSAPI
ldap_new_connection 1 1 0
ldap_connect_to_host: TCP localhost:636
ldap_new_socket: 7
ldap_prepare_socket: 7
ldap_connect_to_host: Trying ::1 636
ldap_pvt_connect: fd: 7 tm: -1 async: 0
TLS: error: tlsm_PR_Recv returned 0 - error 21:Is a directory
TLS: error: connect - force handshake failure: errno 21 - moznss error -5938
TLS: can't connect: TLS error -5938:Encountered end of file.
bind failed: Can't contact LDAP server, retrying for fun and profit!
ldap_sasl_interactive_bind: user selected: GSSAPI
ldap_int_sasl_bind: GSSAPI

Program received signal SIGSEGV, Segmentation fault.
ldap_int_sasl_bind (ld=0x603130, dn=0x0, mechs=0x401a30 "GSSAPI", sctrls=0x0,
cctrls=0x0, flags=1, 
    interact=0x401660 <lutil_sasl_interact>, defaults=0x60cae0, result=0x0,
	msgid=0x7fffffffd88c) at ../../../libraries/libldap/cyrus.c:444
444                     oldctx = ld->ld_defconn->lconn_sasl_authctx;
(gdb) p ld->ldc->ldc_defconn 
$1 = (LDAPConn *) 0x0

If you set slapd to use TLS certs (uncomment the 'TLS*' lines in the config),
there is no segfault.

Reproducer and cn=config.ldif attached.
Original bugreport: https://bugzilla.redhat.com/show_bug.cgi?id=784989

Jan Synacek
BaseOS team Brno
#include <stdio.h>
#include <stdbool.h>
#include <ldap.h>
#include "lutil.h"
#include "lutil_ldap.h"

import ldap
from ldap import sasl
from ldap.ldapobject import SimpleLDAPObject

SASL_AUTH = ldap.sasl.sasl({},'GSSAPI')

def make_conn(url):
	cert_path = '/etc/pki/tls/certs/ca-bundle.crt'
	conn = SimpleLDAPObject(url)
	ldap.set_option(ldap.OPT_DEBUG_LEVEL, 255)
	ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, cert_path)
		conn.sasl_interactive_bind_s('', SASL_AUTH)
	except ldap.SERVER_DOWN:
		conn.sasl_interactive_bind_s('', SASL_AUTH)


static bool do_ldap()
	LDAP *ldap = NULL;
	char *sasl_realm = NULL;
	char *sasl_authc_id = NULL;
	char *sasl_authz_id = NULL;
	char *sasl_mech = "GSSAPI";
	unsigned sasl_flags = LDAP_SASL_INTERACTIVE;   
	void *defaults;
	int dbg = 255;
	int protocol = 3;
	int rc;

	rc = ldap_initialize(&ldap, "ldaps://localhost:636");
	if (rc != LDAP_SUCCESS) {
		fprintf(stderr, "ldap_initialize() failed: %s\n", ldap_err2string(rc));
		return false;

	ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &dbg);
	ldap_set_option(ldap, LDAP_OPT_X_TLS_CACERTFILE, "/never-mind-the-certs/x.crt");
	ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &protocol);   

	defaults = lutil_sasl_defaults(ldap, sasl_mech, sasl_realm, sasl_authc_id, NULL, sasl_authz_id);

	rc = ldap_sasl_interactive_bind_s(ldap, NULL, sasl_mech, NULL, NULL, sasl_flags, lutil_sasl_interact, defaults);
	if (rc != LDAP_SUCCESS) {
		fprintf(stderr, "bind failed: %s, retrying for fun and profit!\n", ldap_err2string(rc));
		rc = ldap_sasl_interactive_bind_s(ldap, NULL, sasl_mech, NULL, NULL, sasl_flags, lutil_sasl_interact, defaults);

	ldap_unbind_ext_s(ldap, NULL, NULL);
	return true;

int main()
    return (do_ldap());

# CRC32 edc69612
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/openldap/slapd.args
olcPidFile: /var/run/openldap/slapd.pid
#olcTLSCACertificatePath: /etc/openldap/certs
#olcTLSCertificateFile: "OpenLDAP Server"
#olcTLSCertificateKeyFile: /etc/openldap/certs/password
structuralObjectClass: olcGlobal
entryUUID: 9bc845b2-e89e-1030-9c1a-e588e4afc7c9
creatorsName: cn=config
createTimestamp: 20120211015107Z
entryCSN: 20120211015107.318106Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20120211015107Z