Esempio n. 1
0
static int ipa_tls_ssl_init(LDAP *ld, const char *ldap_uri)
{
    int ret = LDAP_SUCCESS;
    int tls_hard = LDAP_OPT_X_TLS_HARD;
    int tls_demand = LDAP_OPT_X_TLS_DEMAND;

    if (strncmp(ldap_uri, SCHEMA_LDAP, sizeof(SCHEMA_LDAP) - 1) == 0) {
        ret = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &tls_demand);
        if (ret != LDAP_OPT_SUCCESS) {
            fprintf(stderr, _("Unable to set LDAP_OPT_X_TLS_REQUIRE_CERT\n"));
            return ret;
        }
        ret = ldap_start_tls_s(ld, NULL, NULL);
        if (ret != LDAP_SUCCESS) {
            fprintf(stderr, _("Unable to initialize STARTTLS session\n"));
            return ret;
        }
    } else if (strncmp(ldap_uri, SCHEMA_LDAPS, sizeof(SCHEMA_LDAPS) - 1) == 0) {
        ret = ldap_set_option(ld, LDAP_OPT_X_TLS, &tls_hard);
        if (ret != LDAP_OPT_SUCCESS) {
            fprintf(stderr, _("Unable to set LDAP_OPT_X_TLS\n"));
            return ret;
        }
    }
    return ret;

}
Esempio n. 2
0
static LDAP *pw_ldap_connect(const char *dn, const char *password)
{
    LDAP *ld;
# ifdef LDAP_OPT_PROTOCOL_VERSION
    int version = ldap_version;
# endif

    if (ldap_uri == NULL) {
        return NULL;
    }
    if (ldap_initialize(&ld, ldap_uri) != LDAP_SUCCESS) {
        return NULL;
    }
# ifdef LDAP_OPT_PROTOCOL_VERSION
    if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) !=
        LDAP_SUCCESS) {
        return NULL;
    }
# endif
    if (use_tls > 0 && ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) {
        return NULL;
    }
    if (ldap_bind_s(ld, dn, password, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) {
        return NULL;
    }

    return ld;
}
Esempio n. 3
0
LDAPSession::LDAPSession ( string server,int port,string bindDN,
                           string pass, bool simple, bool start_tls )
{
	ld=ldap_init ( server.c_str(),port );
	if ( !ld )
		throw LDAPExeption ( "ldap_init","Can't initialize LDAP library." );
	int ver=3;
	int errc=ldap_set_option ( ld,LDAP_OPT_PROTOCOL_VERSION,&ver );
	if ( errc != LDAP_SUCCESS )
		throw LDAPExeption ( "ldap_set_option",
		                     ldap_err2string ( errc ) );
	if ( start_tls )
	{
		errc=ldap_start_tls_s ( ld,NULL,NULL );
		if ( errc != LDAP_SUCCESS )
			throw LDAPExeption ( "ldap_start_tls_s",
			                     ldap_err2string ( errc ) );
	}
	if ( !simple )
	{
		errc=ldap_bind_s ( ld,bindDN.c_str(),pass.c_str(),
		                   LDAP_AUTH_SIMPLE );
		if ( errc != LDAP_SUCCESS )
			throw LDAPExeption ( "ldap_bind_s",
			                     ldap_err2string ( errc ) );
	}
	else
	{
		errc=ldap_simple_bind_s ( ld,bindDN.c_str(),pass.c_str() );
		if ( errc != LDAP_SUCCESS )
			throw LDAPExeption ( "ldap_simple_bind_s",
			                     ldap_err2string ( errc ) );
	}
}
Esempio n. 4
0
PyObject *
LDAPObject_start_tls(LDAPObject *self, PyObject *args)
{
	PyObject *controls = NULL;
	LDAPObjectControl *ldapoc = NULL;
	LDAPControl **sctrls = NULL;
	LDAPControl **cctrls = NULL;
	int rc;

	if (self->ldap == NULL) {
		PyErr_SetString(LDAPError, "This instance has already been deallocated.");
		return NULL;
	}

	if (!PyArg_ParseTuple(args, "|O!", &LDAPObjectControlType, &controls))
		return NULL;

	if (controls) {
		ldapoc = (LDAPObjectControl *)controls;
		sctrls = ldapoc->sctrls;
		cctrls = ldapoc->cctrls;
	}

	LDAP_BEGIN_ALLOW_THREADS
	rc = ldap_start_tls_s(self->ldap, sctrls, cctrls);
	LDAP_END_ALLOW_THREADS
	if (rc != LDAP_SUCCESS) {
		PyErr_Format(LDAPError, "%s (%d)", ldap_err2string(rc), rc);
		return NULL;
	}
	Py_RETURN_NONE;
}
Esempio n. 5
0
/*
** Open and initialize a connection to a server.
** @param #1 String with hostname.
** @param #2 String with username.
** @param #3 String with password.
** @param #4 Boolean indicating if TLS must be used.
** @return #1 Userdata with connection structure.
*/
static int lualdap_open_simple (lua_State *L) {
	ldap_pchar_t host = (ldap_pchar_t) luaL_checkstring (L, 1);
	ldap_pchar_t who = (ldap_pchar_t) luaL_optstring (L, 2, NULL);
	const char *password = luaL_optstring (L, 3, NULL);
	int use_tls = lua_toboolean (L, 4);
	conn_data *conn = (conn_data *)lua_newuserdata (L, sizeof(conn_data));
	int err;

	/* Initialize */
	lualdap_setmeta (L, LUALDAP_CONNECTION_METATABLE);
	conn->version = 0;
	conn->ld = ldap_init (host, LDAP_PORT);
	if (conn->ld == NULL)
		return faildirect(L,LUALDAP_PREFIX"Error connecting to server");
	/* Set protocol version */
	conn->version = LDAP_VERSION3;
	if (ldap_set_option (conn->ld, LDAP_OPT_PROTOCOL_VERSION, &conn->version)
		!= LDAP_OPT_SUCCESS)
		return faildirect(L, LUALDAP_PREFIX"Error setting LDAP version");
	/* Use TLS */
	if (use_tls) {
		int rc = ldap_start_tls_s (conn->ld, NULL, NULL);
		if (rc != LDAP_SUCCESS)
			return faildirect (L, ldap_err2string (rc));
	}
	/* Bind to a server */
	err = ldap_bind_s (conn->ld, who, password, LDAP_AUTH_SIMPLE);
	if (err != LDAP_SUCCESS)
		return faildirect (L, ldap_err2string (err));

	return 1;
}
Esempio n. 6
0
static void
ldapdb_bind(struct ldapdb_data *data, LDAP **ldp)
{
#ifndef LDAPDB_RFC1823API
	const int ver = LDAPDB_LDAP_VERSION;
#endif

	if (*ldp != NULL)
		ldap_unbind(*ldp);
	*ldp = ldap_open(data->hostname, data->portno);
	if (*ldp == NULL)
		return;

#ifndef LDAPDB_RFC1823API
	ldap_set_option(*ldp, LDAP_OPT_PROTOCOL_VERSION, &ver);
#endif

#ifdef LDAPDB_TLS
	if (data->tls) {
		ldap_start_tls_s(*ldp, NULL, NULL);
	}
#endif

	if (ldap_simple_bind_s(*ldp, data->bindname, data->bindpw) != LDAP_SUCCESS) {
		ldap_unbind(*ldp);
		*ldp = NULL;
	}
}
Esempio n. 7
0
/* init && bind */
int ldap_connect(ldap_opt_t * ldap) {
    int version = LDAP_VERSION3;

    if (!ldap->servers)
        return FAILURE;

    /* Connection Init and setup */
    ldap->ld = ldap_init(ldap->servers, LDAP_PORT);
    if (!ldap->ld) {
        ldap_perror(ldap->ld, "ldap_init()");
        return FAILURE;
    }

    if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) {
        ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_PROTOCOL_VERSION)");
        return FAILURE;
    }

    /* Timeouts setup */
    if (ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, &ldap->b_timeout) != LDAP_SUCCESS) {
        ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT)");
    }
    if (ldap_set_option(ldap->ld, LDAP_OPT_TIMEOUT, &ldap->s_timeout) != LDAP_SUCCESS) {
        ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_TIMEOUT)");
    }

    /* TLS support */
    if ( (ldap->tls == -1) || (ldap->tls == 1) ) {
        if (ldap_start_tls_s(ldap->ld, NULL, NULL ) != LDAP_SUCCESS) {
            /* failed then reinit the initial connect */
            ldap_perror(ldap->ld, "ldap_connect: (TLS) ldap_start_tls()");
            if (ldap->tls == 1)
                return FAILURE;

            ldap->ld = ldap_init(ldap->servers, LDAP_PORT);
            if (!ldap->ld) { 
                ldap_perror(ldap->ld, "ldap_init()");
                return FAILURE;
            }

            if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) {
                 ldap_perror(ldap->ld, "ldap_set_option()");
                 return FAILURE;
            }
        }
    }


    if ( ldap_simple_bind_s(ldap->ld, ldap->binddn, ldap->bindpw) != LDAP_SUCCESS) {
        ldap_perror(ldap->ld, "ldap_simple_bind_s()");
        return FAILURE;
    }

    /* says it is connected */
    FLAG_SET_CONNECTED(ldap->flags);

    return SUCCESS;
}
Esempio n. 8
0
/*
 * \brief Load the cokebank database
 */
int Bank_Initialise(const char *Argument)
{
	#if USE_LDAP
	 int	rv;
	#endif
	
	// Open Cokebank
	gBank_File = fopen(Argument, "rb+");
	if( !gBank_File )	gBank_File = fopen(Argument, "wb+");
	if( !gBank_File ) {
		perror("Opening coke bank");
		return -1;
	}
	Bank_int_ReadDatabase();

	// Open log file
	// TODO: Do I need this?
	gBank_LogFile = fopen("cokebank.log", "a");
	if( !gBank_LogFile )	gBank_LogFile = stdout;
	
	
	#if USE_LDAP
	// Connect to LDAP
	rv = ldap_create(&gpLDAP);
	if(rv) {
		fprintf(stderr, "ldap_create: %s\n", ldap_err2string(rv));
		return 1;
	}
	rv = ldap_initialize(&gpLDAP, gsLDAPPath);
	if(rv) {
		fprintf(stderr, "ldap_initialize: %s\n", ldap_err2string(rv));
		return 1;
	}
	{ int ver = LDAP_VERSION3; ldap_set_option(gpLDAP, LDAP_OPT_PROTOCOL_VERSION, &ver); }
	# if 0
	rv = ldap_start_tls_s(gpLDAP, NULL, NULL);
	if(rv) {
		fprintf(stderr, "ldap_start_tls_s: %s\n", ldap_err2string(rv));
		return 1;
	}
	# endif
	{
		struct berval	cred;
		struct berval	*servcred;
		cred.bv_val = "secret";
		cred.bv_len = 6;
		rv = ldap_sasl_bind_s(gpLDAP, "cn=admin,dc=ucc,dc=gu,dc=uwa,dc=edu,dc=au",
			"", &cred, NULL, NULL, &servcred);
		if(rv) {
			fprintf(stderr, "ldap_start_tls_s: %s\n", ldap_err2string(rv));
			return 1;
		}
	}
	#endif
	
	return 0;
}
Esempio n. 9
0
static VALUE rldap_start_tls(VALUE obj)
{
	RLDAP_WRAP *wrapper;
	int retval;

	wrapper = get_wrapper(obj);
	retval = ldap_start_tls_s(wrapper->ld, NULL, NULL);
	if (retval == LDAP_SUCCESS)
		return Qtrue;
	else
		rldap_raise(retval);
}
Esempio n. 10
0
/** Create and return a new connection
 *
 * Create a new ldap connection and allocate memory for a new rlm_handle_t
 */
void *mod_conn_create(TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
{
	fr_ldap_rcode_t		status;
	fr_ldap_connection_t	*conn;
	fr_ldap_config_t const	*handle_config = instance;	/* Not talloced */

	conn = fr_ldap_connection_alloc(ctx);
	if (!conn) return NULL;

	if (fr_ldap_connection_configure(conn, handle_config) < 0) {
		talloc_free(conn);
		return NULL;
	}

	fr_ldap_connection_timeout_set(conn, timeout);
	if (handle_config->start_tls) {
		if (ldap_start_tls_s(conn->handle, NULL, NULL) != LDAP_SUCCESS) {
			int ldap_errno;

			ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);

			ERROR("Could not start TLS: %s", ldap_err2string(ldap_errno));

		error:
			talloc_free(conn);

			return NULL;
		}
	}

	status = fr_ldap_bind(NULL,
			      &conn,
			      conn->config->admin_identity, conn->config->admin_password,
			      &(conn->config->admin_sasl),
			      timeout,
			      NULL, NULL);
	if (status != LDAP_PROC_SUCCESS) goto error;
	fr_ldap_connection_timeout_reset(conn);

	/*
	 *	Only error out on memory allocation errors
	 */
	if (fr_ldap_directory_alloc(conn, &conn->directory, &conn) < 0) goto error;

	return conn;
}
Esempio n. 11
0
/** @brief Connect to a LDAP server.
  * @param uri Server to connect too.
  * @param starttls Starttls flags to disallow,allow or enforce SSL.
  * @param timelimit Query timelimit.
  * @param limit Results limit.
  * @param debug Set LDAP_OPT_DEBUG_LEVEL and LBER_OPT_DEBUG_LEVEL to this level.
  * @param err Pointer to a int that will contain the ldap error on failure.
  * @returns Reference to LDAP connection if its NULL the error is returned in err.*/
extern struct ldap_conn *ldap_connect(const char *uri, enum ldap_starttls starttls, int timelimit, int limit, int debug, int *err) {
	struct ldap_conn *ld;
	int version = 3;
	int res, sslres;
	struct timeval timeout;

	if (!(ld = objalloc(sizeof(*ld), free_ldapconn))) {
		return NULL;
	}

	ld->uri = strdup(uri);
	ld->sctrlsp = NULL;
	ld->timelim = timelimit;
	ld->limit = limit;
	ld->sasl = NULL;

	if ((res = ldap_initialize(&ld->ldap, ld->uri) != LDAP_SUCCESS)) {
		objunref(ld);
		ld = NULL;
	} else {
		if (debug) {
			ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debug);
			ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &debug);
		}
		if (timelimit) {
			timeout.tv_sec = timelimit;
			timeout.tv_usec = 0;
			ldap_set_option(ld->ldap, LDAP_OPT_NETWORK_TIMEOUT, (void *)&timeout);
		}
		ldap_set_option(ld->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
		ldap_set_option(ld->ldap, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_ON);
		ldap_set_rebind_proc(ld->ldap, ldap_rebind_proc, ld);

		if ((starttls != LDAP_STARTTLS_NONE) & !ldap_tls_inplace(ld->ldap) && (sslres = ldap_start_tls_s(ld->ldap, ld->sctrlsp, NULL))) {
			if (starttls == LDAP_STARTTLS_ENFORCE) {
				objunref(ld);
				ld = NULL;
				res = sslres;
			}
		}
	}
	*err = res;
	return ld;
}
Esempio n. 12
0
static int
_dico_conn_setup(struct _dico_ldap_handle *lp)
{
    int rc;
    LDAP *ld = NULL;
    int protocol = LDAP_VERSION3; /* FIXME: must be configurable */
  
    if (lp->debug) {
	if (ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &lp->debug)
	    != LBER_OPT_SUCCESS )
	    dico_log(L_ERR, 0, _("cannot set LBER_OPT_DEBUG_LEVEL %d"),
		     lp->debug);

	if (ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &lp->debug)
	    != LDAP_OPT_SUCCESS )
	    dico_log(L_ERR, 0, _("could not set LDAP_OPT_DEBUG_LEVEL %d"),
		     lp->debug);
    }


    rc = ldap_initialize(&ld, lp->url);
    if (rc != LDAP_SUCCESS) {
	dico_log(L_ERR, 0,
		 _("cannot create LDAP session handle for URI=%s (%d): %s"),
		 lp->url, rc, ldap_err2string(rc));
	return 1;
    }
  
    if (lp->tls) {
	rc = ldap_start_tls_s(ld, NULL, NULL);
	if (rc != LDAP_SUCCESS) {
	    dico_log(L_ERR, 0, _("ldap_start_tls failed: %s"),
		     ldap_err2string(rc));
	    return 1;
	}
    }

    ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol);

    /* FIXME: Timeouts, SASL, etc. */
    lp->ldap = ld;
    return 0;
}
Esempio n. 13
0
/* This function takes a ldap connection and 
 * tries to enable TLS on it.
*/
static int enable_tls_on(LDAP *conn) {
#if HAVE_LDAP_TLS
	int version;
	int ldrc;

	if (ldaperror(ldrc=ldap_get_option (conn,
				    LDAP_OPT_PROTOCOL_VERSION,
				    &version))
	    != LDAP_SUCCESS)
	{
		const char *s=ldap_err2string(ldrc);

#if	HAVE_SYSLOG_H
		syslog(LOG_DAEMON|LOG_CRIT,
		       "ldap_get_option failed: %s", s);
#endif
		return (-1);
	}

	if (version < LDAP_VERSION3)
	{
		version = LDAP_VERSION3;
		(void)ldap_set_option (conn,
				       LDAP_OPT_PROTOCOL_VERSION,
				       &version);
	}

	if (ldaperror(ldrc=ldap_start_tls_s(conn, NULL, NULL))
	    != LDAP_SUCCESS)
	{
		const char *s=ldap_err2string(ldrc);

#if	HAVE_SYSLOG_H
		syslog(LOG_DAEMON|LOG_CRIT,
		       "ldap_start_tls_s failed: %s", s);
#endif
		return (-1);
	}
	return 0;
#else
	return (-1);
#endif
}
static int
set_ldap_options(LD_session *session) {
	struct timeval timeout;
	int rc = 0;
	char logbuf[MAXLOGBUF];

	timeout.tv_sec = ldap_network_timeout;
	timeout.tv_usec = FALSE;
	ldap_set_option(session->sess, LDAP_OPT_PROTOCOL_VERSION, &ldap_protocol_version);
	ldap_set_option(session->sess, LDAP_OPT_NETWORK_TIMEOUT, &timeout);

	/* Start TLS if we need it*/
	if (ldap_authorization_tls) {
		if((rc = ldap_start_tls_s(session->sess, NULL,NULL))!=LDAP_SUCCESS)
		{
		    snprintf(logbuf, MAXLOGBUF, "Ldap start TLS error: %s. ", ldap_err2string(rc));	
		    ldap_log(LOG_WARNING, logbuf);
		}
	}
}
Esempio n. 15
0
/**
 * Handle APR_LDAP_OPT_TLS
 *
 * This function sets the type of TLS to be applied to this connection.
 * The options are:
 * APR_LDAP_NONE: no encryption
 * APR_LDAP_SSL: SSL encryption (ldaps://)
 * APR_LDAP_STARTTLS: STARTTLS encryption
 * APR_LDAP_STOPTLS: Stop existing TLS connecttion
 */
static void option_set_tls(apr_pool_t *pool, LDAP *ldap, const void *invalue,
                          apr_ldap_err_t *result)
{
#if APR_HAS_LDAP_SSL /* compiled with ssl support */

    int tls = * (const int *)invalue;

    /* Netscape/Mozilla/Solaris SDK */
#if APR_HAS_NETSCAPE_LDAPSDK || APR_HAS_SOLARIS_LDAPSDK || APR_HAS_MOZILLA_LDAPSK
#if APR_HAS_LDAPSSL_INSTALL_ROUTINES
    if (tls == APR_LDAP_SSL) {
        result->rc = ldapssl_install_routines(ldap);
#ifdef LDAP_OPT_SSL
        /* apparently Netscape and Mozilla need this too, Solaris doesn't */
        if (result->rc == LDAP_SUCCESS) {
            result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, LDAP_OPT_ON);
        }
#endif
        if (result->rc != LDAP_SUCCESS) {
            result->msg = ldap_err2string(result->rc);
            result->reason = "LDAP: Could not switch SSL on for this "
                             "connection.";
        }
    }
    else if (tls == APR_LDAP_STARTTLS) {
        result->reason = "LDAP: STARTTLS is not supported by the "
                         "Netscape/Mozilla/Solaris SDK";
        result->rc = -1;
    }
    else if (tls == APR_LDAP_STOPTLS) {
        result->reason = "LDAP: STOPTLS is not supported by the "
                         "Netscape/Mozilla/Solaris SDK";
        result->rc = -1;
    }
#else
    if (tls != APR_LDAP_NONE) {
        result->reason = "LDAP: SSL/TLS is not supported by this version "
                         "of the Netscape/Mozilla/Solaris SDK";
        result->rc = -1;
    }
#endif
#endif

    /* Novell SDK */
#if APR_HAS_NOVELL_LDAPSDK
    /* ldapssl_install_routines(ldap)
     * Behavior is unpredictable when other LDAP functions are called
     * between the ldap_init function and the ldapssl_install_routines
     * function.
     * 
     * STARTTLS is supported by the ldap_start_tls_s() method
     */
    if (tls == APR_LDAP_SSL) {
        result->rc = ldapssl_install_routines(ldap);
        if (result->rc != LDAP_SUCCESS) {
            result->msg = ldap_err2string(result->rc);
            result->reason = "LDAP: Could not switch SSL on for this "
                             "connection.";
        }
    }
    if (tls == APR_LDAP_STARTTLS) {
        result->rc = ldapssl_start_tls(ldap);
        if (result->rc != LDAP_SUCCESS) {
            result->msg = ldap_err2string(result->rc);
            result->reason = "LDAP: Could not start TLS on this connection";
        }
    }
    else if (tls == APR_LDAP_STOPTLS) {
        result->rc = ldapssl_stop_tls(ldap);
        if (result->rc != LDAP_SUCCESS) {
            result->msg = ldap_err2string(result->rc);
            result->reason = "LDAP: Could not stop TLS on this connection";
        }
    }
#endif

    /* OpenLDAP SDK */
#if APR_HAS_OPENLDAP_LDAPSDK
#ifdef LDAP_OPT_X_TLS
    if (tls == APR_LDAP_SSL) {
        int SSLmode = LDAP_OPT_X_TLS_HARD;
        result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS, &SSLmode);
        if (result->rc != LDAP_SUCCESS) {
            result->reason = "LDAP: ldap_set_option failed. "
                             "Could not set LDAP_OPT_X_TLS to "
                             "LDAP_OPT_X_TLS_HARD";
            result->msg = ldap_err2string(result->rc);
        }   
    }
    else if (tls == APR_LDAP_STARTTLS) {
        result->rc = ldap_start_tls_s(ldap, NULL, NULL);
        if (result->rc != LDAP_SUCCESS) {
            result->reason = "LDAP: ldap_start_tls_s() failed";
            result->msg = ldap_err2string(result->rc);
        }
    }
    else if (tls == APR_LDAP_STOPTLS) {
        result->reason = "LDAP: STOPTLS is not supported by the "
                         "OpenLDAP SDK";
        result->rc = -1;
    }
#else
    if (tls != APR_LDAP_NONE) {
        result->reason = "LDAP: SSL/TLS not yet supported by APR on this "
                         "version of the OpenLDAP toolkit";
        result->rc = -1;
    }
#endif
#endif

    /* Microsoft SDK */
#if APR_HAS_MICROSOFT_LDAPSDK
    if (tls == APR_LDAP_NONE) {
        ULONG ul = (ULONG) LDAP_OPT_OFF;
        result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, &ul);
        if (result->rc != LDAP_SUCCESS) {
            result->reason = "LDAP: an attempt to set LDAP_OPT_SSL off "
                             "failed.";
            result->msg = ldap_err2string(result->rc);
        }
    }
    else if (tls == APR_LDAP_SSL) {
        ULONG ul = (ULONG) LDAP_OPT_ON;
        result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, &ul);
        if (result->rc != LDAP_SUCCESS) {
            result->reason = "LDAP: an attempt to set LDAP_OPT_SSL on "
                             "failed.";
            result->msg = ldap_err2string(result->rc);
        }
    }
#if APR_HAS_LDAP_START_TLS_S
    else if (tls == APR_LDAP_STARTTLS) {
        result->rc = ldap_start_tls_s(ldap, NULL, NULL, NULL, NULL);
        if (result->rc != LDAP_SUCCESS) {
            result->reason = "LDAP: ldap_start_tls_s() failed";
            result->msg = ldap_err2string(result->rc);
        }
    }
    else if (tls == APR_LDAP_STOPTLS) {
        result->rc = ldap_stop_tls_s(ldap);
        if (result->rc != LDAP_SUCCESS) {
            result->reason = "LDAP: ldap_stop_tls_s() failed";
            result->msg = ldap_err2string(result->rc);
        }
    }
#endif
#endif

#if APR_HAS_OTHER_LDAPSDK
    if (tls != APR_LDAP_NONE) {
        result->reason = "LDAP: SSL/TLS is currently not supported by "
                         "APR on this LDAP SDK";
        result->rc = -1;
    }
#endif

#endif /* APR_HAS_LDAP_SSL */

}
Esempio n. 16
0
void
OPENLDAP::Book::refresh_start ()
{
  int msgid = -1;
  int result = LDAP_SUCCESS;
  int ldap_version = LDAP_VERSION3;

  status = std::string (_("Refreshing"));
  updated (this->shared_from_this ());

  result = ldap_initialize (&ldap_context, bookinfo.uri_host.c_str());
  if (result != LDAP_SUCCESS) {

    status = std::string (_("Could not initialize server"));
    updated (this->shared_from_this ());
    return;
  }

  /* the openldap code shows I don't have to check the result of this
   * (see for example tests/prog/slapd-search.c)
   */
  (void)ldap_set_option (ldap_context,
			 LDAP_OPT_PROTOCOL_VERSION, &ldap_version);

  if (bookinfo.starttls) {
    result = ldap_start_tls_s (ldap_context, NULL, NULL);
    if (result != LDAP_SUCCESS) {
      status = std::string (_("LDAP Error: ")) +
        std::string (ldap_err2string (result));
      updated (this->shared_from_this ());
      ldap_unbind_ext (ldap_context, NULL, NULL);
      ldap_context = NULL;
      return;
    }
  }

  if (bookinfo.sasl) {
    interctx ctx;

    ctx.book = this;
    ctx.authcID = bookinfo.authcID;
    ctx.password = bookinfo.password;
    result = ldap_sasl_interactive_bind_s (ldap_context, NULL,
					   bookinfo.saslMech.c_str(), NULL, NULL, LDAP_SASL_QUIET,
					   book_saslinter, &ctx);

  } else {
    /* Simple Bind */
    if (bookinfo.password.empty ()) {
      struct berval bv={0,NULL};

      result = ldap_sasl_bind (ldap_context, NULL,
			       LDAP_SASL_SIMPLE, &bv,
			       NULL, NULL,
			       &msgid);
    } else {

      struct berval passwd = { 0, NULL };
      passwd.bv_val = g_strdup (bookinfo.password.c_str ());
      passwd.bv_len = bookinfo.password.length();

      result = ldap_sasl_bind (ldap_context, bookinfo.authcID.c_str(),
			       LDAP_SASL_SIMPLE, &passwd,
			       NULL, NULL,
			       &msgid);

      g_free (passwd.bv_val);
    }
  }

  if (result != LDAP_SUCCESS) {

    status = std::string (_("LDAP Error: ")) +
      std::string (ldap_err2string (result));
    updated (this->shared_from_this ());

    ldap_unbind_ext (ldap_context, NULL, NULL);
    ldap_context = NULL;
    return;
  }

  status = std::string (_("Contacted server"));
  updated (this->shared_from_this ());

  patience = 3;
  refresh_bound ();
}
static void
ldapconnect(void)
{
    int rc;

/* On Windows ldap_start_tls_s is available starting from Windows XP, 
 * so we need to bind at run-time with the function entry point
 */
#ifdef _SQUID_MSWIN_
    if (use_tls) {

	HMODULE WLDAP32Handle;

	WLDAP32Handle = GetModuleHandle("wldap32");
	if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) {
	    fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n");
	    exit(1);
	}
    }
#endif

    if (ld == NULL) {
#if HAS_URI_SUPPORT
	if (strstr(ldapServer, "://") != NULL) {
	    rc = ldap_initialize(&ld, ldapServer);
	    if (rc != LDAP_SUCCESS) {
		fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer);
	    }
	} else
#endif
#if NETSCAPE_SSL
	if (sslpath) {
	    if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) {
		fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n",
		    sslpath);
		exit(1);
	    } else {
		sslinit++;
	    }
	    if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) {
		fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n",
		    ldapServer, port);
		exit(1);
	    }
	} else
#endif
	if ((ld = ldap_init(ldapServer, port)) == NULL) {
	    fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port);
	}
	if (connect_timeout)
	    squid_ldap_set_connect_timeout(connect_timeout);

#ifdef LDAP_VERSION3
	if (version == -1) {
	    version = LDAP_VERSION2;
	}
	if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version)
	    != LDAP_SUCCESS) {
	    fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
		version);
	    ldap_unbind(ld);
	    ld = NULL;
	}
	if (use_tls) {
#ifdef LDAP_OPT_X_TLS
	    if ((version == LDAP_VERSION3) && (ldap_start_tls_s(ld, NULL, NULL) == LDAP_SUCCESS)) {
		fprintf(stderr, "Could not Activate TLS connection\n");
		ldap_unbind(ld);
		ld = NULL;
	    }
#else
	    fprintf(stderr, "TLS not supported with your LDAP library\n");
	    ldap_unbind(ld);
	    ld = NULL;
#endif
	}
#endif
	squid_ldap_set_timelimit(timelimit);
	squid_ldap_set_referrals(!noreferrals);
	squid_ldap_set_aliasderef(aliasderef);
	if (binddn && bindpasswd && *binddn && *bindpasswd) {
	    rc = ldap_simple_bind_s(ld, binddn, bindpasswd);
	    if (rc != LDAP_SUCCESS) {
		fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc));
		ldap_unbind(ld);
		ld = NULL;
	    }
	}
	if (debug)
	    fprintf(stderr, "Connected OK\n");
    }
}
Esempio n. 18
0
handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
#ifdef USE_LDAP
			int ret;
			struct berval credentials;
			char *binddn_ptr = NULL;

			if (s->auth_ldap_filter->used) {
				char *dollar;

				/* parse filter */

				if (NULL == (dollar = strchr(s->auth_ldap_filter->ptr, '$'))) {
					log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.filter is missing a replace-operator '$'");

					return HANDLER_ERROR;
				}

				buffer_copy_string_len(s->ldap->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr);
				buffer_copy_string(s->ldap->ldap_filter_post, dollar+1);
			}

			if (s->auth_ldap_url->used) {
				if ((ret = ldap_initialize(&s->ldap->ldap, s->auth_ldap_url->ptr))) {
					log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

					return HANDLER_ERROR;
				}

				{
					const int ldap_version = LDAP_VERSION3;
					ret = ldap_set_option(s->ldap->ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
				}
				if (ret != LDAP_OPT_SUCCESS) {
					log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

					ldap_memfree(s->ldap->ldap);
					s->ldap->ldap = NULL;

					return HANDLER_ERROR;
				}

				if (s->auth_ldap_starttls == 1) {
					/* if no CA file is given, it is ok, as we will use encryption
					 * if the server requires a CAfile it will tell us */
					if (!buffer_is_empty(s->auth_ldap_cafile)) {
						if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
										s->auth_ldap_cafile->ptr))) {
							log_error_write(srv, __FILE__, __LINE__, "ss",
									"Loading CA certificate failed:", ldap_err2string(ret));

							ldap_memfree(s->ldap->ldap);
							s->ldap->ldap = NULL;

							return HANDLER_ERROR;
						}
					}

					if (!buffer_is_empty(s->auth_ldap_cert)) {
						if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE,
										s->auth_ldap_cert->ptr))) {
							log_error_write(srv, __FILE__, __LINE__, "ss",
									"Loading TLS certificate failed:", ldap_err2string(ret));

							ldap_memfree(s->ldap->ldap);
							s->ldap->ldap = NULL;

							return HANDLER_ERROR;
						}
					}

					if (!buffer_is_empty(s->auth_ldap_key)) {
						if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE,
										s->auth_ldap_key->ptr))) {
							log_error_write(srv, __FILE__, __LINE__, "ss",
									"Loading TLS key certificate failed:", ldap_err2string(ret));

							ldap_memfree(s->ldap->ldap);
							s->ldap->ldap = NULL;

							return HANDLER_ERROR;
						}
					}

					if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap->ldap, NULL,  NULL))) {
						log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));

						ldap_memfree(s->ldap->ldap);
						s->ldap->ldap = NULL;

						return HANDLER_ERROR;
					}
				}


				/* 1. */
				if (s->auth_ldap_binddn->used) {
					credentials.bv_val = s->auth_ldap_bindpw->ptr;
					credentials.bv_len = s->auth_ldap_bindpw->used;
					binddn_ptr = s->auth_ldap_binddn->ptr;
				} else {
					credentials.bv_val = NULL;
					credentials.bv_len = 0;
					binddn_ptr = NULL;
				}
				ret = ldap_sasl_bind_s(s->ldap->ldap, s->auth_ldap_binddn->ptr, LDAP_SASL_SIMPLE, &credentials, NULL, NULL, NULL);
				if(ret != LDAP_SUCCESS) {
					log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

					ldap_memfree(s->ldap->ldap);
					s->ldap->ldap = NULL;
					return HANDLER_ERROR;
				}
			}
#else
			UNUSED(s);
			log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available");
			return HANDLER_ERROR;
#endif
		return HANDLER_GO_ON;
}
Esempio n. 19
0
/**
LDAP*  open_ldap_connection(char* fn)

設定ファイルを読み込み後,LDAPサーバに接続する

@param  fn  設定の格納されたファイル名.fn, /etc/openldap/ldap.conf, /etc/ldap.conf
            を順に読んで大域変数 JBXLdapHost, JBXLdapDnBind に情報を格納する.

@return LDAPサーバへのセッションハンドラ.接続に失敗した場合は NULL

*/
LDAP*  open_ldap_connection(char* fn)
{
    if (JBXLdapHost==NULL||JBXLdapDnBind==NULL||fn!=NULL) read_ldap_config_file(fn);
    if (JBXLdapHost==NULL||JBXLdapDnBind==NULL) return NULL;
    if (JBXLdapDnBind->dnbind.buf==NULL)        return NULL;
    if (JBXLdapDnBind->passwd.buf==NULL)	    return NULL;
    if (JBXLdapDnBind->passwd.buf[0]=='\0')     return NULL;
    if (JBXLdapHost->hostname.buf==NULL)        return NULL;
    if (JBXLdapHost->port<=0) return NULL;

    int ret;
    LDAP* ld = NULL;

    if (JBXLdapHost->useSSL!=TRUE || JBXLdapHost->port==389) {
        DEBUG_MODE print_message("INFO LDAP NORMAL Mode\n");
        ld = ldap_init((char*)JBXLdapHost->hostname.buf, JBXLdapHost->port);
        if (ld==NULL) {
            DEBUG_MODE print_message("ERR  LDAP Init error.\n");
            return NULL;
        }

        if (JBXLdapHost->useSSL==TRUE) {	// STARTTLS (動作未確認)
            DEBUG_MODE print_message("INFO LDAP STARTTLS Mode\n");
            ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &JBXLdapHost->reqCert);
            if (ret!=LDAP_SUCCESS) {
                DEBUG_MODE print_message("ERR  LDAP STARTTLS Require Cert = %s\n", ldap_err2string(ret));
                ldap_unbind_s(ld);
                return NULL;
            }

            int ldap_vers = LDAP_VERSION3;
            ret = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_vers);
            if (ret!=LDAP_SUCCESS) {
                DEBUG_MODE print_message("ERR  LDAP STARTTLS Version = %s\n", ldap_err2string(ret));
                ldap_unbind_s(ld);
                return NULL;
            }
            //
            ret = ldap_start_tls_s(ld, NULL, NULL);
            if (ret!=LDAP_SUCCESS) {
                DEBUG_MODE print_message("ERR  LDAP STARTTLS Start = %s\n", ldap_err2string(ret));
                ldap_unbind_s(ld);
                return NULL;
            }
        }
    }
    //
    else {			// LDAP over SSL
        DEBUG_MODE print_message("INFO LDAP Over SSL Mode\n");
        Buffer url = make_Buffer_bystr("ldaps://");
        cat_Buffer(&JBXLdapHost->hostname, &url);
        cat_s2Buffer(":", &url);
        cat_s2Buffer(itostr(JBXLdapHost->port), &url);
        DEBUG_MODE print_message("INFO LDAP SSL URL = %s\n", (char*)url.buf);
        //
        ret = ldap_initialize(&ld, (char*)url.buf);
        free_Buffer(&url);
        if (ret!=LDAP_SUCCESS) {
            DEBUG_MODE print_message("ERR  LDAP SSL Init = %s\n", ldap_err2string(ret));
            return NULL;
        }
        //
        ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &JBXLdapHost->reqCert);
        if (ret!=LDAP_SUCCESS) {
            DEBUG_MODE print_message("ERR  LDAP SSL Require Cert = %s\n", ldap_err2string(ret));
            ldap_unbind_s(ld);
            return NULL;
        }
    }

    ret = ldap_simple_bind_s(ld, (char*)JBXLdapDnBind->dnbind.buf, (char*)JBXLdapDnBind->passwd.buf);
    if (ret!=LDAP_SUCCESS) {
        DEBUG_MODE print_message("ERR  LDAP Bind = %s\n", ldap_err2string(ret));
        ldap_unbind_s(ld);
        return NULL;
    }

    return ld;
}
Esempio n. 20
0
int
main (int argc, char *argv[])
{

	LDAP *ld;
	LDAPMessage *result;

	/* should be 	int result = STATE_UNKNOWN; */

	int status = STATE_UNKNOWN;
	long microsec;
	double elapsed_time;

	/* for ldap tls */

	int tls;
	int version=3;

	/* for entry counting */

	LDAPMessage *next_entry;
	int status_entries = STATE_OK;
	int num_entries = 0;

	setlocale (LC_ALL, "");
	bindtextdomain (PACKAGE, LOCALEDIR);
	textdomain (PACKAGE);

	if (strstr(argv[0],"check_ldaps")) {
		xasprintf (&progname, "check_ldaps");
 	}

	/* Parse extra opts if any */
	argv=np_extra_opts (&argc, argv, progname);

	if (process_arguments (argc, argv) == ERROR)
		usage4 (_("Could not parse arguments"));

	if (strstr(argv[0],"check_ldaps") && ! starttls && ! ssl_on_connect)
		starttls = TRUE;

	/* initialize alarm signal handling */
	signal (SIGALRM, socket_timeout_alarm_handler);

	/* set socket timeout */
	alarm (timeout_interval);

	/* get the start time */
	gettimeofday (&tv, NULL);

	/* initialize ldap */
	if (ld_uri != NULL)
	{
#ifdef HAVE_LDAP_INITIALIZE
		int result = ldap_initialize(&ld, ld_uri);
		if (result != LDAP_SUCCESS)
		{
			printf ("Failed to connect to LDAP server at %s: %s\n",
				ld_uri, ldap_err2string(result));
			return STATE_CRITICAL;
		}
#else
		printf ("Sorry, this version of %s was compiled without URI support!\n",
			argv[0]);
		return STATE_CRITICAL;
#endif
	}
#ifdef HAVE_LDAP_INIT
	else if (!(ld = ldap_init (ld_host, ld_port))) {
		printf ("Could not connect to the server at port %i\n", ld_port);
		return STATE_CRITICAL;
	}
#else
	else if (!(ld = ldap_open (ld_host, ld_port))) {
		if (verbose)
			ldap_perror(ld, "ldap_open");
		printf (_("Could not connect to the server at port %i\n"), ld_port);
		return STATE_CRITICAL;
	}
#endif /* HAVE_LDAP_INIT */

#ifdef HAVE_LDAP_SET_OPTION
	/* set ldap options */
	if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &ld_protocol) !=
			LDAP_OPT_SUCCESS ) {
		printf(_("Could not set protocol version %d\n"), ld_protocol);
		return STATE_CRITICAL;
	}
#endif

	if (ld_port == LDAPS_PORT || ssl_on_connect) {
		xasprintf (&SERVICE, "LDAPS");
#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
		/* ldaps: set option tls */
		tls = LDAP_OPT_X_TLS_HARD;

		if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
		{
			if (verbose)
				ldap_perror(ld, "ldaps_option");
			printf (_("Could not init TLS at port %i!\n"), ld_port);
			return STATE_CRITICAL;
		}
#else
		printf (_("TLS not supported by the libraries!\n"));
		return STATE_CRITICAL;
#endif /* LDAP_OPT_X_TLS */
	} else if (starttls) {
		xasprintf (&SERVICE, "LDAP-TLS");
#if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S)
		/* ldap with startTLS: set option version */
		if (ldap_get_option(ld,LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS )
		{
			if (version < LDAP_VERSION3)
			{
				version = LDAP_VERSION3;
				ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
			}
		}
		/* call start_tls */
		if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS)
		{
			if (verbose)
				ldap_perror(ld, "ldap_start_tls");
			printf (_("Could not init startTLS at port %i!\n"), ld_port);
			return STATE_CRITICAL;
		}
#else
		printf (_("startTLS not supported by the library, needs LDAPv3!\n"));
		return STATE_CRITICAL;
#endif /* HAVE_LDAP_START_TLS_S */
	}

	/* bind to the ldap server */
	if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) !=
			LDAP_SUCCESS) {
		if (verbose)
			ldap_perror(ld, "ldap_bind");
		printf (_("Could not bind to the LDAP server\n"));
		return STATE_CRITICAL;
	}

	/* do a search of all objectclasses in the base dn */
	if (ldap_search_s (ld, ld_base, (crit_entries!=NULL || warn_entries!=NULL) ? LDAP_SCOPE_SUBTREE : LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result)
			!= LDAP_SUCCESS) {
		if (verbose)
			ldap_perror(ld, "ldap_search");
		printf (_("Could not search/find objectclasses in %s\n"), ld_base);
		return STATE_CRITICAL;
	} else if (crit_entries!=NULL || warn_entries!=NULL) {
		num_entries = ldap_count_entries(ld, result);
	}

	/* unbind from the ldap server */
	ldap_unbind (ld);

	/* reset the alarm handler */
	alarm (0);

	/* calcutate the elapsed time and compare to thresholds */

	microsec = deltime (tv);
	elapsed_time = (double)microsec / 1.0e6;

	if (crit_time!=UNDEFINED && elapsed_time>crit_time)
		status = STATE_CRITICAL;
	else if (warn_time!=UNDEFINED && elapsed_time>warn_time)
		status = STATE_WARNING;
	else
		status = STATE_OK;

	if(entries_thresholds != NULL) {
		if (verbose) {
			printf ("entries found: %d\n", num_entries);
			print_thresholds("entry threasholds", entries_thresholds);
		}
		status_entries = get_status(num_entries, entries_thresholds);
		if (status_entries == STATE_CRITICAL) {
			status = STATE_CRITICAL;
		} else if (status != STATE_CRITICAL) {
			status = status_entries;
		}
	}

	/* print out the result */
	if (crit_entries!=NULL || warn_entries!=NULL) {
		printf (_("LDAP %s - found %d entries in %.3f seconds|%s %s\n"),
			state_text (status),
			num_entries,
			elapsed_time,
			fperfdata ("time", elapsed_time, "s",
				(int)warn_time, warn_time,
				(int)crit_time, crit_time,
				TRUE, 0, FALSE, 0),
			sperfdata ("entries", (double)num_entries, "",
				warn_entries,
				crit_entries,
				TRUE, 0.0, FALSE, 0.0));
	} else {
		printf (_("LDAP %s - %.3f seconds response time|%s\n"),
			state_text (status),
			elapsed_time,
			fperfdata ("time", elapsed_time, "s",
				(int)warn_time, warn_time,
				(int)crit_time, crit_time,
				TRUE, 0, FALSE, 0));
	}

	return status;
}
Esempio n. 21
0
handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
#ifdef USE_LDAP
	int ret;
#if 0
	if (s->auth_ldap_basedn->used == 0) {
		log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set");

		return HANDLER_ERROR;
	}
#endif

	if (s->auth_ldap_hostname->used) {
		/* free old context */
		if (NULL != s->ldap) ldap_unbind_s(s->ldap);

		if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) {
			log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));

			return HANDLER_ERROR;
		}

		ret = LDAP_VERSION3;
		if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
			log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

			return HANDLER_ERROR;
		}

		if (s->auth_ldap_starttls) {
			/* if no CA file is given, it is ok, as we will use encryption
				* if the server requires a CAfile it will tell us */
			if (!buffer_is_empty(s->auth_ldap_cafile)) {
				if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
								s->auth_ldap_cafile->ptr))) {
					log_error_write(srv, __FILE__, __LINE__, "ss",
							"Loading CA certificate failed:", ldap_err2string(ret));

					return HANDLER_ERROR;
				}
			}

			if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL,  NULL))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));

				return HANDLER_ERROR;
			}
		}


		/* 1. */
		if (s->auth_ldap_binddn->used) {
			if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

				return HANDLER_ERROR;
			}
		} else {
			if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

				return HANDLER_ERROR;
			}
		}
	}
	return HANDLER_GO_ON;
#else
	UNUSED(s);
	log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available");
	return HANDLER_ERROR;
#endif
}
Esempio n. 22
0
static int
libbalsa_address_book_ldap_open_connection(LibBalsaAddressBookLdap * ab)
{
    int result;
    static const int version = LDAP_VERSION3;
    gboolean v3_enabled;
    LibBalsaAddressBook *lbab = LIBBALSA_ADDRESS_BOOK(ab);

    g_return_val_if_fail(ab->host != NULL, FALSE);

    ldap_initialize(&ab->directory, ab->host);
    if (ab->directory == NULL) { /* very unlikely... */
        libbalsa_address_book_set_status(lbab, g_strdup("Host not found"));
	return LDAP_SERVER_DOWN;
    }
    /* ignore error if the V3 LDAP cannot be set */
    v3_enabled = 
        ldap_set_option(ab->directory, LDAP_OPT_PROTOCOL_VERSION, &version)
       == LDAP_OPT_SUCCESS;
    if(!v3_enabled) printf("Too old LDAP server - interaction may fail.\n");
    if(v3_enabled && ab->enable_tls) {
#ifdef HAVE_LDAP_TLS
        /* turn TLS on  but what if we have SSL already on? */
        result = ldap_start_tls_s(ab->directory, NULL, NULL);
        if(result != LDAP_SUCCESS) {
            ldap_unbind_ext(ab->directory, NULL, NULL);
            ab->directory = NULL;
            libbalsa_address_book_set_status
                (lbab, g_strdup(ldap_err2string(result)));
            return result;
        }
#else /* HAVE_LDAP_TLS */
     libbalsa_address_book_set_status(lbab,
                                      _("TLS requested but not compiled in"));
     return LDAP_INAPPRIOPRIATE_AUTH;
#endif /* HAVE_LDAP_TLS */
    }

#ifdef HAVE_CYRUS_SASL
    result = ldap_sasl_interactive_bind_s(ab->directory, ab->bind_dn, NULL,
                                          NULL, NULL,
                                          LDAP_SASL_QUIET, abl_interact, ab);
#else /* HAVE_CYRUS_SASL */
    {
     struct berval   cred;   
     cred.bv_val = ab->passwd;
     cred.bv_len = ab->passwd ? strlen(ab->passwd) : 0;
     result = ldap_sasl_bind_s(ab->directory, ab->bind_dn, NULL, &cred,
                              NULL, NULL, NULL);
    }
#endif /* HAVE_CYRUS_SASL */

    /* do not follow referrals (OpenLDAP binds anonymously here, which will usually
     * fail */
    if (result == LDAP_SUCCESS)
	result = ldap_set_option(ab->directory, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF);

    if (result != LDAP_SUCCESS) {
        libbalsa_address_book_set_status(lbab,
                                         g_strdup(ldap_err2string(result)));
	ldap_unbind_ext(ab->directory, NULL, NULL);
	ab->directory = NULL;
    }
    return result;
}
Esempio n. 23
0
void run_ldap_tests(service_t *ldaptest, int sslcertcheck, int querytimeout)
{
#ifdef HAVE_LDAP
	ldap_data_t *req;
	testitem_t *t;
	struct timespec starttime;
	struct timespec endtime;

	/* Pick a sensible default for the timeout setting */
	if (querytimeout == 0) querytimeout = 30;

	for (t = ldaptest->items; (t); t = t->next) {
		LDAPURLDesc	*ludp;
		LDAP		*ld;
		int		rc, finished;
		int		msgID = -1;
		struct timeval	ldaptimeout;
		struct timeval	openldaptimeout;
		LDAPMessage	*result;
		LDAPMessage	*e;
		strbuffer_t	*response;
		char		buf[MAX_LINE_LEN];

		req = (ldap_data_t *) t->privdata;
		if (req->skiptest) continue;

		ludp = (LDAPURLDesc *) req->ldapdesc;

		getntimer(&starttime);

		/* Initiate session with the LDAP server */
		dbgprintf("Initiating LDAP session for host %s port %d\n",
			ludp->lud_host, ludp->lud_port);

		if( (ld = ldap_init(ludp->lud_host, ludp->lud_port)) == NULL ) {
			dbgprintf("ldap_init failed\n");
			req->ldapstatus = XYMON_LDAP_INITFAIL;
			continue;
		}

		/* 
		 * There is apparently no standard way of defining a network
		 * timeout for the initial connection setup. 
		 */
#if (LDAP_VENDOR == OpenLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT)
		/* 
		 * OpenLDAP has an undocumented ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv)
		 */
		openldaptimeout.tv_sec = querytimeout;
		openldaptimeout.tv_usec = 0;
		ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &openldaptimeout);
#else
		/*
		 * So using an alarm() to interrupt any pending operations
		 * seems to be the least insane way of doing this.
		 *
		 * Note that we must do this right after ldap_init(), as
		 * any operation on the session handle (ld) may trigger the
		 * network connection to be established.
		 */
		connect_timeout = 0;
		signal(SIGALRM, ldap_alarmhandler);
		alarm(querytimeout);
#endif

		/*
		 * This is completely undocumented in the OpenLDAP docs.
		 * But apparently it is documented in 
		 * http://www.ietf.org/proceedings/99jul/I-D/draft-ietf-ldapext-ldap-c-api-03.txt
		 *
		 * Both of these routines appear in the <ldap.h> file 
		 * from OpenLDAP 2.1.22. Their use to enable TLS has
		 * been deciphered from the ldapsearch() utility
		 * sourcecode.
		 *
		 * According to Manon Goo <*****@*****.**>, recent (Jan. 2005)
		 * OpenLDAP implementations refuse to talk LDAPv2.
		 */
#ifdef LDAP_OPT_PROTOCOL_VERSION 
		{
			int protocol = LDAP_VERSION3;

			dbgprintf("Attempting to select LDAPv3\n");
			if ((rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) {
				dbgprintf("Failed to select LDAPv3, trying LDAPv2\n");
				protocol = LDAP_VERSION2;
				if ((rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) {
					req->output = strdup(ldap_err2string(rc));
					req->ldapstatus = XYMON_LDAP_TLSFAIL;
				}
				continue;
			}
		}
#endif

		if (req->usetls) {
			dbgprintf("Trying to enable TLS for session\n");
			if ((rc = ldap_start_tls_s(ld, NULL, NULL)) != LDAP_SUCCESS) {
				dbgprintf("ldap_start_tls failed\n");
				req->output = strdup(ldap_err2string(rc));
				req->ldapstatus = XYMON_LDAP_TLSFAIL;
				continue;
			}
		}

		if (!connect_timeout) {
			msgID = ldap_simple_bind(ld, (t->host->ldapuser ? t->host->ldapuser : ""), 
					 (t->host->ldappasswd ? t->host->ldappasswd : ""));
		}

		/* Cancel any pending alarms */
		alarm(0);
		signal(SIGALRM, SIG_DFL);

		/* Did we connect? */
		if (connect_timeout || (msgID == -1)) {
			req->ldapstatus = XYMON_LDAP_BINDFAIL;
			req->output = "Cannot connect to server";
			continue;
		}

		/* Wait for bind to complete */
		rc = 0; finished = 0; 
		ldaptimeout.tv_sec = querytimeout;
		ldaptimeout.tv_usec = 0L;
		while( ! finished ) {
			int rc2;

			rc = ldap_result(ld, msgID, LDAP_MSG_ONE, &ldaptimeout, &result);
			dbgprintf("ldap_result returned %d for ldap_simple_bind()\n", rc);
			if(rc == -1) {
				finished = 1;
				req->ldapstatus = XYMON_LDAP_BINDFAIL;

				if (result == NULL) {
					errprintf("LDAP library problem - NULL result returned\n");
					req->output = strdup("LDAP BIND failed\n");
				}
				else {
					rc2 = ldap_result2error(ld, result, 1);
					req->output = strdup(ldap_err2string(rc2));
				}
				ldap_unbind(ld);
			}
			else if (rc == 0) {
				finished = 1;
				req->ldapstatus = XYMON_LDAP_BINDFAIL;
				req->output = strdup("Connection timeout");
				ldap_unbind(ld);
			}
			else if( rc > 0 ) {
				finished = 1;
				if (result == NULL) {
					errprintf("LDAP library problem - got a NULL resultcode for status %d\n", rc);
					req->ldapstatus = XYMON_LDAP_BINDFAIL;
					req->output = strdup("LDAP library problem: ldap_result2error returned a NULL result for status %d\n");
					ldap_unbind(ld);
				}
				else {
					rc2 = ldap_result2error(ld, result, 1);
					if(rc2 != LDAP_SUCCESS) {
						req->ldapstatus = XYMON_LDAP_BINDFAIL;
						req->output = strdup(ldap_err2string(rc));
						ldap_unbind(ld);
					}
				}
			}
		} /* ... while() */

		/* We're done connecting. If something went wrong, go to next query. */
		if (req->ldapstatus != 0) continue;

		/* Now do the search. With a timeout */
		ldaptimeout.tv_sec = querytimeout;
		ldaptimeout.tv_usec = 0L;
		rc = ldap_search_st(ld, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, &ldaptimeout, &result);

		if(rc == LDAP_TIMEOUT) {
			req->ldapstatus = XYMON_LDAP_TIMEOUT;
			req->output = strdup(ldap_err2string(rc));
	  		ldap_unbind(ld);
			continue;
		}
		if( rc != LDAP_SUCCESS ) {
			req->ldapstatus = XYMON_LDAP_SEARCHFAILED;
			req->output = strdup(ldap_err2string(rc));
	  		ldap_unbind(ld);
			continue;
		}

		getntimer(&endtime);

		response = newstrbuffer(0);
		sprintf(buf, "Searching LDAP for %s yields %d results:\n\n", 
			t->testspec, ldap_count_entries(ld, result));
		addtobuffer(response, buf);

		for(e = ldap_first_entry(ld, result); (e != NULL); e = ldap_next_entry(ld, e) ) {
			char 		*dn;
			BerElement	*ber;
			char		*attribute;
			char		**vals;

			dn = ldap_get_dn(ld, e);
			sprintf(buf, "DN: %s\n", dn); 
			addtobuffer(response, buf);

			/* Addtributes and values */
			for (attribute = ldap_first_attribute(ld, e, &ber); (attribute != NULL); attribute = ldap_next_attribute(ld, e, ber) ) {
				if ((vals = ldap_get_values(ld, e, attribute)) != NULL) {
					int i;

					for(i = 0; (vals[i] != NULL); i++) {
						sprintf(buf, "\t%s: %s\n", attribute, vals[i]);
						addtobuffer(response, buf);
					}
				}
				/* Free memory used to store values */
				ldap_value_free(vals);
			}

			/* Free memory used to store attribute */
			ldap_memfree(attribute);
			ldap_memfree(dn);
			if (ber != NULL) ber_free(ber, 0);

			addtobuffer(response, "\n");
		}
		req->ldapstatus = XYMON_LDAP_OK;
		req->output = grabstrbuffer(response);
		tvdiff(&starttime, &endtime, &req->duration);

		ldap_msgfree(result);
		ldap_unbind(ld);
		ldap_free_urldesc(ludp);
	}
#endif
}
Esempio n. 24
0
int ld_con_connect(db_con_t* con)
{
	struct ld_con* lcon;
	struct ld_uri* luri;
	int ret, version = 3;
	char* err_str = NULL;

	lcon = DB_GET_PAYLOAD(con);
	luri = DB_GET_PAYLOAD(con->uri);

	/* Do not reconnect already connected connections */
	if (lcon->flags & LD_CONNECTED) return 0;

	DBG("ldap: Connecting to %s\n", luri->uri);

	if (lcon->con) {
		ret = ldap_unbind_ext_s(lcon->con, NULL, NULL);
		if (ret != LDAP_SUCCESS) {
			ERR("ldap: Error while unbinding from %s: %s\n",
				luri->uri, ldap_err2string(ret));
		}
	}

	/* we pass the TLS_REQCERT and TLS_REQCERT attributes over environment
	   variables to ldap library */
	if (luri->tls) {
		if (setenv("LDAPTLS_CACERT", luri->ca_list, 1)) {
			ERR("ldap: Can't set environment variable 'LDAPTLS_CACERT'\n");
			goto error;
		}
		if (setenv("LDAPTLS_REQCERT", luri->req_cert, 1)) {
			ERR("ldap: Can't set environment variable 'LDAPTLS_REQCERT'\n");
			goto error;
		}
	}

	ret = ldap_initialize(&lcon->con, luri->uri);
	if (lcon->con == NULL) {
		ERR("ldap: Error while initializing new LDAP connection to %s\n",
			luri->uri);
		goto error;
	}

	ret = ldap_set_option(lcon->con, LDAP_OPT_PROTOCOL_VERSION, &version);
	if (ret != LDAP_OPT_SUCCESS) {
		ERR("ldap: Error while setting protocol version 3: %s\n",
			ldap_err2string(ret));
		goto error;
	}

	if (luri->tls) {
		ret = ldap_start_tls_s(lcon->con, NULL, NULL);
		if (ret != LDAP_SUCCESS) {
			/* get addition info of this error */
#ifdef OPENLDAP23
			ldap_get_option(lcon->con, LDAP_OPT_ERROR_STRING, &err_str);
#elif OPENLDAP24
			ldap_get_option(lcon->con, LDAP_OPT_DIAGNOSTIC_MESSAGE, &err_str);
#endif
			ERR("ldap: Error while starting TLS: %s\n", ldap_err2string(ret));
			if (err_str) {
				ERR("ldap: %s\n", err_str);
				ldap_memfree(err_str);
			}
			goto error;
		}
	}

	switch (luri->authmech) {
		case LDAP_AUTHMECH_NONE:
			ret = ldap_simple_bind_s(lcon->con, NULL, NULL);
			break;
		case LDAP_AUTHMECH_SIMPLE:
			ret = ldap_simple_bind_s(lcon->con, luri->username, luri->password);
			break;
		case LDAP_AUTHMECH_DIGESTMD5:
			ret = ldap_sasl_interactive_bind_s( lcon->con, NULL,
					LDAP_MECHANISM_STR_DIGESTMD5, NULL, NULL,
					0, lutil_sasl_interact, luri );
			break;
		case LDAP_AUTHMECH_EXTERNAL:
		default:
			ret = !LDAP_SUCCESS;
			break;
	}

	if (ret != LDAP_SUCCESS) {
		ERR("ldap: Bind to %s failed: %s\n",
			luri->uri, ldap_err2string(ret));
		goto error;
	}

	DBG("ldap: Successfully bound to %s\n", luri->uri);
	lcon->flags |= LD_CONNECTED;
	return 0;

 error:
	if (lcon->con) {
		ret = ldap_unbind_ext_s(lcon->con, NULL, NULL);
		if (ret) {
			ERR("ldap: Error while unbinding from %s: %s\n",
				luri->uri, ldap_err2string(ret));
		}
	}
	lcon->con = NULL;
	return -1;
}
Esempio n. 25
0
/*
 * Opes connection to an LDAP server
 * uri must be one URI
 */
static int do_open (LDAP **ld, const char* uri, int defport, ldap_ssl_options_t ssl_on_local)
{

#if defined(LDAP_OPT_NETWORK_TIMEOUT) || defined(HAVE_LDAP_START_TLS)
	struct timeval tv;
#endif
#ifdef HAVE_LDAP_START_TLS
	struct timeval *tvp;
	LDAPMessage *res = NULL;
	int msgid;
#endif
	int rc;

	rc = do_init (ld, uri, defport);

	if (rc != LDAP_SUCCESS)
	{
		DBG("do_open(): do_init failed");
		return rc;
    }

	if( ! *ld)
	{
		DBG("do_open(): internal error - assert (*ld != NULL)");
		return(-2);
	}

#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_PROTOCOL_VERSION)
	ldap_set_option (*ld, LDAP_OPT_PROTOCOL_VERSION, &ldapVersion);
#endif /* LDAP_OPT_PROTOCOL_VERSION */

#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT)
/*	ldap_set_option (*ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout); */

	rc = ldap_set_option(*ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
	if ( rc != LDAP_SUCCESS ) {
		DBG2("Warning: failed to set connection timeout to %d: %s", timeout, ldap_err2string(rc));
	} else
		DBG1("Set connection timeout to %d", timeout);
#endif /* LDAP_OPT_NETWORK_TIMEOUT */

#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT)
	tv.tv_sec = bind_timelimit;
	tv.tv_usec = 0;
	ldap_set_option (*ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
#endif /* LDAP_OPT_NETWORK_TIMEOUT */


#if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS)
	if (ssl_on_local == SSL_START_TLS)
    {
		int version;

		/* we need V3 at least */
		if (ldap_get_option(*ld, LDAP_OPT_PROTOCOL_VERSION,
							&version) == LDAP_OPT_SUCCESS)
		{
			if (ldapVersion < LDAP_VERSION3)
			{
				ldapVersion = LDAP_VERSION3;
				ldap_set_option (*ld, LDAP_OPT_PROTOCOL_VERSION,
			    			&ldapVersion);
	    	}
		}

		/* set up SSL context */
		if (do_ssl_options (*ld) != LDAP_SUCCESS)
		{
			ldap_unbind (*ld);
			DBG("do_open(): SSL setup failed");
			return LDAP_UNAVAILABLE;
		}

#ifdef HAVE_LDAP_START_TLS

  		DBG("do_open(): do_start_tls");
		rc = ldap_start_tls (*ld, NULL, NULL, &msgid);
		if (rc != LDAP_SUCCESS)
		{
		  DBG1("do_open(): ldap_start_tls failed: %s", ldap_err2string (rc));
		  return rc;
		}

		if (bind_timelimit == LDAP_NO_LIMIT)
		{
			tvp = NULL;
    	}
  		else
    	{
      		tv.tv_sec = bind_timelimit;
      		tv.tv_usec = 0;
      		tvp = &tv;
    	}

		rc = ldap_result (*ld, msgid, 1, tvp, &res);
		if (rc == -1)
		{
#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
			if (ldap_get_option (*ld, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_SUCCESS)
			{
				rc = LDAP_UNAVAILABLE;
			}
#else
			rc = ld->ld_errno;
#endif /* LDAP_OPT_ERROR_NUMBER */

			DBG1("do_open(): ldap_start_tls failed: %s", ldap_err2string (rc));
			return rc;
		}

		rc = ldap_result2error (*ld, res, 1);
		if (rc != LDAP_SUCCESS)
		{
			DBG1("do_open(): ldap_result2error failed: %s)", ldap_err2string (rc));
			return rc;
		}

		rc = ldap_install_tls (*ld);
#else
		rc = ldap_start_tls_s (*ld, NULL, NULL);
#endif /* HAVE_LDAP_START_TLS */

  		if (rc == LDAP_SUCCESS)
		{
  			DBG("do_open(): TLS startup succeeded");
		}
		else
		{
			ldap_unbind (*ld);
			DBG2("do_open(): TLS startup failed for LDAP server %s: %s",
			     uri, ldap_err2string (rc));
		    return rc;
		}
	}
  	else
#endif /* HAVE_LDAP_START_TLS_S || HAVE_LDAP_START_TLS */

	/*
	 * If SSL is desired, then enable it.
	 */
	if (ssl_on_local == SSL_LDAPS)
    {
#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
		int tls = LDAP_OPT_X_TLS_HARD;
		if (ldap_set_option (*ld, LDAP_OPT_X_TLS, &tls) !=
			LDAP_SUCCESS)
		{
			ldap_unbind (*ld);
			DBG("do_open(): TLS setup failed");
			return LDAP_UNAVAILABLE;
		}

		/* set up SSL context */
		if (do_ssl_options (*ld) != LDAP_SUCCESS)
		{
			ldap_unbind (*ld);
			DBG("do_open(): SSL setup failed");
			return LDAP_UNAVAILABLE;
		}
#endif
    }

	rc = do_bind (*ld, bind_timelimit);
	if (rc != LDAP_SUCCESS)
	{
		DBG2("do_open(): failed to bind to LDAP server %s: %s",
			 uri, ldap_err2string (rc));
		ldap_unbind (*ld);
	}
	return rc;
}
Esempio n. 26
0
handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
#ifdef USE_LDAP
    int ret;
#if 0
    if (s->auth_ldap_basedn->used == 0) {
        log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set");

        return HANDLER_ERROR;
    }
#endif

    if (s->auth_ldap_filter->used) {
        char *dollar;

        /* parse filter */

        if (NULL == (dollar = strchr(s->auth_ldap_filter->ptr, '$'))) {
            log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.filter is missing a replace-operator '$'");

            return HANDLER_ERROR;
        }

        buffer_copy_string_len(s->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr);
        buffer_copy_string(s->ldap_filter_post, dollar+1);
    }

    if (s->auth_ldap_hostname->used) {
        if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) {
            log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));

            return HANDLER_ERROR;
        }

        ret = LDAP_VERSION3;
        if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
            log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

            return HANDLER_ERROR;
        }

        if (s->auth_ldap_starttls) {
            /* if no CA file is given, it is ok, as we will use encryption
             * if the server requires a CAfile it will tell us */
            if (!buffer_is_empty(s->auth_ldap_cafile)) {
                if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
                                               s->auth_ldap_cafile->ptr))) {
                    log_error_write(srv, __FILE__, __LINE__, "ss",
                                    "Loading CA certificate failed:", ldap_err2string(ret));

                    return HANDLER_ERROR;
                }
            }

            if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL,  NULL))) {
                log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));

                return HANDLER_ERROR;
            }
        }


        /* 1. */
        if (s->auth_ldap_binddn->used) {
            if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) {
                log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

                return HANDLER_ERROR;
            }
        } else {
            if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) {
                log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

                return HANDLER_ERROR;
            }
        }
    }
#else
    log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available");
    return HANDLER_ERROR;
#endif
    return HANDLER_GO_ON;
}
Esempio n. 27
0
/*
 * always protected by conn_mutex
 * optionally protected by req_mutex and res_mutex
 */
LDAPConn *
ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb,
	int connect, LDAPreqinfo *bind, int m_req, int m_res )
{
	LDAPConn	*lc;
	int		async = 0;

	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_conn_mutex );
	Debug( LDAP_DEBUG_TRACE, "ldap_new_connection %d %d %d\n",
		use_ldsb, connect, (bind != NULL) );
	/*
	 * make a new LDAP server connection
	 * XXX open connection synchronously for now
	 */
	lc = (LDAPConn *)LDAP_CALLOC( 1, sizeof( LDAPConn ) );
	if ( lc == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return( NULL );
	}
	
	if ( use_ldsb ) {
		assert( ld->ld_sb != NULL );
		lc->lconn_sb = ld->ld_sb;

	} else {
		lc->lconn_sb = ber_sockbuf_alloc();
		if ( lc->lconn_sb == NULL ) {
			LDAP_FREE( (char *)lc );
			ld->ld_errno = LDAP_NO_MEMORY;
			return( NULL );
		}
	}

	if ( connect ) {
		LDAPURLDesc	**srvp, *srv = NULL;

		async = LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_CONNECT_ASYNC );

		for ( srvp = srvlist; *srvp != NULL; srvp = &(*srvp)->lud_next ) {
			int		rc;

			rc = ldap_int_open_connection( ld, lc, *srvp, async );
			if ( rc != -1 ) {
				srv = *srvp;

				if ( ld->ld_urllist_proc && ( !async || rc != -2 ) ) {
					ld->ld_urllist_proc( ld, srvlist, srvp, ld->ld_urllist_params );
				}

				break;
			}
		}

		if ( srv == NULL ) {
			if ( !use_ldsb ) {
				ber_sockbuf_free( lc->lconn_sb );
			}
			LDAP_FREE( (char *)lc );
			ld->ld_errno = LDAP_SERVER_DOWN;
			return( NULL );
		}

		lc->lconn_server = ldap_url_dup( srv );
	}

	lc->lconn_status = async ? LDAP_CONNST_CONNECTING : LDAP_CONNST_CONNECTED;
	lc->lconn_next = ld->ld_conns;
	ld->ld_conns = lc;

	if ( connect ) {
#ifdef HAVE_TLS
		if ( lc->lconn_server->lud_exts ) {
			int rc, ext = find_tls_ext( lc->lconn_server );
			if ( ext ) {
				LDAPConn	*savedefconn;

				savedefconn = ld->ld_defconn;
				++lc->lconn_refcnt;	/* avoid premature free */
				ld->ld_defconn = lc;

				LDAP_REQ_UNLOCK_IF(m_req);
				LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
				LDAP_RES_UNLOCK_IF(m_res);
				rc = ldap_start_tls_s( ld, NULL, NULL );
				LDAP_RES_LOCK_IF(m_res);
				LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
				LDAP_REQ_LOCK_IF(m_req);
				ld->ld_defconn = savedefconn;
				--lc->lconn_refcnt;

				if ( rc != LDAP_SUCCESS && ext == 2 ) {
					ldap_free_connection( ld, lc, 1, 0 );
					return NULL;
				}
			}
		}
#endif
	}

	if ( bind != NULL ) {
		int		err = 0;
		LDAPConn	*savedefconn;

		/* Set flag to prevent additional referrals
		 * from being processed on this
		 * connection until the bind has completed
		 */
		lc->lconn_rebind_inprogress = 1;
		/* V3 rebind function */
		if ( ld->ld_rebind_proc != NULL) {
			LDAPURLDesc	*srvfunc;

			srvfunc = ldap_url_dup( *srvlist );
			if ( srvfunc == NULL ) {
				ld->ld_errno = LDAP_NO_MEMORY;
				err = -1;
			} else {
				savedefconn = ld->ld_defconn;
				++lc->lconn_refcnt;	/* avoid premature free */
				ld->ld_defconn = lc;

				Debug( LDAP_DEBUG_TRACE, "Call application rebind_proc\n", 0, 0, 0);
				LDAP_REQ_UNLOCK_IF(m_req);
				LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
				LDAP_RES_UNLOCK_IF(m_res);
				err = (*ld->ld_rebind_proc)( ld,
					bind->ri_url, bind->ri_request, bind->ri_msgid,
					ld->ld_rebind_params );
				LDAP_RES_LOCK_IF(m_res);
				LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
				LDAP_REQ_LOCK_IF(m_req);

				ld->ld_defconn = savedefconn;
				--lc->lconn_refcnt;

				if ( err != 0 ) {
					err = -1;
					ldap_free_connection( ld, lc, 1, 0 );
					lc = NULL;
				}
				ldap_free_urldesc( srvfunc );
			}

		} else {
			int		msgid, rc;
			struct berval	passwd = BER_BVNULL;

			savedefconn = ld->ld_defconn;
			++lc->lconn_refcnt;	/* avoid premature free */
			ld->ld_defconn = lc;

			Debug( LDAP_DEBUG_TRACE,
				"anonymous rebind via ldap_sasl_bind(\"\")\n",
				0, 0, 0);

			LDAP_REQ_UNLOCK_IF(m_req);
			LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
			LDAP_RES_UNLOCK_IF(m_res);
			rc = ldap_sasl_bind( ld, "", LDAP_SASL_SIMPLE, &passwd,
				NULL, NULL, &msgid );
			if ( rc != LDAP_SUCCESS ) {
				err = -1;

			} else {
				for ( err = 1; err > 0; ) {
					struct timeval	tv = { 0, 100000 };
					LDAPMessage	*res = NULL;

					switch ( ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res ) ) {
					case -1:
						err = -1;
						break;

					case 0:
#ifdef LDAP_R_COMPILE
						ldap_pvt_thread_yield();
#endif
						break;

					case LDAP_RES_BIND:
						rc = ldap_parse_result( ld, res, &err, NULL, NULL, NULL, NULL, 1 );
						if ( rc != LDAP_SUCCESS ) {
							err = -1;

						} else if ( err != LDAP_SUCCESS ) {
							err = -1;
						}
						/* else err == LDAP_SUCCESS == 0 */
						break;

					default:
						Debug( LDAP_DEBUG_TRACE,
							"ldap_new_connection %p: "
							"unexpected response %d "
							"from BIND request id=%d\n",
							(void *) ld, ldap_msgtype( res ), msgid );
						err = -1;
						break;
					}
				}
			}
			LDAP_RES_LOCK_IF(m_res);
			LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
			LDAP_REQ_LOCK_IF(m_req);
			ld->ld_defconn = savedefconn;
			--lc->lconn_refcnt;

			if ( err != 0 ) {
				ldap_free_connection( ld, lc, 1, 0 );
				lc = NULL;
			}
		}
		if ( lc != NULL )
			lc->lconn_rebind_inprogress = 0;
	}
	return( lc );
}
Esempio n. 28
0
static int ldap_pap_auth(char *user, char *password, char **msgp,
	struct wordlist **paddrs, struct wordlist **popts)
{
	int rc,ldap_errno;
	int version = LDAP_VERSION3;
	char filter[LDAP_FILT_MAXSIZ];
	char userdn[MAX_BUF];
	char **ldap_values;
	LDAP *ldap;
	LDAPMessage *ldap_mesg;
	LDAPMessage	*ldap_entry;

	/* Initiate session and bind to LDAP server */
	if ((ldap = ldap_init(ldap_host, ldap_port)) == NULL) {
		error("LDAP: failed to initialize session\n");
		return -1;
	}

	/* Set LDAP specific options such as timeout, version and tls */
	if ((rc = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION,
		&version) != LDAP_OPT_SUCCESS)) {
		error("LDAP: failed to set protocol version\n");
		return -1;
	}

	if ((rc = ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT,
		&ldap_nettimeout) != LDAP_OPT_SUCCESS)) {
		error("LDAP: failed to set network timeout version\n");
		return -1;
	}

	if ((rc = ldap_set_option(ldap, LDAP_OPT_TIMELIMIT,
		&ldap_timeout) != LDAP_OPT_SUCCESS)) {
		error("LDAP: failed to set timeout option\n");
		return -1;
	}

#ifdef OPT_WITH_TLS
	/* Some servers support only LDAPS but not TLS */
	if ((ldap_port == LDAPS_PORT) && ldap_usetls) {
		int tls_opt = LDAP_OPT_X_TLS_HARD;
		if ((rc = ldap_set_option(ldap, LDAP_OPT_X_TLS,
			(void *)&tls_opt)) != LDAP_SUCCESS) {
		ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
		error("LDAP: failed to set TLS option: %s\n", ldap_err2string(rc));
		return -1;
		}
	}

	if (ldap_usetls) {
#ifdef DEBUG
		info("LDAP: Setting TLS option -> ON\n");
#endif
		if((rc = ldap_start_tls_s(ldap, NULL, NULL) != LDAP_SUCCESS)) {
		ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
		error("LDAP: failed to initiate TLS: %s\n", ldap_err2string(ldap_errno));
		return -1;
		}
	}
#endif

	/* Perform binding at last */
	if ((rc = ldap_bind_s(ldap, ldap_dn, ldap_pw, LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) {
		ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
		error("LDAP: failed to bind: %s\n",ldap_err2string(rc));
		ldap_unbind(ldap);
		return -1;
	}

	/* Form a search filter from supplied peer's credentials */
	if ((rc = snprintf(filter, LDAP_FILT_MAXSIZ,"(uid=%s)",
		 user)) == -1) {
		error("LDAP: LDAP filter too big\n");
		ldap_unbind(ldap);
		return -1;
	};

#ifdef DEBUG
		info("LDAP: search filter: %s\n",filter);
#endif

	/* Perform search*/
	if ((rc = ldap_search_s(ldap, userbasedn, LDAP_SCOPE_SUBTREE, filter,
		NULL, 0, &ldap_mesg)) != LDAP_SUCCESS) {
		ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
		error("LDAP: Can't perform search: %s\n",
			ldap_err2string(rc));
		ldap_unbind(ldap);
		return -1;
	};

	/* If search returned more than 2 results or 0 - something is wrong! */
	if ( ldap_mesg == NULL ){
		info("LDAP: No such user \"%s\"\n",user);
		ldap_unbind(ldap);
		return -1;
	}

	if ((ldap_count_entries(ldap, ldap_mesg)) > 1){
		warn("LDAP: more than one user \"%s\" exists!\n",user);
		ldap_unbind(ldap);
		return -1;
	}

	/* Check existance of dialupAccess attribute and it's value */
#ifdef DEBUG
	info("LDAP: found %u entries\n",ldap_count_entries(ldap, ldap_mesg));
#endif

	ldap_entry = ldap_first_entry(ldap, ldap_mesg);

	if ((rc = snprintf(userdn,MAX_BUF,"%s",ldap_get_dn(ldap,ldap_entry))) == -1)
		warn("LDAP: user DN stripped\n");

#ifdef DEBUG
	info("LDAP: rebind DN: %s\n",userdn);
#endif

	if ((rc = ldap_simple_bind_s(ldap,userdn,password)) != LDAP_SUCCESS) {
		error("LDAP: username or password incorrect\n");
		*msgp = "Username or password incorrect!";
		ldap_unbind(ldap);
		ldap_msgfree(ldap_mesg);
		return 0;
	}

	/* Set pppd options */
	ldap_setoptions(ldap, ldap_mesg, &ldap_data);

#ifdef DEBUG
	info("LDAP: Auth success\n");
#endif
	*msgp = "Access OK!";
	ldap_data.access_ok = 1;

	/* Write ppp_utmp data in place */
	return 1;
}
Esempio n. 29
0
static int
_mu_conn_setup (LDAP **pld)
{
  int rc;
  LDAPURLDesc *ludlist, **ludp;
  char **urls = NULL;
  int nurls = 0;
  char *ldapuri = NULL;
  LDAP *ld = NULL;
  int protocol = LDAP_VERSION3; /* FIXME: must be configurable */
  
  if (ldap_param.debug)
    {
      if (ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, &ldap_param.debug)
	  != LBER_OPT_SUCCESS )
	mu_error (_("cannot set LBER_OPT_DEBUG_LEVEL %d"), ldap_param.debug);

      if (ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, &ldap_param.debug)
	  != LDAP_OPT_SUCCESS )
	mu_error (_("could not set LDAP_OPT_DEBUG_LEVEL %d"),
		  ldap_param.debug);
    }

  if (ldap_param.url)
    {
      rc = ldap_url_parse (ldap_param.url, &ludlist);
      if (rc != LDAP_URL_SUCCESS)
	{
	  mu_error (_("cannot parse LDAP URL(s)=%s (%d)"),
		    ldap_param.url, rc);
	  return 1;
	}
      
      for (ludp = &ludlist; *ludp; )
	{
	  LDAPURLDesc *lud = *ludp;
	  char **tmp;
	  
	  if (lud->lud_dn && lud->lud_dn[0]
	      && (lud->lud_host == NULL || lud->lud_host[0] == '\0'))
	    {
	      /* if no host but a DN is provided, try DNS SRV to gather the
		 host list */
	      char *domain = NULL, *hostlist = NULL;
	      size_t i;
	      struct mu_wordsplit ws;
	      
	      if (ldap_dn2domain (lud->lud_dn, &domain) || !domain)
		{
		  mu_error (_("DNS SRV: cannot convert DN=\"%s\" into a domain"),
			    lud->lud_dn );
		  goto dnssrv_free;
		}
	      
	      rc = ldap_domain2hostlist (domain, &hostlist);
	      if (rc)
		{
		  mu_error (_("DNS SRV: cannot convert domain=%s into a hostlist"),
			    domain);
		  goto dnssrv_free;
		}

	      if (mu_wordsplit (hostlist, &ws, MU_WRDSF_DEFFLAGS))
		{
		  mu_error (_("DNS SRV: could not parse hostlist=\"%s\": %s"),
			    hostlist, mu_wordsplit_strerror (&ws));
		  goto dnssrv_free;
		}
	      
	      tmp = realloc (urls, sizeof(char *) * (nurls + ws.ws_wordc + 1));
	      if (!tmp)
		{
		  mu_error ("DNS SRV %s", mu_strerror (errno));
		  goto dnssrv_free;
		}
	      
	      urls = tmp;
	      urls[nurls] = NULL;
	      
	      for (i = 0; i < ws.ws_wordc; i++)
		{
		  urls[nurls + i + 1] = NULL;
		  rc = mu_asprintf (&urls[nurls + i],
				    "%s://%s",
				    lud->lud_scheme, ws.ws_wordv[i]);
		  if (rc)
		    {
		      mu_error ("DNS SRV %s", mu_strerror (rc));
		      goto dnssrv_free;
		    }
		}
	      
	      nurls += i;
	      
	    dnssrv_free:
	      mu_wordsplit_free (&ws);
	      ber_memfree (hostlist);
	      ber_memfree (domain);
	    }
	  else
	    {
	      tmp = realloc (urls, sizeof(char *) * (nurls + 2));
	      if (!tmp)
		{
		  mu_error ("DNS SRV %s", mu_strerror (errno));
		  break;
		}
	      urls = tmp;
	      urls[nurls + 1] = NULL;
	      
	      urls[nurls] = ldap_url_desc2str (lud);
	      if (!urls[nurls])
		{
		  mu_error ("DNS SRV %s", mu_strerror (errno));
		  break;
		}
	      nurls++;
	    }
	  
	  *ludp = lud->lud_next;
	  
	  lud->lud_next = NULL;
	  ldap_free_urldesc (lud);
	}

      if (ludlist)
	{
	  ldap_free_urldesc (ludlist);
	  return 1;
	}
      else if (!urls)
	return 1;
      
      rc = mu_argcv_string (nurls, urls, &ldapuri);
      if (rc)
	{
	  mu_error ("%s", mu_strerror (rc));
	  return 1;
	}
      
      ber_memvfree ((void **)urls);
    }

  mu_diag_output (MU_DIAG_INFO,
		  "constructed LDAP URI: %s", ldapuri ? ldapuri : "<DEFAULT>");

  rc = ldap_initialize (&ld, ldapuri);
  if (rc != LDAP_SUCCESS)
    {
      mu_error (_("cannot create LDAP session handle for URI=%s (%d): %s"),
		ldapuri, rc, ldap_err2string (rc));

      free (ldapuri);
      return 1;
    }
  free (ldapuri);
  
  ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &protocol);

  if (ldap_param.tls)
    {
      rc = ldap_start_tls_s (ld, NULL, NULL);
      if (rc != LDAP_SUCCESS)
	{
	  char *msg = NULL;
	  ldap_get_option (ld,
			   LDAP_OPT_DIAGNOSTIC_MESSAGE,
			   (void*)&msg);
	  
	  mu_error (_("ldap_start_tls failed: %s"), ldap_err2string (rc));
	  mu_error (_("TLS diagnostics: %s"), msg);
	  ldap_memfree (msg);

	  ldap_unbind_ext (ld, NULL, NULL);
	  
	  return 1;
	}
    }

  /* FIXME: Timeouts, SASL, etc. */
  *pld = ld;
  return 0;
}
Esempio n. 30
0
int
main(int argc, char **argv)
{
    char buf[8192];
    char *user, *group, *extension_dn = NULL;
    char *ldapServer = NULL;
    LDAP *ld = NULL;
    int tryagain = 0, rc;
    int port = LDAP_PORT;
    int use_extension_dn = 0;
    int strip_nt_domain = 0;
    int strip_kerberos_realm = 0;

    setbuf(stdout, NULL);

    while (argc > 1 && argv[1][0] == '-') {
	char *value = "";
	char option = argv[1][1];
	switch (option) {
	case 'P':
	case 'R':
	case 'z':
	case 'Z':
	case 'd':
	case 'g':
	case 'S':
	case 'K':
	    break;
	default:
	    if (strlen(argv[1]) > 2) {
		value = argv[1] + 2;
	    } else if (argc > 2) {
		value = argv[2];
		argv++;
		argc--;
	    } else
		value = "";
	    break;
	}
	argv++;
	argc--;
	switch (option) {
	case 'H':
#if !HAS_URI_SUPPORT
	    fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n");
	    exit(1);
#endif
	    /* Fall thru to -h */
	case 'h':
	    if (ldapServer) {
		int len = strlen(ldapServer) + 1 + strlen(value) + 1;
		char *newhost = malloc(len);
		snprintf(newhost, len, "%s %s", ldapServer, value);
		free(ldapServer);
		ldapServer = newhost;
	    } else {
		ldapServer = strdup(value);
	    }
	    break;
	case 'b':
	    basedn = value;
	    break;
	case 'f':
	    searchfilter = value;
	    break;
	case 'B':
	    userbasedn = value;
	    break;
	case 'F':
	    usersearchfilter = value;
	    break;
	case 'u':
	    userdnattr = value;
	    break;
	case 's':
	    if (strcmp(value, "base") == 0)
		searchscope = LDAP_SCOPE_BASE;
	    else if (strcmp(value, "one") == 0)
		searchscope = LDAP_SCOPE_ONELEVEL;
	    else if (strcmp(value, "sub") == 0)
		searchscope = LDAP_SCOPE_SUBTREE;
	    else {
		fprintf(stderr, PROGRAM_NAME " ERROR: Unknown search scope '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'E':
#if defined(NETSCAPE_SSL)
	    sslpath = value;
	    if (port == LDAP_PORT)
		port = LDAPS_PORT;
#else
	    fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n");
	    exit(1);
#endif
	    break;
	case 'c':
	    connect_timeout = atoi(value);
	    break;
	case 't':
	    timelimit = atoi(value);
	    break;
	case 'a':
	    if (strcmp(value, "never") == 0)
		aliasderef = LDAP_DEREF_NEVER;
	    else if (strcmp(value, "always") == 0)
		aliasderef = LDAP_DEREF_ALWAYS;
	    else if (strcmp(value, "search") == 0)
		aliasderef = LDAP_DEREF_SEARCHING;
	    else if (strcmp(value, "find") == 0)
		aliasderef = LDAP_DEREF_FINDING;
	    else {
		fprintf(stderr, PROGRAM_NAME " ERROR: Unknown alias dereference method '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'D':
	    binddn = value;
	    break;
	case 'w':
	    bindpasswd = value;
	    break;
	case 'W':
	    readSecret(value);
	    break;
	case 'P':
	    persistent = !persistent;
	    break;
	case 'p':
	    port = atoi(value);
	    break;
	case 'R':
	    noreferrals = !noreferrals;
	    break;
#ifdef LDAP_VERSION3
	case 'v':
	    switch (atoi(value)) {
	    case 2:
		version = LDAP_VERSION2;
		break;
	    case 3:
		version = LDAP_VERSION3;
		break;
	    default:
		fprintf(stderr, "Protocol version should be 2 or 3\n");
		exit(1);
	    }
	    break;
	case 'Z':
	    if (version == LDAP_VERSION2) {
		fprintf(stderr, "TLS (-Z) is incompatible with version %d\n",
		    version);
		exit(1);
	    }
	    version = LDAP_VERSION3;
	    use_tls = 1;
	    break;
#endif
	case 'd':
	    debug = 1;
	    break;
	case 'g':
	    use_extension_dn = 1;
	    break;
	case 'S':
	    strip_nt_domain = 1;
	    break;
	case 'K':
	    strip_kerberos_realm = 1;
	    break;
	default:
	    fprintf(stderr, PROGRAM_NAME " ERROR: Unknown command line option '%c'\n", option);
	    exit(1);
	}
    }

    while (argc > 1) {
	char *value = argv[1];
	if (ldapServer) {
	    int len = strlen(ldapServer) + 1 + strlen(value) + 1;
	    char *newhost = malloc(len);
	    snprintf(newhost, len, "%s %s", ldapServer, value);
	    free(ldapServer);
	    ldapServer = newhost;
	} else {
	    ldapServer = strdup(value);
	}
	argc--;
	argv++;
    }

    if (!ldapServer)
	ldapServer = "localhost";

    if (!basedn || !searchfilter) {
	fprintf(stderr, "\n" PROGRAM_NAME " version " PROGRAM_VERSION "\n\n");
	fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn -f filter [options] ldap_server_name\n\n");
	fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under where to search for groups\n");
	fprintf(stderr, "\t-f filter (REQUIRED)\tgroup search filter pattern. %%u = user,\n\t\t\t\t%%g = group\n");
	fprintf(stderr, "\t-B basedn (REQUIRED)\tbase dn under where to search for users\n");
	fprintf(stderr, "\t-F filter (REQUIRED)\tuser search filter pattern. %%s = login\n");
	fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n");
	fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n");
	fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n");
	fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n");
#if HAS_URI_SUPPORT
	fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n");
#endif
	fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n");
	fprintf(stderr, "\t-p port\t\t\tLDAP server port (defaults to %d)\n", LDAP_PORT);
	fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n");
#if defined(NETSCAPE_SSL)
	fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n");
#endif
	fprintf(stderr, "\t-c timeout\t\tconnect timeout\n");
	fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n");
	fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n");
	fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n");
#ifdef LDAP_VERSION3
	fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n");
	fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires\n\t\t\t\tLDAP version 3\n");
#endif
	fprintf(stderr, "\t-g\t\t\tfirst query parameter is base DN extension\n\t\t\t\tfor this query\n");
	fprintf(stderr, "\t-S\t\t\tStrip NT domain from usernames\n");
	fprintf(stderr, "\t-K\t\t\tStrip Kerberos realm from usernames\n");
	fprintf(stderr, "\t-d\t\t\tenable debug mode\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n");
	exit(1);
    }
/* On Windows ldap_start_tls_s is available starting from Windows XP, 
 * so we need to bind at run-time with the function entry point
 */
#ifdef _SQUID_MSWIN_
    if (use_tls) {

	HMODULE WLDAP32Handle;

	WLDAP32Handle = GetModuleHandle("wldap32");
	if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) {
	    fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n");
	    exit(1);
	}
    }
#endif

    while (fgets(buf, 256, stdin) != NULL) {
	int found = 0;
	if (!strchr(buf, '\n')) {
	    /* too large message received.. skip and deny */
	    fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf);
	    while (fgets(buf, sizeof(buf), stdin)) {
		fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf);
		if (strchr(buf, '\n') != NULL)
		    break;
	    }
	    goto error;
	}
	user = strtok(buf, " \n");
	if (!user) {
	    fprintf(stderr, "%s: Invalid request\n", argv[0]);
	    goto error;
	}
	rfc1738_unescape(user);
	if (strip_nt_domain) {
	    char *u = strrchr(user, '\\');
	    if (!u)
		u = strrchr(user, '/');
	    if (!u)
		u = strrchr(user, '+');
	    if (u && u[1])
		user = u + 1;
	}
	if (strip_kerberos_realm) {
	    char *u = strchr(user, '@');
	    if (u != NULL) {
		*u = '\0';
	    }
	}
	if (use_extension_dn) {
	    extension_dn = strtok(NULL, " \n");
	    if (!extension_dn) {
		fprintf(stderr, "%s: Invalid request\n", argv[0]);
		goto error;
	    }
	    rfc1738_unescape(extension_dn);
	}
	while (!found && user && (group = strtok(NULL, " \n")) != NULL) {
	    rfc1738_unescape(group);

	  recover:
	    if (ld == NULL) {
#if HAS_URI_SUPPORT
		if (strstr(ldapServer, "://") != NULL) {
		    rc = ldap_initialize(&ld, ldapServer);
		    if (rc != LDAP_SUCCESS) {
			fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer);
			break;
		    }
		} else
#endif
#if NETSCAPE_SSL
		if (sslpath) {
		    if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) {
			fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n",
			    sslpath);
			exit(1);
		    } else {
			sslinit++;
		    }
		    if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) {
			fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n",
			    ldapServer, port);
			exit(1);
		    }
		} else
#endif
		if ((ld = ldap_init(ldapServer, port)) == NULL) {
		    fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port);
		    break;
		}
		if (connect_timeout)
		    squid_ldap_set_connect_timeout(ld, connect_timeout);

#ifdef LDAP_VERSION3
		if (version == -1) {
		    version = LDAP_VERSION2;
		}
		if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) {
		    fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
			version);
		    ldap_unbind(ld);
		    ld = NULL;
		    break;
		}
		if (use_tls) {
#ifdef LDAP_OPT_X_TLS
		    if (version != LDAP_VERSION3) {
			fprintf(stderr, "TLS requires LDAP version 3\n");
			exit(1);
		    } else if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) {
			fprintf(stderr, "Could not Activate TLS connection\n");
			ldap_unbind(ld);
			ld = NULL;
			break;
		    }
#else
		    fprintf(stderr, "TLS not supported with your LDAP library\n");
		    exit(1);
#endif
		}
#endif
		squid_ldap_set_timelimit(ld, timelimit);
		squid_ldap_set_referrals(ld, !noreferrals);
		squid_ldap_set_aliasderef(ld, aliasderef);
		if (binddn && bindpasswd && *binddn && *bindpasswd) {
		    rc = ldap_simple_bind_s(ld, binddn, bindpasswd);
		    if (rc != LDAP_SUCCESS) {
			fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc));
			ldap_unbind(ld);
			ld = NULL;
			break;
		    }
		}
		if (debug)
		    fprintf(stderr, "Connected OK\n");
	    }
	    if (searchLDAP(ld, group, user, extension_dn) == 0) {
		found = 1;
		break;
	    } else {
		if (tryagain) {
		    tryagain = 0;
		    ldap_unbind(ld);
		    ld = NULL;
		    goto recover;
		}
	    }
	}
	if (found)
	    printf("OK\n");
	else {
	  error:
	    printf("ERR\n");
	}

	if (ld != NULL) {
	    if (!persistent || (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) {
		ldap_unbind(ld);
		ld = NULL;
	    } else {
		tryagain = 1;
	    }
	}
    }
    if (ld)
	ldap_unbind(ld);
    return 0;
}