Exemple #1
0
LDAP *
ldap_open(char *host, int port)
{
	LDAP		*ld;
	int err;

	if ((ld = ldap_init(host, port)) == NULL) {
		return (NULL);
	}

	Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 113,
		"ldap_open (after ldap_init)\n"), 0, 0, 0);

#ifdef _REENTRANT
	LOCK_LDAP(ld);
#endif
	if ((err = open_default_ldap_connection(ld)) != LDAP_SUCCESS) {
#ifdef _REENTRANT
	UNLOCK_LDAP(ld);
#endif
		ldap_ld_free(ld, 0);
		Debug(LDAP_DEBUG_ANY, catgets(slapdcat, 1, 1275,
			"ldap_open failed, %s\n"),
			ldap_err2string(err), 0, 0);
		return (NULL);
	}

	Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 194,
		"ldap_open successful, ld_host is %s\n"),
		(ld->ld_host == NULL) ? "(null)" : ld->ld_host, 0, 0);
#ifdef _REENTRANT
	UNLOCK_LDAP(ld);
#endif
	return (ld);

}
Exemple #2
0
LDAP_CALL
ldap_open( const char *host, int port )
{
	LDAP	*ld;

	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 );

	if (( ld = ldap_init( host, port )) == NULL ) {
		return( NULL );
	}

	LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
	if ( nsldapi_open_ldap_defconn( ld ) < 0 ) {
		LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
		ldap_ld_free( ld, NULL, NULL, 0 );
		return( NULL );
	}

	LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n",
		( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 );

	return( ld );
}
Exemple #3
0
int main( int argc, char *argv[] ) {
   LDAP *ld;
   int  result;
   int  auth_method = LDAP_AUTH_SIMPLE;
   int desired_version = LDAP_VERSION3;
   char *ldap_host = "localhost";
   char *root_dn = "cn=Manager, dc=example, dc=com";
   char *root_pw = "secret";

   BerElement* ber;
   LDAPMessage* msg;
   LDAPMessage* entry;

   char* base="ou=developers,dc=example,dc=com";
   char* filter="(objectClass=*)";
   char* errstring;
   char* dn = NULL;
   char* attr;
   char** vals;
   int i;

   if ((ld = ldap_init(ldap_host, LDAP_PORT)) == NULL ) {
      perror( "ldap_init failed" );
      exit( EXIT_FAILURE );
   }

   /* set the LDAP version to be 3 */
   if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != LDAP_OPT_SUCCESS)
   {
      ldap_perror(ld, "ldap_set_option");
      exit(EXIT_FAILURE);
   }

   if (ldap_bind_s(ld, root_dn, root_pw, auth_method) != LDAP_SUCCESS ) {
      ldap_perror( ld, "ldap_bind" );
      exit( EXIT_FAILURE );
   }

   if (ldap_search_s(ld, base, LDAP_SCOPE_SUBTREE, filter, NULL, 0, &msg) != LDAP_SUCCESS) {
      ldap_perror( ld, "ldap_search_s" );
      exit(EXIT_FAILURE);
   }

   printf("The number of entries returned was %d\n\n", ldap_count_entries(ld, msg));

   /* Iterate through the returned entries */
   for(entry = ldap_first_entry(ld, msg); entry != NULL; entry = ldap_next_entry(ld, entry)) {

      if((dn = ldap_get_dn(ld, entry)) != NULL) {
	 printf("Returned dn: %s\n", dn);
	 ldap_memfree(dn);
      }

      for( attr = ldap_first_attribute(ld, entry, &ber); 
	    attr != NULL; 
	    attr = ldap_next_attribute(ld, entry, ber)) {
	 if ((vals = ldap_get_values(ld, entry, attr)) != NULL)  {
	    for(i = 0; vals[i] != NULL; i++) {
	       printf("%s: %s\n", attr, vals[i]);
	    }

	    ldap_value_free(vals);
	 }

	 ldap_memfree(attr);
      }

      if (ber != NULL) {
	 ber_free(ber,0);
      }

      printf("\n");
   }

   /* clean up */
   ldap_msgfree(msg);
   result = ldap_unbind_s(ld);

   if (result != 0) {
      fprintf(stderr, "ldap_unbind_s: %s\n", ldap_err2string(result));
      exit( EXIT_FAILURE );
   }

   return EXIT_SUCCESS;
}
Exemple #4
0
/*
 * Creates an LDAP search URL given a comma-separated list of attributes.
 * Returns a list of key=values separated by '\n'
 */
char * pref_get_ldap_attributes(char* host, char* base, char* filter, char* attrs,
	char** return_error)
{
	char *value = NULL;
	LDAP* ld;
	int err, i;
	char *url;
	LDAPMessage *result;
	LDAPMessage	*e;
	char *a;
	BerElement	*ber;
	char **vals;
	
	ld = ldap_init(host, LDAP_PORT);
	if (!ld)
		return value;
		
	url = (char*) malloc(sizeof(char) *
		 (strlen(host) + strlen(base) + strlen(filter) + strlen(attrs) + 20));
	if (!url)
		return value;
		
	XP_SPRINTF(url, "ldap://%s/%s?%s?sub?%s", host, base, attrs, filter);
	
	err = ldap_url_search_s( ld, url, 0, &result );
	XP_FREE(url);
	if (err != LDAP_SUCCESS) {
		*return_error = ldap_err2string(err);
		return value;
	}
	
	e = ldap_first_entry( ld, result );

	if (e) {
		a = ldap_first_attribute( ld, e, &ber );
		if (a) {
			int total_buf_size = 200;
			int remaining_buf_size = total_buf_size;
			value = (char*) malloc(sizeof(char*) * total_buf_size);
			if (!value)
				return NULL;
			value[0] = '\0';
			
			for ( ; a != NULL; a = ldap_next_attribute( ld, e, ber )) {
				vals = ldap_get_values( ld, e, a );
				if (vals && vals[0]) {
					remaining_buf_size -= (strlen(a) + strlen(vals[0]) + 2);
					if (remaining_buf_size < 1) {
						remaining_buf_size += 2 * total_buf_size;
						total_buf_size += 2 * total_buf_size;
						value = (char*) realloc(value, sizeof(char*) * total_buf_size);
						if (!value)
							return NULL;
					}
					
					strcat(value, "\n");
					strcat(value, a);
					strcat(value, "=");
					strcat(value, vals[0]);
					
					ldap_value_free( vals );
				}
			}
			ldap_memfree(a);
		}
		if (ber)
			ber_free(ber, 0);
	}

	ldap_msgfree(result);
	ldap_unbind(ld);
	
	return value;
}
Exemple #5
0
bool AD::Init()
{
    ldap = ldap_init((PWCHAR)host.c_str(), LDAP_PORT);

    return ldap == NULL ? false : true;
}
Exemple #6
0
sInt32 CLDAPNode::BindProc ( sLDAPNodeStruct *inLDAPNodeStruct )
{

    sInt32				siResult		= eDSNoErr;
    int					bindMsgId		= 0;
	int					version			= -1;
    sLDAPConfigData	   *pConfig			= nil;
    char			   *ldapAcct		= nil;
    char			   *ldapPasswd		= nil;
    int					openTO			= 0;
	LDAP			   *inLDAPHost		= inLDAPNodeStruct->fHost;
	LDAPMessage		   *result			= nil;
	int					ldapReturnCode	= 0;

	try
	{
		if ( inLDAPNodeStruct == nil ) throw( (sInt32)eDSNullParameter );
		
		if (inLDAPNodeStruct->fLDAPSessionMutex != nil)
		{
			inLDAPNodeStruct->fLDAPSessionMutex->Wait();
		}
        // Here is the bind to the LDAP server
		// Note that there may be stored name/password in the config table
		// ie. always use the config table data if authentication has not explicitly been set
		// use LDAPAuthNodeMap if inLDAPNodeStruct contains a username
		
		//check that we were already here
		if (inLDAPHost == NULL)
		{
			//retrieve the config data
			//don't need to retrieve for the case of "generic unknown" so don't check index 0
			if (( inLDAPNodeStruct->fLDAPConfigTableIndex < gConfigTableLen) && ( inLDAPNodeStruct->fLDAPConfigTableIndex >= 1 ))
			{
				pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inLDAPNodeStruct->fLDAPConfigTableIndex );
				if (pConfig != nil)
				{
					if ( (pConfig->bSecureUse) && (inLDAPNodeStruct->fUserName == nil) )
					{
						if (pConfig->fServerAccount != nil)
						{
							ldapAcct = new char[1+::strlen(pConfig->fServerAccount)];
							::strcpy( ldapAcct, pConfig->fServerAccount );
						}
						if (pConfig->fServerPassword != nil)
						{
							ldapPasswd = new char[1+::strlen(pConfig->fServerPassword)];
							::strcpy( ldapPasswd, pConfig->fServerPassword );
						}
					}
					else
					{
						if (inLDAPNodeStruct->fUserName != nil)
						{
							ldapAcct = new char[1+::strlen(inLDAPNodeStruct->fUserName)];
							::strcpy( ldapAcct, inLDAPNodeStruct->fUserName );
						}
						if (inLDAPNodeStruct->fAuthCredential != nil)
						{
							if (inLDAPNodeStruct->fAuthType != nil)
							{
								//auth type of clear text means char * password
								if (strcmp(inLDAPNodeStruct->fAuthType,kDSStdAuthClearText) == 0)
								{
									ldapPasswd = new char[1+::strlen((char*)(inLDAPNodeStruct->fAuthCredential))];
									::strcpy( ldapPasswd, (char*)(inLDAPNodeStruct->fAuthCredential) );
								}
							}
							else //default is password
							{
								ldapPasswd = new char[1+::strlen((char*)(inLDAPNodeStruct->fAuthCredential))];
								::strcpy( ldapPasswd, (char*)(inLDAPNodeStruct->fAuthCredential) );
							}
						}
					}
					openTO		= pConfig->fOpenCloseTimeout;
				}
			}

			if (inLDAPNodeStruct->fLDAPConfigTableIndex != 0)
			{
				if (pConfig != nil)
				{
					inLDAPHost = ldap_init( pConfig->fServerName, pConfig->fServerPort );
				}
			}
			else
			{
				inLDAPHost = ldap_init( inLDAPNodeStruct->fServerName, inLDAPNodeStruct->fDirectLDAPPort );
			}
			
			if ( inLDAPHost == nil ) throw( (sInt32)eDSCannotAccessSession );
			
			if (pConfig != nil)
			{
				if ( pConfig->bIsSSL )
				{
					int ldapOptVal = LDAP_OPT_X_TLS_HARD;
					ldap_set_option(inLDAPHost, LDAP_OPT_X_TLS, &ldapOptVal);
				}
			}
			/* LDAPv3 only */
			version = LDAP_VERSION3;
			ldap_set_option( inLDAPHost, LDAP_OPT_PROTOCOL_VERSION, &version );
			
			//heuristic to prevent many consecutive failures with long timeouts
			//ie. forcing quick failures after first failure during a window of
			//the same length as the timeout value
			//NN fLDAPNodeOpenMutex.Wait();
			if ( inLDAPNodeStruct->bHasFailed )
			{
				if ( time( nil ) < inLDAPNodeStruct->fDelayedBindTime )
				{
					//NN fLDAPNodeOpenMutex.Signal();
					throw( (sInt32)eDSCannotAccessSession );
				}
				else
				{
					inLDAPNodeStruct->bHasFailed = false;
					//fDelayedBindTime then is unused so no need to reset
				}
			}
			//NN fLDAPNodeOpenMutex.Signal();

			//this is our and only our LDAP session for now
			//need to use our timeout so we don't hang indefinitely
			bindMsgId = ldap_bind( inLDAPHost, ldapAcct, ldapPasswd, LDAP_AUTH_SIMPLE );
			
			if (openTO == 0)
			{
				ldapReturnCode = ldap_result(inLDAPHost, bindMsgId, 0, NULL, &result);
			}
			else
			{
				struct	timeval	tv;
				tv.tv_sec		= openTO;
				tv.tv_usec		= 0;
				ldapReturnCode	= ldap_result(inLDAPHost, bindMsgId, 0, &tv, &result);
			}

			if ( ldapReturnCode == -1 )
			{
				throw( (sInt32)eDSCannotAccessSession );
			}
			else if ( ldapReturnCode == 0 )
			{
				// timed out, let's forget it
				ldap_abandon(inLDAPHost, bindMsgId);

				//log this timed out connection
				if (pConfig != nil)
				{
					syslog(LOG_INFO,"DSLDAPv3PlugIn: Timed out in attempt to bind to [%s] LDAP server.", pConfig->fServerName);
					syslog(LOG_INFO,"DSLDAPv3PlugIn: Disabled future attempts to bind to [%s] LDAP server for next %d seconds.", pConfig->fServerName, inLDAPNodeStruct->fDelayRebindTry);
				}
				else
				{
					syslog(LOG_INFO,"DSLDAPv3PlugIn: Timed out in attempt to bind to [%s] LDAP server.", inLDAPNodeStruct->fServerName);
					syslog(LOG_INFO,"DSLDAPv3PlugIn: Disabled future attempts to bind to [%s] LDAP server for next %d seconds.", inLDAPNodeStruct->fServerName, inLDAPNodeStruct->fDelayRebindTry);
				}
				//NN fLDAPNodeOpenMutex.Wait();
				inLDAPNodeStruct->bHasFailed = true;
				inLDAPNodeStruct->fDelayedBindTime = time( nil ) + inLDAPNodeStruct->fDelayRebindTry;
				//NN fLDAPNodeOpenMutex.Signal();
				throw( (sInt32)eDSCannotAccessSession );
			}
			else if ( ldap_result2error(inLDAPHost, result, 1) != LDAP_SUCCESS )
			{
				//NN fLDAPNodeOpenMutex.Wait();
				inLDAPNodeStruct->bHasFailed = true;
				inLDAPNodeStruct->fHost = inLDAPHost;
				//NN fLDAPNodeOpenMutex.Signal();
				throw( (sInt32)eDSCannotAccessSession );
			}
			//NN fLDAPNodeOpenMutex.Wait();
			inLDAPNodeStruct->fHost = inLDAPHost;
			//NN fLDAPNodeOpenMutex.Signal();

			//result is consumed above within ldap_result2error
			result = nil;
		}
		
	} // try
	
	catch ( sInt32 err )
	{
		siResult = err;
	}
	
	if (ldapAcct != nil)
	{
		delete (ldapAcct);
		ldapAcct = nil;
	}
	if (ldapPasswd != nil)
	{
		delete (ldapPasswd);
		ldapPasswd = nil;
	}
	
	if (inLDAPNodeStruct->fLDAPSessionMutex != nil)
	{
		inLDAPNodeStruct->fLDAPSessionMutex->Signal();
	}

	return (siResult);
	
}// BindProc
static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params,
									void *user_data)
{
	xml_binding_t *binding = (xml_binding_t *) user_data;
	switch_event_header_t *hi;

	switch_xml_t xml = NULL, sub = NULL;

	struct ldap_c ldap_connection;
	struct ldap_c *ldap = &ldap_connection;

	int auth_method = LDAP_AUTH_SIMPLE;
	int desired_version = LDAP_VERSION3;
	xml_ldap_query_type_t query_type;
	char *dir_exten = NULL, *dir_domain = NULL;

	char *search_filter = NULL, *search_base = NULL;
	int off = 0, ret = 1;

	//char *buf;
	//buf = malloc(4096);


	if (!binding) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No bindings...sorry bud returning now\n");
		return NULL;
	}

	if (!strcmp(section, "configuration")) {
		query_type = XML_LDAP_CONFIG;
	} else if (!strcmp(section, "directory")) {
		query_type = XML_LDAP_DIRECTORY;
	} else if (!strcmp(section, "dialplan")) {
		query_type = XML_LDAP_DIALPLAN;
	} else if (!strcmp(section, "phrases")) {
		query_type = XML_LDAP_PHRASE;
	} else if (!strcmp(section, "languages")) {
		query_type = XML_LDAP_LANGUAGE;
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid section\n");
		return NULL;
	}

	if (params) {
		if ((hi = params->headers)) {
			for (; hi; hi = hi->next) {
				switch (query_type) {
				case XML_LDAP_CONFIG:
					break;

				case XML_LDAP_DIRECTORY:
					if (!strcmp(hi->name, "user")) {
						dir_exten = strdup(hi->value);
					} else if (!strcmp(hi->name, "domain")) {
						dir_domain = strdup(hi->value);
					}
					break;

				case XML_LDAP_DIALPLAN:
				case XML_LDAP_PHRASE:
				case XML_LDAP_LANGUAGE:
					break;
				}
			}
			switch (query_type) {
			case XML_LDAP_CONFIG:
				break;

			case XML_LDAP_DIRECTORY:
				if (dir_exten && dir_domain) {
					if ((xml = switch_xml_new("directory"))) {
						switch_xml_set_attr_d(xml, "type", "freeswitch/xml");

						if ((sub = switch_xml_add_child_d(xml, "section", off++))) {
							switch_xml_set_attr_d(sub, "name", "directory");
						}

						if ((sub = switch_xml_add_child_d(sub, "domain", off++))) {
							switch_xml_set_attr_d(sub, "name", dir_domain);
						}

						if ((sub = switch_xml_add_child_d(sub, "user", off++))) {
							switch_xml_set_attr_d(sub, "id", dir_exten);
						}

					}

					search_filter = switch_mprintf(binding->filter, dir_exten);
					search_base = switch_mprintf(binding->basedn, dir_domain);

					free(dir_exten);
					dir_exten = NULL;

					free(dir_domain);
					dir_domain = NULL;

				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
									  "Something bad happened during the query construction phase likely exten(%s) or domain(%s) is null\n", dir_exten,
									  dir_domain);
					goto cleanup;
				}
				break;

			case XML_LDAP_DIALPLAN:
				if ((xml = switch_xml_new("document"))) {
					switch_xml_set_attr_d(xml, "type", "freeswitch/xml");

					if ((sub = switch_xml_add_child_d(xml, "section", off++))) {
						switch_xml_set_attr_d(sub, "name", "dialplan");
					}

					sub = switch_xml_add_child_d(xml, "context", off++);
				}

				break;

			case XML_LDAP_PHRASE:
			case XML_LDAP_LANGUAGE:
				break;
			}
		} else {
			goto cleanup;
		}
	}



	if ((ldap->ld = (LDAP *) ldap_init(binding->host, LDAP_PORT)) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to connect to ldap server.%s\n", binding->host);
		goto cleanup;
	}

	if (ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != LDAP_OPT_SUCCESS) {
		goto cleanup;
	}

	ldap_set_option(ldap->ld, LDAP_OPT_X_SASL_SECPROPS, &ldap->sp);



	if (binding->binddn) {
		if (ldap_bind_s(ldap->ld, binding->binddn, binding->bindpass, auth_method) != LDAP_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to bind to ldap server %s as %s\n", binding->host, binding->binddn);
			goto cleanup;
		}
	} else {
		if (ldap_sasl_interactive_bind_s
			(ldap->ld, NULL, binding->defaults->mech, NULL, NULL, (unsigned) (intptr_t) LDAP_SASL_SIMPLE, lutil_sasl_interact,
			 binding->defaults) != LDAP_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to sasl_bind to ldap server %s as %s\n", binding->host,
							  binding->defaults->authcid);
			goto cleanup;
		}
	}

	if (ldap_search_s(ldap->ld, search_base, LDAP_SCOPE_SUBTREE, search_filter, NULL, 0, &ldap->msg) != LDAP_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Query failed: -b \"%s\" \"%s\"\n", search_base, search_filter);
		goto cleanup;
	}

	if (ldap_count_entries(ldap->ld, ldap->msg) <= 0) {
		goto cleanup;
	}

	if (sub && xml_ldap_result(&ldap_connection, binding, &sub, &off, query_type) != SWITCH_STATUS_SUCCESS) {
		goto cleanup;
	}

	ret = 0;

  cleanup:
	if (ldap->msg) {
		ldap_msgfree(ldap->msg);
	}

	if (ldap->ld) {
		ldap_unbind_s(ldap->ld);
	}

	switch_safe_free(search_filter);
	switch_safe_free(search_base);

	//switch_xml_toxml_buf(xml,buf,0,0,1);
	//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Providing:\n%s\n", buf);

	if (ret) {
		switch_xml_free(xml);
		return NULL;
	}

	return xml;
}
Exemple #8
0
static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
{
  CURLcode result = CURLE_OK;
  int rc = 0;
  LDAP *server = NULL;
  LDAPURLDesc *ludp = NULL;
  LDAPMessage *ldapmsg = NULL;
  LDAPMessage *entryIterator;
  int num = 0;
  struct SessionHandle *data=conn->data;
  int ldap_proto = LDAP_VERSION3;
  int ldap_ssl = 0;
  char *val_b64 = NULL;
  size_t val_b64_sz = 0;
  curl_off_t dlsize = 0;
#ifdef LDAP_OPT_NETWORK_TIMEOUT
  struct timeval ldap_timeout = {10,0}; /* 10 sec connection/search timeout */
#endif

  *done = TRUE; /* unconditionally */
  infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n",
          LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION);
  infof(data, "LDAP local: %s\n", data->change.url);

#ifdef HAVE_LDAP_URL_PARSE
  rc = ldap_url_parse(data->change.url, &ludp);
#else
  rc = _ldap_url_parse(conn, &ludp);
#endif
  if(rc != 0) {
    failf(data, "LDAP local: %s", ldap_err2string(rc));
    result = CURLE_LDAP_INVALID_URL;
    goto quit;
  }

  /* Get the URL scheme ( either ldap or ldaps ) */
  if(conn->given->flags & PROTOPT_SSL)
    ldap_ssl = 1;
  infof(data, "LDAP local: trying to establish %s connection\n",
          ldap_ssl ? "encrypted" : "cleartext");

#ifdef LDAP_OPT_NETWORK_TIMEOUT
  ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout);
#endif
  ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);

  if(ldap_ssl) {
#ifdef HAVE_LDAP_SSL
#ifdef CURL_LDAP_WIN
    /* Win32 LDAP SDK doesn't support insecure mode without CA! */
    server = ldap_sslinit(conn->host.name, (int)conn->port, 1);
    ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
#else
    int ldap_option;
    char* ldap_ca = data->set.str[STRING_SSL_CAFILE];
#if defined(CURL_HAS_NOVELL_LDAPSDK)
    rc = ldapssl_client_init(NULL, NULL);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
    if(data->set.ssl.verifypeer) {
      /* Novell SDK supports DER or BASE64 files. */
      int cert_type = LDAPSSL_CERT_FILETYPE_B64;
      if((data->set.str[STRING_CERT_TYPE]) &&
         (Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER")))
        cert_type = LDAPSSL_CERT_FILETYPE_DER;
      if(!ldap_ca) {
        failf(data, "LDAP local: ERROR %s CA cert not set!",
              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"));
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      infof(data, "LDAP local: using %s CA cert '%s'\n",
              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
              ldap_ca);
      rc = ldapssl_add_trusted_cert(ldap_ca, cert_type);
      if(rc != LDAP_SUCCESS) {
        failf(data, "LDAP local: ERROR setting %s CA cert: %s",
                (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
                ldap_err2string(rc));
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      ldap_option = LDAPSSL_VERIFY_SERVER;
    }
    else
      ldap_option = LDAPSSL_VERIFY_NONE;
    rc = ldapssl_set_verify_mode(ldap_option);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
    server = ldapssl_init(conn->host.name, (int)conn->port, 1);
    if(server == NULL) {
      failf(data, "LDAP local: Cannot connect to %s:%ld",
              conn->host.name, conn->port);
      result = CURLE_COULDNT_CONNECT;
      goto quit;
    }
#elif defined(LDAP_OPT_X_TLS)
    if(data->set.ssl.verifypeer) {
      /* OpenLDAP SDK supports BASE64 files. */
      if((data->set.str[STRING_CERT_TYPE]) &&
         (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
        failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      if(!ldap_ca) {
        failf(data, "LDAP local: ERROR PEM CA cert not set!");
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca);
      rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca);
      if(rc != LDAP_SUCCESS) {
        failf(data, "LDAP local: ERROR setting PEM CA cert: %s",
                ldap_err2string(rc));
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      ldap_option = LDAP_OPT_X_TLS_DEMAND;
    }
    else
      ldap_option = LDAP_OPT_X_TLS_NEVER;

    rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
    server = ldap_init(conn->host.name, (int)conn->port);
    if(server == NULL) {
      failf(data, "LDAP local: Cannot connect to %s:%ld",
              conn->host.name, conn->port);
      result = CURLE_COULDNT_CONNECT;
      goto quit;
    }
    ldap_option = LDAP_OPT_X_TLS_HARD;
    rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
/*
    rc = ldap_start_tls_s(server, NULL, NULL);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
*/
#else
    /* we should probably never come up to here since configure
       should check in first place if we can support LDAP SSL/TLS */
    failf(data, "LDAP local: SSL/TLS not supported with this version "
            "of the OpenLDAP toolkit\n");
    result = CURLE_SSL_CERTPROBLEM;
    goto quit;
#endif
#endif
#endif /* CURL_LDAP_USE_SSL */
  }
  else {
    server = ldap_init(conn->host.name, (int)conn->port);
    if(server == NULL) {
      failf(data, "LDAP local: Cannot connect to %s:%ld",
              conn->host.name, conn->port);
      result = CURLE_COULDNT_CONNECT;
      goto quit;
    }
  }
#ifdef CURL_LDAP_WIN
  ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
#endif

  rc = ldap_simple_bind_s(server,
                          conn->bits.user_passwd ? conn->user : NULL,
                          conn->bits.user_passwd ? conn->passwd : NULL);
  if(!ldap_ssl && rc != 0) {
    ldap_proto = LDAP_VERSION2;
    ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
    rc = ldap_simple_bind_s(server,
                            conn->bits.user_passwd ? conn->user : NULL,
                            conn->bits.user_passwd ? conn->passwd : NULL);
  }
  if(rc != 0) {
    failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
    result = CURLE_LDAP_CANNOT_BIND;
    goto quit;
  }

  rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
                     ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg);

  if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
    failf(data, "LDAP remote: %s", ldap_err2string(rc));
    result = CURLE_LDAP_SEARCH_FAILED;
    goto quit;
  }

  for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg);
      entryIterator;
      entryIterator = ldap_next_entry(server, entryIterator), num++) {
    BerElement *ber = NULL;
    char  *attribute;       /*! suspicious that this isn't 'const' */
    char  *dn = ldap_get_dn(server, entryIterator);
    int i;

    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
    if(result)
      goto quit;

    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)dn, 0);
    if(result)
      goto quit;

    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
    if(result)
      goto quit;

    dlsize += strlen(dn)+5;

    for(attribute = ldap_first_attribute(server, entryIterator, &ber);
        attribute;
        attribute = ldap_next_attribute(server, entryIterator, ber)) {
      BerValue **vals = ldap_get_values_len(server, entryIterator, attribute);

      if(vals != NULL) {
        for(i = 0; (vals[i] != NULL); i++) {
          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
          if(result)
            goto quit;

          result = Curl_client_write(conn, CLIENTWRITE_BODY,
                                     (char *)attribute, 0);
          if(result)
            goto quit;

          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
          if(result)
            goto quit;
          dlsize += strlen(attribute)+3;

          if((strlen(attribute) > 7) &&
              (strcmp(";binary",
                      (char *)attribute +
                      (strlen((char *)attribute) - 7)) == 0)) {
            /* Binary attribute, encode to base64. */
            CURLcode error = Curl_base64_encode(data,
                                                vals[i]->bv_val,
                                                vals[i]->bv_len,
                                                &val_b64,
                                                &val_b64_sz);
            if(error) {
              ldap_value_free_len(vals);
              ldap_memfree(attribute);
              ldap_memfree(dn);
              if(ber)
                ber_free(ber, 0);
              result = error;
              goto quit;
            }
            if(val_b64_sz > 0) {
              result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
                                         val_b64_sz);
              free(val_b64);
              if(result)
                goto quit;
              dlsize += val_b64_sz;
            }
          }
          else {
            result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
                                       vals[i]->bv_len);
            if(result)
              goto quit;
            dlsize += vals[i]->bv_len;
          }
          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
          if(result)
            goto quit;
          dlsize++;
        }

        /* Free memory used to store values */
        ldap_value_free_len(vals);
      }
      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
      if(result)
        goto quit;
      dlsize++;
      Curl_pgrsSetDownloadCounter(data, dlsize);
      ldap_memfree(attribute);
    }
    ldap_memfree(dn);
    if(ber)
       ber_free(ber, 0);
  }

quit:
  if(ldapmsg) {
    ldap_msgfree(ldapmsg);
    LDAP_TRACE (("Received %d entries\n", num));
  }
  if(rc == LDAP_SIZELIMIT_EXCEEDED)
    infof(data, "There are more than %d entries\n", num);
  if(ludp)
    ldap_free_urldesc(ludp);
  if(server)
    ldap_unbind_s(server);
#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK)
  if(ldap_ssl)
    ldapssl_client_deinit();
#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */

  /* no data to transfer */
  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  connclose(conn, "LDAP connection always disable re-use");

  return result;
}
Exemple #9
0
static int do_init (LDAP ** ld, const char *uri, int ldapdefport)
{
	int rc;
	int ldaps;
	char uribuf[512];
	char *p;

	DBG("do_init():");

	ldaps = (strncasecmp (uri, "ldaps://", sizeof ("ldaps://") - 1) == 0);
	p = strchr (uri, ':');
	/* we should be looking for the second instance to find the port number */
	if (p != NULL)
	{
		p = strchr (p, ':');
	}

#ifdef HAVE_LDAP_INITIALIZE
	if (p == NULL &&
		((ldaps && ldapdefport != LDAPS_PORT) || (!ldaps && ldapdefport != LDAP_PORT)))
	{
		/* No port specified in URI and non-default port specified */
		snprintf (uribuf, sizeof (uribuf), "%s:%d", uri, ldapdefport);
		uri = uribuf;
	}
	rc = ldap_initialize (ld, uri);
#else
	/* TODO: !HAVE_LDAP_INITIALIZE => no ldaps:// possible? */
	if (strncasecmp (uri, "ldap://", sizeof ("ldap://") - 1) != 0)
    {
		return LDAP_UNAVAILABLE;
    }

	uri += sizeof ("ldap://") - 1;
	p = strchr (uri, ':');

	if (p != NULL)
    {
		size_t urilen = (p - uri);

		if (urilen >= sizeof (uribuf))
		{
			return LDAP_UNAVAILABLE;
		}

		memcpy (uribuf, uri, urilen);
		uribuf[urilen] = '\0';

		ldapdefport = atoi (p + 1);
		uri = uribuf;
	}

# ifdef HAVE_LDAP_INIT
	*ld = ldap_init (uri, ldapdefport);
# else
	*ld = ldap_open (uri, ldapdefport);
# endif
	rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS;

#endif /* HAVE_LDAP_INITIALIZE */

	if (rc == LDAP_SUCCESS && *ld == NULL)
	{
	  	rc = LDAP_UNAVAILABLE;
	}
	return rc;
}
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");
    }
}
Exemple #11
0
LDAP *
cldap_open( char *host, int port )
{
    int 		s;
    in_addr_t		address;
    struct sockaddr_in 	sock;
    struct hostent	*hp;
    LDAP		*ld;
    char		*p;
    int		i;
#ifdef SUN
    struct hostent      hpret;
    char                hpbuf[NSS_BUFLEN_HOSTS];
    int                 hperrno;
#endif
    in_addr_t inet_addr(const char *);
    int close(int);

    Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 113, "ldap_open\n"), 0, 0, 0 );

    if ( port == 0 ) {
	    port = LDAP_PORT;
    }

    if ( (s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
	return( NULL );
    }

    sock.sin_addr.s_addr = 0;
    sock.sin_family = AF_INET;
    sock.sin_port = 0;
    if ( bind(s, (struct sockaddr *) &sock, sizeof(sock)) < 0)  {
	close( s );
	return( NULL );
    }

    if (( ld = ldap_init( host, port )) == NULL ) {
	close( s );
	return( NULL );
    }
    if ( (ld->ld_sb.sb_fromaddr = (void *) calloc( 1,
	    sizeof( struct sockaddr ))) == NULL ) {
	free( ld );
	close( s );
	return( NULL );
    }	
    ld->ld_sb.sb_sd = s;
    ld->ld_sb.sb_naddr = 0;
    ld->ld_version = LDAP_VERSION;

    sock.sin_family = AF_INET;
    sock.sin_port = htons( port );

    /*
     * 'host' may be a space-separated list.
     */
    if ( host != NULL ) {
	for ( ; host != NULL; host = p ) {
	    if (( p = strchr( host, ' ' )) != NULL ) {
		for (*p++ = '\0'; *p == ' '; p++) {
		    ;
		}
	    }

	    if ( (address = inet_addr( host )) == -1 ) {
#ifdef SUN
		if ( (hp = gethostbyname_r( host, &hpret, hpbuf, NSS_BUFLEN_HOSTS, &hperrno)) == NULL ) {
		    errno = EHOSTUNREACH;
		    continue;
		}
#else
		if ( (hp = gethostbyname( host )) == NULL ) {
		    errno = EHOSTUNREACH;
		    continue;
		}
#endif

		for ( i = 0; hp->h_addr_list[ i ] != 0; ++i ) {
		    SAFEMEMCPY( (char *)&sock.sin_addr.s_addr,
			    (char *)hp->h_addr_list[ i ],
			    sizeof(sock.sin_addr.s_addr));
		    if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
			close( s );
			free( ld );
			return( NULL );
		    }
		}

	    } else {
		sock.sin_addr.s_addr = address;
		if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
		    close( s );
		    free( ld );
		    return( NULL );
		}
	    }

	    if ( ld->ld_host == NULL ) {
		    ld->ld_host = strdup( host );
	    }
	}

    } else {
	address = INADDR_LOOPBACK;
	sock.sin_addr.s_addr = htonl( address );
	if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
	    close( s );
	    free( ld );
	    return( NULL );
	}
    }

    if ( ld->ld_sb.sb_addrs == NULL
#ifdef LDAP_REFERRALS
	    || ( ld->ld_defconn = new_connection( ld, NULL, 1,0,0 )) == NULL
#endif /* LDAP_REFERRALS */
	    ) {
	free( ld );
	return( NULL );
    }

    ld->ld_sb.sb_useaddr = ld->ld_sb.sb_addrs[ 0 ];
    cldap_setretryinfo( ld, 0, 0 );

#ifdef LDAP_DEBUG
    putchar( '\n' );
    for ( i = 0; i < ld->ld_sb.sb_naddr; ++i ) {
	Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 114, "end of cldap_open address %1$d is %2$s\n"),
		i, inet_ntoa( ((struct sockaddr_in *)
		ld->ld_sb.sb_addrs[ i ])->sin_addr ), 0 );
    }
#endif

    return( ld );
}
Exemple #12
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;
}
Exemple #13
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;
}
/*
 * fetches a binary blob from an ldap url
 */
static err_t
fetch_ldap_url(char *url, chunk_t *blob)
{
    LDAPURLDesc *lurl;
    err_t ugh = NULL;
    int rc;

    DBG(DBG_CONTROL,
	DBG_log("Trying LDAP URL '%s'", url)
    )

    rc = ldap_url_parse(url, &lurl);
    
    if (rc == LDAP_SUCCESS)
    {
	LDAP *ldap = ldap_init(lurl->lud_host, lurl->lud_port);

	if (ldap != NULL)
	{
	    int ldap_version = (LDAP_VER == 2)? LDAP_VERSION2 : LDAP_VERSION3;
	    struct timeval timeout;

	    timeout.tv_sec  = FETCH_CMD_TIMEOUT;
	    timeout.tv_usec = 0;
	    ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
	    ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);

	    rc = ldap_simple_bind_s(ldap, NULL, NULL);

	    if (rc == LDAP_SUCCESS)
	    {
		LDAPMessage *result;

		timeout.tv_sec = FETCH_CMD_TIMEOUT;
		timeout.tv_usec = 0;
		
		rc = ldap_search_st(ldap, lurl->lud_dn
					, lurl->lud_scope
					, lurl->lud_filter
					, lurl->lud_attrs
					, 0, &timeout, &result);

		if (rc == LDAP_SUCCESS)
		{
		    ugh = parse_ldap_result(ldap, result, blob);
		    ldap_msgfree(result);
		}
		else
		{
		    ugh = ldap_err2string(rc);
		}
	    }
	    else
	    {
		ugh = ldap_err2string(rc);
	    }
	    ldap_unbind_s(ldap);
	}
	else
	{
	    ugh = "ldap init";
	}
	ldap_free_urldesc(lurl);
    }
    else
    {
	ugh = ldap_err2string(rc);
    }
    return ugh;
}
Exemple #15
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;
}
Exemple #16
0
/*
 * This function will look in ldap id the token correspond to the
 * requested user. It will returns 0 for failure and 1 for success.
 *
 * For the moment ldaps is not supported. ldap serve can be on a
 * remote host.
 *
 * You need the following parameters in you pam config:
 * ldapserver=  OR ldap_uri=
 * ldapdn=
 * user_attr=
 * yubi_attr=
 *
 */
static int
authorize_user_token_ldap (struct cfg *cfg,
                           const char *user,
                           const char *token_id)
{
    DBG(("called"));
    int retval = 0;
    int protocol;
#ifdef HAVE_LIBLDAP
    LDAP *ld = NULL;
    LDAPMessage *result = NULL, *e;
    BerElement *ber;
    char *a;
    char *attrs[2] = {NULL, NULL};

    struct berval **vals;
    int i, rc;

    char *find = NULL, *sr = NULL;

    if (cfg->user_attr == NULL) {
        DBG (("Trying to look up user to YubiKey mapping in LDAP, but user_attr not set!"));
        return 0;
    }
    if (cfg->yubi_attr == NULL) {
        DBG (("Trying to look up user to YubiKey mapping in LDAP, but yubi_attr not set!"));
        return 0;
    }
    if (cfg->ldapdn == NULL) {
        DBG (("Trying to look up user to YubiKey mapping in LDAP, but ldapdn not set!"));
        return 0;
    }

    /* Get a handle to an LDAP connection. */
    if (cfg->ldap_uri)
    {
        rc = ldap_initialize (&ld, cfg->ldap_uri);
        if (rc != LDAP_SUCCESS)
        {
            DBG (("ldap_init: %s", ldap_err2string (rc)));
            retval = 0;
            goto done;
        }
    }
    else
    {
        if ((ld = ldap_init (cfg->ldapserver, PORT_NUMBER)) == NULL)
        {
            DBG (("ldap_init"));
            retval = 0;
            goto done;
        }
    }

    /* LDAPv2 is historical -- RFC3494. */
    protocol = LDAP_VERSION3;
    ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &protocol);

    /* Bind anonymously to the LDAP server. */
    rc = ldap_simple_bind_s (ld, NULL, NULL);
    if (rc != LDAP_SUCCESS)
    {
        DBG (("ldap_simple_bind_s: %s", ldap_err2string (rc)));
        retval = 0;
        goto done;
    }

    /* Allocation of memory for search strings depending on input size */
    find = malloc((strlen(cfg->user_attr)+strlen(cfg->ldapdn)+strlen(user)+3)*sizeof(char));

    sprintf (find, "%s=%s,%s", cfg->user_attr, user, cfg->ldapdn);

    attrs[0] = (char *) cfg->yubi_attr;

    DBG(("LDAP : look up object '%s', ask for attribute '%s'", find, cfg->yubi_attr));

    /* Search for the entry. */
    if ((rc = ldap_search_ext_s (ld, find, LDAP_SCOPE_BASE,
                                 NULL, attrs, 0, NULL, NULL, LDAP_NO_LIMIT,
                                 LDAP_NO_LIMIT, &result)) != LDAP_SUCCESS)
    {
        DBG (("ldap_search_ext_s: %s", ldap_err2string (rc)));

        retval = 0;
        goto done;
    }

    e = ldap_first_entry (ld, result);
    if (e == NULL)
    {
        DBG (("No result from LDAP search"));
    }
    else
    {
        /* Iterate through each returned attribute. */
        for (a = ldap_first_attribute (ld, e, &ber);
                a != NULL; a = ldap_next_attribute (ld, e, ber))
        {
            if ((vals = ldap_get_values_len (ld, e, a)) != NULL)
            {
                /* Compare each value for the attribute against the token id. */
                for (i = 0; vals[i] != NULL; i++)
                {
                    if (!strncmp (token_id, vals[i]->bv_val, strlen (token_id)))
                    {
                        DBG (("Token Found :: %s", vals[i]->bv_val));
                        retval = 1;
                    }
                    else
                    {
                        DBG (("No match : (%s) %s != %s", a, vals[i]->bv_val, token_id));
                    }
                }
                ldap_value_free_len (vals);
            }
            ldap_memfree (a);
        }
        if (ber != NULL)
            ber_free (ber, 0);
    }

done:
    if (result != NULL)
        ldap_msgfree (result);
    if (ld != NULL)
        ldap_unbind (ld);

    /* free memory allocated for search strings */
    if (find != NULL)
        free(find);
    if (sr != NULL)
        free(sr);

#else
    DBG (("Trying to use LDAP, but this function is not compiled in pam_yubico!!"));
    DBG (("Install libldap-dev and then recompile pam_yubico."));
#endif
    return retval;
}
static void
do_modrdn( char *uri, char *host, int port, char *manager,
	char *passwd, char *entry, int maxloop )
{
	LDAP	*ld = NULL;
	int  	i;
	pid_t	pid;
	char *DNs[2];
	char *rdns[2];

	pid = getpid();
	DNs[0] = entry;
	DNs[1] = strdup( entry );

	/* reverse the RDN, make new DN */
	{
		char *p1, *p2;

		p1 = strchr( entry, '=' ) + 1;
		p2 = strchr( p1, ',' );

		*p2 = '\0';
		rdns[1] = strdup( entry );
		*p2-- = ',';

		for (i = p1 - entry;p2 >= p1;)
			DNs[1][i++] = *p2--;
		
		DNs[1][i] = '\0';
		rdns[0] = strdup( DNs[1] );
		DNs[1][i] = ',';
	}
		
	if ( uri ) {
		ldap_initialize( &ld, uri );
	} else {
		ld = ldap_init( host, port );
	}
	if ( ld == NULL ) {
		perror( "ldap_init" );
		exit( EXIT_FAILURE );
	}

	{
		int version = LDAP_VERSION3;
		(void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
			&version ); 
	}

	if ( ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE ) != LDAP_SUCCESS ) {
		ldap_perror( ld, "ldap_bind" );
		 exit( EXIT_FAILURE );
	}


	fprintf( stderr, "PID=%ld - Modrdn(%d): entry=\"%s\".\n",
		 (long) pid, maxloop, entry );

	for ( i = 0; i < maxloop; i++ ) {
		int         rc;

		if (( rc = ldap_modrdn2_s( ld, DNs[0], rdns[0], 0 ))
			!= LDAP_SUCCESS ) {
			ldap_perror( ld, "ldap_modrdn" );
			if ( rc != LDAP_NO_SUCH_OBJECT ) break;
			continue;
		}
		if (( rc = ldap_modrdn2_s( ld, DNs[1], rdns[1], 1 ))
			!= LDAP_SUCCESS ) {
			ldap_perror( ld, "ldap_modrdn" );
			if ( rc != LDAP_NO_SUCH_OBJECT ) break;
			continue;
		}
	}

	fprintf( stderr, " PID=%ld - Modrdn done.\n", (long) pid );

	ldap_unbind( ld );
}
Exemple #18
0
CURLcode Curl_ldap(struct connectdata *conn)
{
  CURLcode status = CURLE_OK;
  int rc;
  void *(*ldap_init)(char *, int);
  int (*ldap_simple_bind_s)(void *, char *, char *);
  int (*ldap_unbind_s)(void *);
  int (*ldap_url_parse)(char *, LDAPURLDesc **);
  void (*ldap_free_urldesc)(void *);
  int (*ldap_search_s)(void *, char *, int, char *, char **, int, void **);
  int (*ldap_search_st)(void *, char *, int, char *, char **, int, void *, void **);
  void *(*ldap_first_entry)(void *, void *);
  void *(*ldap_next_entry)(void *, void *);
  char *(*ldap_err2string)(int);
  char *(*ldap_get_dn)(void *, void *);
  char *(*ldap_first_attribute)(void *, void *, void **);
  char *(*ldap_next_attribute)(void *, void *, void *);
  char **(*ldap_get_values)(void *, void *, char *);
  void (*ldap_value_free)(char **);
  void (*ldap_memfree)(void *);
  void (*ber_free)(void *, int);
 
  void *server;
  LDAPURLDesc *ludp;
  void *result;
  void *entryIterator;
  void *ber;
  void *attribute;

  struct SessionHandle *data=conn->data;
  
  infof(data, "LDAP: %s\n", data->change.url);

  DynaOpen();
  if (libldap == NULL) {
    failf(data, "The needed LDAP library/libraries couldn't be opened");
    return CURLE_LIBRARY_NOT_FOUND;
  }

  /* The types are needed because ANSI C distinguishes between
   * pointer-to-object (data) and pointer-to-function.
   */
  DYNA_GET_FUNCTION(void *(*)(char *, int), ldap_init);
  DYNA_GET_FUNCTION(int (*)(void *, char *, char *), ldap_simple_bind_s);
  DYNA_GET_FUNCTION(int (*)(void *), ldap_unbind_s);
  DYNA_GET_FUNCTION(int (*)(char *, LDAPURLDesc **), ldap_url_parse);
  DYNA_GET_FUNCTION(void (*)(void *), ldap_free_urldesc);
  DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int, void **), ldap_search_s);
  DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int, void *, void **), ldap_search_st);
  DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_first_entry);
  DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_next_entry);
  DYNA_GET_FUNCTION(char *(*)(int), ldap_err2string);
  DYNA_GET_FUNCTION(char *(*)(void *, void *), ldap_get_dn);
  DYNA_GET_FUNCTION(char *(*)(void *, void *, void **), ldap_first_attribute);
  DYNA_GET_FUNCTION(char *(*)(void *, void *, void *), ldap_next_attribute);
  DYNA_GET_FUNCTION(char **(*)(void *, void *, char *), ldap_get_values);
  DYNA_GET_FUNCTION(void (*)(char **), ldap_value_free);
  DYNA_GET_FUNCTION(void (*)(void *), ldap_memfree);
  DYNA_GET_FUNCTION(void (*)(void *, int), ber_free);
  
  server = ldap_init(conn->hostname, conn->port);
  if (server == NULL) {
    failf(data, "LDAP: Cannot connect to %s:%d",
	  conn->hostname, conn->port);
    status = CURLE_COULDNT_CONNECT;
  }
  else {
    rc = ldap_simple_bind_s(server,
                            conn->bits.user_passwd?conn->user:NULL,
                            conn->bits.user_passwd?conn->passwd:NULL);
    if (rc != 0) {
      failf(data, "LDAP: %s", ldap_err2string(rc));
      status = CURLE_LDAP_CANNOT_BIND;
    }
    else {
      rc = ldap_url_parse(data->change.url, &ludp);
      if (rc != 0) {
	failf(data, "LDAP: %s", ldap_err2string(rc));
	status = CURLE_LDAP_INVALID_URL;
      }
      else {
	rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
                           ludp->lud_filter, ludp->lud_attrs, 0, &result);
	if (rc != 0) {
	  failf(data, "LDAP: %s", ldap_err2string(rc));
	  status = CURLE_LDAP_SEARCH_FAILED;
	}
	else {
	  for (entryIterator = ldap_first_entry(server, result);
	       entryIterator;
	       entryIterator = ldap_next_entry(server, entryIterator)) {
            char *dn = ldap_get_dn(server, entryIterator);
            char **vals;
            int i;
            
            Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
            Curl_client_write(data, CLIENTWRITE_BODY, dn, 0);
            Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
            for(attribute = ldap_first_attribute(server, entryIterator,
                                                 &ber); 
                attribute; 
                attribute = ldap_next_attribute(server, entryIterator,
                                                ber) ) {
              vals = ldap_get_values(server, entryIterator, attribute);
              if (vals != NULL) {
                for(i = 0; (vals[i] != NULL); i++) {
                  Curl_client_write(data, CLIENTWRITE_BODY, (char*)"\t", 1);
                  Curl_client_write(data, CLIENTWRITE_BODY, attribute, 0);
                  Curl_client_write(data, CLIENTWRITE_BODY, (char *)": ", 2);
                  Curl_client_write(data, CLIENTWRITE_BODY, vals[i], 0);
                  Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
                }
              }

              /* Free memory used to store values */
              ldap_value_free(vals);
            }
            Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
            
            ldap_memfree(attribute);
            ldap_memfree(dn);
            if (ber) ber_free(ber, 0);
          }
	}

	ldap_free_urldesc(ludp);
      }
      ldap_unbind_s(server);
    }
  }
  DynaClose();

  /* no data to transfer */
  Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  
  return status;
}
Exemple #19
0
int
main( int argc, char **argv )
{
	LDAP			*ld;
	LDAPMessage		*result, *e;
	char			*attrfail, *matched = NULL, *errmsg = NULL;
	char			**vals, **referrals;
	int			rc, parse_rc, version;
	unsigned long		sortrc;
	LDAPControl		*sortctrl = NULL;
	LDAPControl		*requestctrls[ 2 ];
	LDAPControl		**resultctrls = NULL;
	LDAPsortkey		**sortkeylist;

	/* Arrange for all connections to use LDAPv3 */
	version = LDAP_VERSION3;
	if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version )
	    != 0 ) {
		fprintf( stderr,
		    "ldap_set_option protocol version to %d failed\n",
		    version );
		return( 1 );
	}

	/* Get a handle to an LDAP connection */
	if ( (ld = ldap_init( MY_HOST, MY_PORT ) ) == NULL ) {
		perror( "ldap_init" );
		return( 1 );
	}

	/* Authenticate as Directory Manager */
	if ( ldap_simple_bind_s( ld, MGR_DN, MGR_PW ) != LDAP_SUCCESS ) {
		ldap_perror( ld, "ldap_simple_bind_s" );
		ldap_unbind( ld );
		return( 1 );
	}

	/*
	 * Create a sort key list that specifies the sort order of the results.
	 * Sort the results by last name first, then by first name.
	 */
	ldap_create_sort_keylist( &sortkeylist, "description -givenname" );

	/* Create the sort control. */
	rc = ldap_create_sort_control( ld, sortkeylist, 1, &sortctrl );
	if ( rc != LDAP_SUCCESS ) {
		fprintf( stderr, "ldap_create_sort_control: %s\n",
		    ldap_err2string( rc ) );
		ldap_unbind( ld );
		return( 1 );
	}
	requestctrls[ 0 ] = sortctrl;
	requestctrls[ 1 ] = NULL;

	/* Search for all entries in Sunnyvale */

	rc = ldap_search_ext_s( ld, PEOPLE_BASE, LDAP_SCOPE_SUBTREE,
	    "(objectclass=person)", NULL, 0, requestctrls, NULL, NULL, 0,
	    &result );

	if ( rc != LDAP_SUCCESS ) {
		fprintf( stderr, "ldap_search_ext_s: %s\n",
		    ldap_err2string( rc ) );
		ldap_unbind( ld );
		return( 1 );
	}

	parse_rc = ldap_parse_result( ld, result, &rc, &matched, &errmsg,
	    &referrals, &resultctrls, 0 );

	if ( parse_rc != LDAP_SUCCESS ) {
		fprintf( stderr, "ldap_parse_result: %s\n",
		    ldap_err2string( parse_rc ) );
		ldap_unbind( ld );
		return( 1 );
	}

	if ( rc != LDAP_SUCCESS ) {
		fprintf( stderr, "ldap_search_ext_s: %s\n",
		    ldap_err2string( rc ) );
		if ( errmsg != NULL && *errmsg != '\0' ) {
			fprintf( stderr, "%s\n", errmsg );
		}

		ldap_unbind( ld );
		return( 1 );
	}

	parse_rc = ldap_parse_sort_control( ld, resultctrls, &sortrc,
	    &attrfail );

	if ( parse_rc != LDAP_SUCCESS ) {
		fprintf( stderr, "ldap_parse_sort_control: %s\n",
		    ldap_err2string( parse_rc ) );
		ldap_unbind( ld );
		return( 1 );
	}

	if ( sortrc != LDAP_SUCCESS ) {
		fprintf( stderr, "Sort error: %s\n", ldap_err2string( sortrc ));
		if ( attrfail != NULL && *attrfail != '\0' ) {
			fprintf( stderr, "Bad attribute: %s\n", attrfail);
		}
		ldap_unbind( ld );
		return( 1 );
	}

	/* for each entry print out name + all attrs and values */
	for ( e = ldap_first_entry( ld, result ); e != NULL;
	    e = ldap_next_entry( ld, e ) ) {
		if ((vals = ldap_get_values( ld, e, "sn")) != NULL ) {
			if ( vals[0] != NULL ) {
				printf( "%s", vals[0] );
			}
			ldap_value_free( vals );
		}

		if ((vals = ldap_get_values( ld, e, "givenname")) != NULL ) {
			if ( vals[0] != NULL ) {
				printf( "\t%s", vals[0] );
			}
			ldap_value_free( vals );
		}

		putchar( '\n' );
	}

	ldap_msgfree( result );
	ldap_free_sort_keylist( sortkeylist );
	ldap_control_free( sortctrl );
	ldap_controls_free( resultctrls );
	ldap_unbind( ld );

	return( 0 );
}
Exemple #20
0
/** Initialise libldap and check library versions
 *
 * @return
 *	- 0 on success.
 *	- -1 on failure.
 */
int fr_ldap_init(void)
{
	int			ldap_errno;
	static LDAPAPIInfo	info = { .ldapai_info_version = LDAP_API_INFO_VERSION };	/* static to quiet valgrind about this being uninitialised */
	fr_ldap_config_t	*handle_config = &ldap_global_handle_config;

	if (instance_count > 0) {
		instance_count++;
		return 0;
	}

	/*
	 *	Only needs to be done once, prevents races in environment
	 *	initialisation within libldap.
	 *
	 *	See: https://github.com/arr2036/ldapperf/issues/2
	 */
#ifdef HAVE_LDAP_INITIALIZE
	ldap_initialize(&ldap_global_handle, "");
#else
	ldap_global_handle = ldap_init("", 0);
#endif
	if (!ldap_global_handle) {
		ERROR("Failed initialising global LDAP handle");
		return -1;
	}

	ldap_errno = ldap_get_option(NULL, LDAP_OPT_API_INFO, &info);
	if (ldap_errno == LDAP_OPT_SUCCESS) {
		/*
		 *	Don't generate warnings if the compile type vendor name
		 *	is found within the link time vendor name.
		 *
		 *	This allows the server to be built against OpenLDAP but
		 *	run with Symas OpenLDAP.
		 */
		if (strcasestr(info.ldapai_vendor_name, LDAP_VENDOR_NAME) == NULL) {
			WARN("ldap - libldap vendor changed since the server was built");
			WARN("ldap - linked: %s, built: %s", info.ldapai_vendor_name, LDAP_VENDOR_NAME);
		}

		if (info.ldapai_vendor_version < LDAP_VENDOR_VERSION) {
			WARN("ldap - libldap older than the version the server was built against");
			WARN("ldap - linked: %i, built: %i",
			     info.ldapai_vendor_version, LDAP_VENDOR_VERSION);
		}

		INFO("ldap - libldap vendor: %s, version: %i", info.ldapai_vendor_name,
		     info.ldapai_vendor_version);

		if (info.ldapai_extensions) {
			char **p;

			for (p = info.ldapai_extensions; *p != NULL; p++) {
				INFO("ldap - extension: %s", *p);
				ldap_memfree(*p);
			}

			ldap_memfree(info.ldapai_extensions);
		}

		ldap_memfree(info.ldapai_vendor_name);

	} else {
		DEBUG("ldap - Falling back to build time libldap version info.  Query for LDAP_OPT_API_INFO "
		      "returned: %i", ldap_errno);
		INFO("ldap - libldap vendor: %s, version: %i.%i.%i", LDAP_VENDOR_NAME,
		     LDAP_VENDOR_VERSION_MAJOR, LDAP_VENDOR_VERSION_MINOR, LDAP_VENDOR_VERSION_PATCH);
	}

	instance_count++;

	return 0;
}
int
main( int argc, char **argv )
{
    LDAP	    	*ld;
    LDAPMessage	    	*result, *e;
    BerElement	    	*ber;
    char	    	*host, *a, *dn;
    char	  	**vals;
    int		    	i;
    int		   	rc;
    int			finished;
    int			msgid;
    int			num_entries = 0;
    struct timeval	zerotime;

    if ( argc > 1 ) {
	host = argv[1];
    } else {
	host = MY_HOST;
    }

    zerotime.tv_sec = zerotime.tv_usec = 0L;

    if ( prldap_install_routines( NULL, 1 /* shared */ ) != LDAP_SUCCESS ) {
	ldap_perror( NULL, "prldap_install_routines" );
	return( 1 );
    }

    /* get a handle to an LDAP connection */
    if ( (ld = ldap_init( host, MY_PORT )) == NULL ) {
	perror( host );
	return( 1 );
    }

    /* authenticate to the directory as nobody */
    if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
	ldap_perror( ld, "ldap_simple_bind_s" );
	return( 1 );
    }
    /* search for all entries with surname of Jensen */
    if (( msgid = ldap_search( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE,
	    MY_FILTER, NULL, 0 )) < 0 ) {
	ldap_perror( ld, "ldap_search" );
	return( 1 );
    }

    /* Loop, polling for results until finished */
    finished = 0;
    while ( !finished ) {
	/*
	 * Poll for results.   We call ldap_result with the "all" argument
	 * set to LDAP_MSG_ONE.  This causes ldap_result() to return exactly one
	 * entry if at least one entry is available.  This allows us to
	 * display the entries as they are received.
	 */
	result = NULL;
	rc = ldap_result( ld, msgid, LDAP_MSG_ONE, &zerotime, &result );
	switch ( rc ) {
	case -1:
	    /* some error occurred */
	    ldap_perror( ld, "ldap_result" );
	    return( 1 );
	case 0:
	    /* Timeout was exceeded.  No entries are ready for retrieval. */
	    if ( result != NULL ) {
		ldap_msgfree( result );
	    }
	    break;
	default:
	    /*
	     * Either an entry is ready for retrieval, or all entries have
	     * been retrieved.
	     */
	    if (( e = ldap_first_entry( ld, result )) == NULL ) {
		/* All done */
		finished = 1;
		if ( result != NULL ) {
		    ldap_msgfree( result );
		}
		continue;
	    }
	    /* for each entry print out name + all attrs and values */
	    num_entries++;
	    if (( dn = ldap_get_dn( ld, e )) != NULL ) {
		printf( "dn: %s\n", dn );
		ldap_memfree( dn );
	    }
	    for ( a = ldap_first_attribute( ld, e, &ber );
		    a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
		if (( vals = ldap_get_values( ld, e, a )) != NULL ) {
		    for ( i = 0; vals[ i ] != NULL; i++ ) {
			printf( "%s: %s\n", a, vals[ i ] );
		    }
		    ldap_value_free( vals );
		}
		ldap_memfree( a );
	    }
	    if ( ber != NULL ) {
		ber_free( ber, 0 );
	    }
	    printf( "\n" );
	    ldap_msgfree( result );
	}
	/* Do other work here while you are waiting... */
	do_other_work();
    }

    /* All done.  Print a summary. */
    printf( "%d entries retrieved.  I counted to %ld "
	    "while I was waiting.\n", num_entries,
	    global_counter );
    ldap_unbind( ld );
    return( 0 );
}
Exemple #22
0
int
main( int argc, char **argv )
{
    LDAP		*ld;
    LDAPMessage		*result, *e;
    char		**vals, *attrs[ 5 ];
    int			i;

    /* get a handle to an LDAP connection */
    if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) {
	perror( "ldap_init" );
	return( 1 );
    }

    attrs[ 0 ] = "cn";			/* Get canonical name(s) (full name) */
    attrs[ 1 ] = "sn";			/* Get surname(s) (last name) */
    attrs[ 2 ] = "mail";		/* Get email address(es) */
    attrs[ 3 ] = "telephonenumber";	/* Get telephone number(s) */
    attrs[ 4 ] = NULL;

    if ( ldap_search_s( ld, ENTRYDN, LDAP_SCOPE_BASE,
	    "(objectclass=*)", attrs, 0, &result ) != LDAP_SUCCESS ) {
	ldap_perror( ld, "ldap_search_s" );
	return( 1 );
    }

    /* print it out */
    if (( e = ldap_first_entry( ld, result )) != NULL ) {
	if (( vals = ldap_get_values( ld, e, "cn" )) != NULL ) {
	    printf( "Full name:\n" );
	    for ( i = 0; vals[i] != NULL; i++ ) {
		printf( "\t%s\n", vals[i] );
	    }
	    ldap_value_free( vals );
	}
	if (( vals = ldap_get_values( ld, e, "sn" )) != NULL ) {
	    printf( "Last name (surname):\n" );
	    for ( i = 0; vals[i] != NULL; i++ ) {
		printf( "\t%s\n", vals[i] );
	    }
	    ldap_value_free( vals );
	}
	if (( vals = ldap_get_values( ld, e, "mail" )) != NULL ) {
	    printf( "Email address:\n" );
	    for ( i = 0; vals[i] != NULL; i++ ) {
		printf( "\t%s\n", vals[i] );
	    }
	    ldap_value_free( vals );
	}
	if (( vals = ldap_get_values( ld, e, "telephonenumber" )) != NULL ) {
	    printf( "Telephone number:\n" );
	    for ( i = 0; vals[i] != NULL; i++ ) {
		printf( "\t%s\n", vals[i] );
	    }
	    ldap_value_free( vals );
	}
    }
    ldap_msgfree( result );
    ldap_unbind( ld );
    return( 0 );
}
Exemple #23
0
/*
 * Map key -> value resolution
 * NOTE: these are old-fashion maps; new maps will be parsed on separate
 * config lines, and referred by name.
 */
int
rewrite_xmap_apply(
		struct rewrite_info *info,
		struct rewrite_op *op,
		struct rewrite_map *map,
		struct berval *key,
		struct berval *val
)
{
	int rc = REWRITE_SUCCESS;
	
	assert( info != NULL );
	assert( op != NULL );
	assert( map != NULL );
	assert( key != NULL );
	assert( val != NULL );
	
	val->bv_val = NULL;
	val->bv_len = 0;
	
	switch ( map->lm_type ) {
#ifdef HAVE_GETPWNAM
	case REWRITE_MAP_XPWDMAP: {
		struct passwd *pwd;

#ifdef USE_REWRITE_LDAP_PVT_THREADS
		ldap_pvt_thread_mutex_lock( &xpasswd_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
		
		pwd = getpwnam( key->bv_val );
		if ( pwd == NULL ) {

#ifdef USE_REWRITE_LDAP_PVT_THREADS
			ldap_pvt_thread_mutex_unlock( &xpasswd_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

			rc = LDAP_NO_SUCH_OBJECT;
			break;
		}

#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
		if ( pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0' ) {
			int l = strlen( pwd->pw_gecos );
			
			val->bv_val = strdup( pwd->pw_gecos );
			val->bv_len = l;
		} else
#endif /* HAVE_STRUCT_PASSWD_PW_GECOS */
		{
			val->bv_val = strdup( key->bv_val );
			val->bv_len = key->bv_len;
		}

#ifdef USE_REWRITE_LDAP_PVT_THREADS
		ldap_pvt_thread_mutex_unlock( &xpasswd_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

		if ( val->bv_val == NULL ) {
			rc = REWRITE_ERR;
		}
		break;
	}
#endif /* HAVE_GETPWNAM*/
	
	case REWRITE_MAP_XFILEMAP: {
		char buf[1024];
		
		if ( map->lm_args == NULL ) {
			rc = REWRITE_ERR;
			break;
		}
		
#ifdef USE_REWRITE_LDAP_PVT_THREADS
		ldap_pvt_thread_mutex_lock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

		rewind( ( FILE * )map->lm_args );
		
		while ( fgets( buf, sizeof( buf ), ( FILE * )map->lm_args ) ) {
			char *p;
			int blen;
			
			blen = strlen( buf );
			if ( buf[ blen - 1 ] == '\n' ) {
				buf[ blen - 1 ] = '\0';
			}
			
			p = strtok( buf, " " );
			if ( p == NULL ) {
#ifdef USE_REWRITE_LDAP_PVT_THREADS
				ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
				rc = REWRITE_ERR;
				goto rc_return;
			}
			if ( strcasecmp( p, key->bv_val ) == 0 
					&& ( p = strtok( NULL, "" ) ) ) {
				val->bv_val = strdup( p );
				if ( val->bv_val == NULL ) {
					return REWRITE_ERR;
				}

				val->bv_len = strlen( p );
				
#ifdef USE_REWRITE_LDAP_PVT_THREADS
				ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
				
				goto rc_return;
			}
		}

#ifdef USE_REWRITE_LDAP_PVT_THREADS
		ldap_pvt_thread_mutex_unlock( &map->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

		rc = REWRITE_ERR;
		
		break;
	}

	case REWRITE_MAP_XLDAPMAP: {
		LDAP *ld;
		char filter[1024];
		LDAPMessage *res = NULL, *entry;
		LDAPURLDesc *lud = ( LDAPURLDesc * )map->lm_args;
		int attrsonly = 0;
		char **values;

		assert( lud != NULL );

		/*
		 * No mutex because there is no write on the map data
		 */
		
		ld = ldap_init( lud->lud_host, lud->lud_port );
		if ( ld == NULL ) {
			rc = REWRITE_ERR;
			goto rc_return;
		}

		snprintf( filter, sizeof( filter ), lud->lud_filter,
				key->bv_val );

		if ( strcasecmp( lud->lud_attrs[ 0 ], "dn" ) == 0 ) {
			attrsonly = 1;
		}
		rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope,
				filter, lud->lud_attrs, attrsonly, &res );
		if ( rc != LDAP_SUCCESS ) {
			ldap_unbind( ld );
			rc = REWRITE_ERR;
			goto rc_return;
		}

		if ( ldap_count_entries( ld, res ) != 1 ) {
			ldap_unbind( ld );
			rc = REWRITE_ERR;
			goto rc_return;
		}

		entry = ldap_first_entry( ld, res );
		if ( entry == NULL ) {
			ldap_msgfree( res );
			ldap_unbind( ld );
			rc = REWRITE_ERR;
			goto rc_return;
		}
		if ( attrsonly == 1 ) {
			val->bv_val = ldap_get_dn( ld, entry );

		} else {
			values = ldap_get_values( ld, entry,
					lud->lud_attrs[0] );
			if ( values != NULL ) {
				val->bv_val = strdup( values[ 0 ] );
				ldap_value_free( values );
			}
		}

		ldap_msgfree( res );
		ldap_unbind( ld );
		
		if ( val->bv_val == NULL ) {
			rc = REWRITE_ERR;
			goto rc_return;
		}
		val->bv_len = strlen( val->bv_val );

		rc = REWRITE_SUCCESS;
	} break;
	}

rc_return:;
	return rc;
}
int
abook_ldap_searchstart(abook_ldap_state **ldap_state, 
		       abook_fielddata *flist, int fcount)
{
    abook_ldap_state *mystate;
    int msgid, rc;
    int sizelimit;
    char *msg;
    char *attrs[20];
    LDAP *ld;
    LDAPMessage *result;
    char *filter, *secondaryfilter;

    int searching_secondary = 0;

    if (config_ldap() < 0) {
	syslog(LOG_ERR, "abook_ldap_searchstart: failed to configure LDAP");
	return -1;
    }
    
    if (imsp_to_ldap_filter(flist, fcount, &filter, config) < 0) {
	syslog(LOG_ERR, "abook_ldap_searchstart: failed to convert filter");
	return -1;
    }

    ld = ldap_init(config.ldaphost, config.ldapport);
    if (ld == NULL) {
	syslog(LOG_ERR, "abook_ldap_searchstart: LDAP init failed: %s",
	       strerror(errno));
	return -1;
    }

    rc = ldap_simple_bind_s(ld, NULL, NULL);
    if (rc != LDAP_SUCCESS) {
	syslog(LOG_ERR, "abook_ldap_searchstart: simple bind failed: %s",
	       ldap_err2string(rc));
	return -1;
    }

    /* For testing the error handlers...
      sizelimit = 4;
      ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit);
    */
    attrs[0] = config.fullnameattr;
    attrs[1] = config.uniqueattr;
    attrs[2] = NULL;

    msgid = ldap_search(ld, config.searchbase, config.scope, 
			filter, attrs, 0/*attrs-only*/);
    if (msgid == -1) {
	syslog(LOG_ERR, "abook_ldap_searchstart: LDAP search failed");
	ldap_unbind(ld);
	return -1;
    }

    rc = ldap_result(ld, msgid, 0, NULL, &result);

    switch (rc) {
    case LDAP_RES_SEARCH_ENTRY:
      /* Do nothing here. The abook_search function will pull out this
       * entry and send it back for display to the user.
       * The result is freed later.
       */
      break;
      
    case LDAP_RES_SEARCH_RESULT:
      rc = ldap_result2error(ld, result, 1 /* free result */);
      if (rc == LDAP_SUCCESS) {
	/* 
	 * Search returned successfully, but with no matching entries.
	 * 
	 * Try to do the secondary search, if configured to do so.
	 * fails, then set the prevresult to NULL.
	 */
	if (secondaryconfig.ldaphost) {
	  searching_secondary = 1;

	  /* close the connection to the primary ldap server */
	  ldap_unbind(ld);
	  
	  if (imsp_to_ldap_filter(flist, fcount, &secondaryfilter, 
				  secondaryconfig) < 0) {
	    syslog(LOG_ERR, "abook_ldap_searchstart: failed to convert filter");
	      return -1;
	  }
	  
	  /* open connection to the secondary server */
	  ld = ldap_init(secondaryconfig.ldaphost, secondaryconfig.ldapport);
	  if (ld == NULL) {
	      syslog(LOG_ERR, "abook_ldap_searchstart: LDAP init failed: %s",
		     strerror(errno));
	      return -1;
	  }
	  
	  rc = ldap_simple_bind_s(ld, NULL, NULL);
	  if (rc != LDAP_SUCCESS) {
	    syslog(LOG_ERR, "abook_ldap_searchstart: simple bind failed: %s",
		   ldap_err2string(rc));
	    return -1;
	  }
	  
	  attrs[0] = secondaryconfig.fullnameattr;
	  attrs[1] = secondaryconfig.uniqueattr;
	  attrs[2] = NULL;
	  
	  msgid = ldap_search(ld, secondaryconfig.searchbase, 
			      secondaryconfig.scope, secondaryfilter, 
			      attrs, 0 /*attrs-only*/);
	  if (msgid == -1) {
	    syslog(LOG_ERR, "abook_ldap_searchstart: LDAP search failed");
	    ldap_unbind(ld);
	    return -1;
	  }
	  
	  rc = ldap_result(ld, msgid, 0, NULL, &result);
	  
	  switch (rc) {
	  case LDAP_RES_SEARCH_ENTRY:
	    /* Do nothing here. The abook_search function will pull out this
	     * entry and send it back for display to the user.
	     * The result is freed later.
	     */
	    break;
	    
	  case LDAP_RES_SEARCH_RESULT:
	    /* Still didn't get any data.  Send a null "prevresult" to the
	     * abook_search function.
	     */
	    result = NULL;
	    break;
	    
	  default:
	    syslog(LOG_ERR, "abook_ldap_searchstart: ldap_result failed: %s (%d)",
		   ldap_err2string(rc), rc);
	    (void) ldap_msgfree(result);  /* ignore message type return value */
	    ldap_unbind(ld); 
	    return -1;
	  }

	} /* if (secondaryconfig.ldaphost) */

      } else {
	syslog(LOG_ERR,"abook_ldap_searchstart: search returned error: %s",
	       ldap_err2string(rc));
	ldap_unbind(ld);
	return -1;
      }
      break;
      
    default:
      syslog(LOG_ERR, "abook_ldap_searchstart: ldap_result failed: A1 SEARCHADDRESS %s",
	     ldap_err2string(rc));
      (void) ldap_msgfree(result);  /* ignore message type return value */
      ldap_unbind(ld);
      return -1;
    }
    
    mystate = (abook_ldap_state *) malloc (sizeof (abook_ldap_state));
    *ldap_state = mystate;
    
    if (mystate == NULL) {
      syslog(LOG_ERR, "abook_ldap_searchstart: Out of memory");
      (void) ldap_msgfree(result);  /* ignore message type return value */
      ldap_unbind(ld);
      return -1;
    }
    
    mystate->ld = ld;
    mystate->msgid = msgid;
    mystate->prevresult = result;

    if (searching_secondary == 0) {
      mystate->ldapconfig = &config;
    } else {
      mystate->ldapconfig = &secondaryconfig;
    }
    
    return 0;
}
Exemple #25
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;
}
abook_fielddata *
abook_ldap_fetch(char *alias, int *count)
{
  int i, rc, ldapcount, mappedfieldcount;
  char *ptr;
  char prefix[1024];
  char filter[1024];
  abook_fielddata *fdata, *fptr;
  char *searchattr;
  char *searchkey;
  LDAP *ld;
  LDAPMessage *results, *entry;
  char **values;
  
  if (config_ldap() < 0) {
    syslog(LOG_ERR, "abook_ldap_fetch: failed to configure LDAP");
    return NULL;
  }
  
  /*
   * Decide how to search for the user.
   */
  
  snprintf(prefix, sizeof(prefix), "[%s:", config.uniqueattr);
  ptr = strstr(alias, prefix);
  if (ptr != NULL) {
    *ptr = '\0';
    ptr += 1 /*[*/ + strlen(config.uniqueattr) + 1 /*:*/;
    searchkey = ptr;
    ptr += strlen(ptr) - 1 /*]*/;
    *ptr = '\0';
    searchattr = config.uniqueattr;
  } else {
    searchkey  = alias;
    searchattr = config.fullnameattr;
  }
  snprintf(filter, sizeof(filter), "(&%s(%s=%s))", config.defaultfilter, 
	  searchattr, searchkey);
  
  ld = ldap_init(config.ldaphost, config.ldapport);
  if (ld == NULL) {
    syslog(LOG_ERR, "abook_ldap_fetch: LDAP init failed: %s",
	   strerror(errno));
    return NULL;
  }
  
  rc = ldap_simple_bind_s(ld, NULL, NULL);
  if (rc != LDAP_SUCCESS) {
    syslog(LOG_ERR, "abook_ldap_fetch: simple bind failed: %s",
	   ldap_err2string(rc));
    return NULL;
  }
  
  rc = ldap_search_s(ld, config.searchbase, config.scope, filter, 
		     NULL/*get all attrs*/, 0/*attrs-only*/, &results);
  if (rc != LDAP_SUCCESS) {
    syslog(LOG_ERR, "abook_ldap_fetch: LDAP search failed: %s",
	   ldap_err2string(rc));
    ldap_unbind(ld);
    return NULL;
    }
  
  ldapcount = ldap_count_entries(ld, results);

  if (ldapcount == 0) {
    /* no matches on primary search, try secondary search if configured */
    
    if (secondaryconfig.ldaphost) {
      
      /* close the connection to the primary server */
      ldap_unbind(ld);

      snprintf(prefix, sizeof(prefix), "[%s:", secondaryconfig.uniqueattr);
      ptr = strstr(alias, prefix);
      if (ptr != NULL) {
	*ptr = '\0';
	ptr += 1 /*[*/ + strlen(secondaryconfig.uniqueattr) + 1 /*:*/;
	searchkey = ptr;
	ptr += strlen(ptr) - 1 /*]*/;
	*ptr = '\0';
	searchattr = secondaryconfig.uniqueattr;
      } else {
	searchkey  = alias;
	searchattr = secondaryconfig.fullnameattr;
      }
      snprintf(filter, sizeof(filter), "(&%s(%s=%s))", secondaryconfig.defaultfilter, 
	      searchattr, searchkey);
      
      ld=ldap_init(secondaryconfig.ldaphost, secondaryconfig.ldapport);
      if (ld == NULL){
	syslog(LOG_ERR, "abook_ldap_fetch: LDAP secondary init failed: %s",
	       strerror(errno));
	return NULL;
      }
      
      rc = ldap_simple_bind_s(ld, NULL, NULL);
      if (rc != LDAP_SUCCESS) {
	syslog(LOG_ERR, "abook_ldap_fetch: simple secondary bind failed: %s",
	       ldap_err2string(rc));
	return NULL;
      }
      
      rc = ldap_search_s(ld, secondaryconfig.searchbase, secondaryconfig.scope, filter, 
			 NULL/*get all attrs*/, 0/*attrs-only*/, &results);
      
      if (rc != LDAP_SUCCESS) {
	syslog(LOG_ERR, "abook_ldap_fetch: LDAP secondary search failed: %s",
	       ldap_err2string(rc));
	ldap_unbind(ld);
	return NULL;
      }
      
      ldapcount = ldap_count_entries(ld, results);
      
      if (ldapcount != 1) {
	syslog(LOG_ERR, "abook_ldap_fetch: unexpected count of secondary search"
	       " hits: %d", ldapcount);
	(void) ldap_msgfree(results);  /* ignore message type return value */
	ldap_unbind(ld);
	return NULL;
      }	       
      
      entry = ldap_first_entry(ld, results);
      if (entry == NULL) {
	  syslog(LOG_ERR, "abook_ldap_fetch: ldap_first_entry failed");
	  (void) ldap_msgfree(results);  /* ignore message type return value */
	  ldap_unbind(ld);
	  return NULL;
      }
      
      /* This memory is freed by abook_fetchdone() which is called by 
       * show_address() after it's finished sending the field/data pairs 
       * back to the IMSP client
       */
      
      mappedfieldcount = 0;
      for (i = 0; secondaryconfig.map[i].field != NULL; i++) {
	if (secondaryconfig.map[i].attr != NULL)
	  mappedfieldcount++;
      }
      
      fdata = (abook_fielddata *) 
	malloc(sizeof (abook_fielddata) * mappedfieldcount);
      if (fdata == NULL) {
	syslog(LOG_ERR, "abook_ldap_fetch: Out of memory");
	(void) ldap_msgfree(results);  /* ignore message type return value */
	ldap_unbind(ld);
	return NULL;
      }
      
      *count = 0;
      fptr = fdata;
      
      for (i = 0; secondaryconfig.map[i].field != NULL; i++) {
	if ((secondaryconfig.map[i].attr != NULL) &&
	    (strcmp(secondaryconfig.map[i].attr, secondaryconfig.fullnameattr) != 0)) {
	  values = ldap_get_values(ld, entry, secondaryconfig.map[i].attr);
	  if (values != NULL && values[0] != NULL) {
	    fptr->field = strdup(secondaryconfig.map[i].field);
	    if (secondaryconfig.map[i].append != NULL) {
	      int fptrdatalen = strlen(values[0])+strlen(secondaryconfig.map[i].append)+1;
	      fptr->data=malloc(fptrdatalen);
	      if(!fptr->data) fatal("out of memory", EC_TEMPFAIL);
	      strlcpy(fptr->data, values[0], fptrdatalen);
	      strlcat(fptr->data, secondaryconfig.map[i].append, fptrdatalen);
	    } else {
	      fptr->data  = strdup(values[0]);
	      if(!fptr->data) fatal("out of memory", EC_TEMPFAIL);
	    }
	    (*count)++;
	    fptr++;
	  }
	  if (values != NULL)
	    ldap_value_free(values);
	}
      }
      
      (void) ldap_msgfree(results);  /* ignore message type return value */
      ldap_unbind(ld);
      
      return (fdata);
    }
  }

  if (ldapcount != 1) {
	syslog(LOG_ERR, "abook_ldap_fetch: unexpected count of search"
	       " hits: %d", ldapcount);
	(void) ldap_msgfree(results);  /* ignore message type return value */
	ldap_unbind(ld);
	return NULL;
    }	       

    entry = ldap_first_entry(ld, results);
    if (entry == NULL) {
	syslog(LOG_ERR, "abook_ldap_fetch: ldap_first_entry failed");
	(void) ldap_msgfree(results);  /* ignore message type return value */
	ldap_unbind(ld);
	return NULL;
    }

    /* This memory is freed by abook_fetchdone() which is called by 
     * show_address() after it's finished sending the field/data pairs 
     * back to the IMSP client
     */
    
    mappedfieldcount = 0;
    for (i = 0; config.map[i].field != NULL; i++) {
	if (config.map[i].attr != NULL)
	    mappedfieldcount++;
    }

    fdata = (abook_fielddata *) 
	malloc(sizeof (abook_fielddata) * mappedfieldcount);
    if (fdata == NULL) {
	syslog(LOG_ERR, "abook_ldap_fetch: Out of memory");
	(void) ldap_msgfree(results);  /* ignore message type return value */
	ldap_unbind(ld);
	return NULL;
    }

    *count = 0;
    fptr = fdata;
    
    for (i = 0; config.map[i].field != NULL; i++) {
	if ((config.map[i].attr != NULL) &&
	    (strcmp(config.map[i].attr, config.fullnameattr) != 0)) {
	    values = ldap_get_values(ld, entry, config.map[i].attr);
	    if (values != NULL && values[0] != NULL) {
		fptr->field = strdup(config.map[i].field);
		if (config.map[i].append != NULL) {
		  printf("appending %s to field: %s value: %s\n", config.map[i].append, config.map[i].field,values[0]);

		  fptr->data=malloc(strlen(values[0])+strlen(config.map[i].append)+1);
		  fptr->data=strcat(fptr->data, values[0]);
		  fptr->data=strcat(fptr->data, config.map[i].append);
		} else {
		  fptr->data  = strdup(values[0]);
		}
		(*count)++;
		fptr++;
	    }
	    if (values != NULL)
		ldap_value_free(values);
	}
    }

    (void) ldap_msgfree(results);  /* ignore message type return value */
    ldap_unbind(ld);

    return (fdata);
}
Exemple #27
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
}
Exemple #28
0
int
main(int argc, char **argv)
{
	LDAPAPIInfo api;
	int ival;
	char *sval;

	printf("Compile time API Information\n");

#ifdef LDAP_API_INFO_VERSION
	api.ldapai_info_version = LDAP_API_INFO_VERSION;
	printf("  API Info version:  %d\n", (int) api.ldapai_info_version);
#else
	api.ldapai_info_version = 1;
	printf("  API Info version:  unknown\n");
#endif

#ifdef LDAP_FEATURE_INFO_VERSION
	printf("  Feature Info version:  %d\n", (int) LDAP_FEATURE_INFO_VERSION);
#else
	printf("  Feature Info version:  unknown\n");
	api.ldapai_info_version = 1;
#endif

#ifdef LDAP_API_VERSION
	printf("  API version:       %d\n", (int) LDAP_API_VERSION);
#else
	printf("  API version:       unknown\n");
#endif

#ifdef LDAP_VERSION
	printf("  Protocol Version:  %d\n", (int) LDAP_VERSION);
#else
	printf("  Protocol Version:  unknown\n");
#endif
#ifdef LDAP_VERSION_MIN
	printf("  Protocol Min:      %d\n", (int) LDAP_VERSION_MIN);
#else
	printf("  Protocol Min:      unknown\n");
#endif
#ifdef LDAP_VERSION_MAX
	printf("  Protocol Max:      %d\n", (int) LDAP_VERSION_MAX);
#else
	printf("  Protocol Max:      unknown\n");
#endif
#ifdef LDAP_VENDOR_NAME
	printf("  Vendor Name:       %s\n", LDAP_VENDOR_NAME);
#else
	printf("  Vendor Name:       unknown\n");
#endif
#ifdef LDAP_VENDOR_VERSION
	printf("  Vendor Version:    %d\n", (int) LDAP_VENDOR_VERSION);
#else
	printf("  Vendor Version:    unknown\n");
#endif

	if(ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(API_INFO) failed\n", argv[0]);
		return EXIT_FAILURE;
	}

	printf("\nExecution time API Information\n");
	printf("  API Info version:  %d\n", api.ldapai_info_version);

	if (api.ldapai_info_version != LDAP_API_INFO_VERSION) {
		printf(" API INFO version mismatch: got %d, expected %d\n",
			api.ldapai_info_version, LDAP_API_INFO_VERSION);
		return EXIT_FAILURE;
	}

	printf("  API Version:       %d\n", api.ldapai_api_version);
	printf("  Protocol Max:      %d\n", api.ldapai_protocol_version);

	if(api.ldapai_extensions == NULL) {
		printf("  Extensions:        none\n");

	} else {
		int i;
		for(i=0; api.ldapai_extensions[i] != NULL; i++) /* empty */;
		printf("  Extensions:        %d\n", i);
		for(i=0; api.ldapai_extensions[i] != NULL; i++) {
#ifdef LDAP_OPT_API_FEATURE_INFO
			LDAPAPIFeatureInfo fi;
			fi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
			fi.ldapaif_name = api.ldapai_extensions[i];
			fi.ldapaif_version = 0;

			if( ldap_get_option(NULL, LDAP_OPT_API_FEATURE_INFO, &fi) == LDAP_SUCCESS ) {
				if(fi.ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) {
					printf("                     %s feature info mismatch: got %d, expected %d\n",
						api.ldapai_extensions[i],
						LDAP_FEATURE_INFO_VERSION,
						fi.ldapaif_info_version);

				} else {
					printf("                     %s: version %d\n",
						fi.ldapaif_name,
						fi.ldapaif_version);
				}

			} else {
				printf("                     %s (NO FEATURE INFO)\n",
					api.ldapai_extensions[i]);
			}

#else
			printf("                     %s\n",
				api.ldapai_extensions[i]);
#endif

			ldap_memfree(api.ldapai_extensions[i]);
		}
		ldap_memfree(api.ldapai_extensions);
	}

	printf("  Vendor Name:       %s\n", api.ldapai_vendor_name);
	ldap_memfree(api.ldapai_vendor_name);

	printf("  Vendor Version:    %d\n", api.ldapai_vendor_version);

	printf("\nExecution time Default Options\n");

	if(ldap_get_option(NULL, LDAP_OPT_DEREF, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(api) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  DEREF:             %d\n", ival);

	if(ldap_get_option(NULL, LDAP_OPT_SIZELIMIT, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(sizelimit) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  SIZELIMIT:         %d\n", ival);

	if(ldap_get_option(NULL, LDAP_OPT_TIMELIMIT, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(timelimit) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  TIMELIMIT:         %d\n", ival);

	if(ldap_get_option(NULL, LDAP_OPT_REFERRALS, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(referrals) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  REFERRALS:         %s\n", ival ? "on" : "off");

	if(ldap_get_option(NULL, LDAP_OPT_RESTART, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(restart) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  RESTART:           %s\n", ival ? "on" : "off");

	if(ldap_get_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(protocol version) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  PROTOCOL VERSION:  %d\n", ival);

	if(ldap_get_option(NULL, LDAP_OPT_HOST_NAME, &sval) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(host name) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	if( sval != NULL ) {
		printf("  HOST NAME:         %s\n", sval);
		ldap_memfree(sval);
	} else {
		puts("  HOST NAME:         <not set>");
	}

#if 0
	/* API tests */
	{	/* bindless unbind */
		LDAP *ld;
		int rc;

		ld = ldap_init( "localhost", 389 );
		if( ld == NULL ) {
			perror("ldap_init");
			return EXIT_FAILURE;
		}

		rc = ldap_unbind( ld );
		if( rc != LDAP_SUCCESS ) {
			perror("ldap_unbind");
			return EXIT_FAILURE;
		}
	}
	{	/* bindless unbind */
		LDAP *ld;
		int rc;

		ld = ldap_init( "localhost", 389 );
		if( ld == NULL ) {
			perror("ldap_init");
			return EXIT_FAILURE;
		}

		rc = ldap_abandon_ext( ld, 0, NULL, NULL );
		if( rc != LDAP_SERVER_DOWN ) {
			ldap_debug_perror( ld, "ldap_abandon");
			return EXIT_FAILURE;
		}

		rc = ldap_unbind( ld );
		if( rc != LDAP_SUCCESS ) {
			perror("ldap_unbind");
			return EXIT_FAILURE;
		}
	}
#endif

	return EXIT_SUCCESS;
}
Exemple #29
0
/** Instantiate the module
 *
 * Creates a new instance of the module reading parameters from a configuration section.
 *
 * @param conf to parse.
 * @param instance Where to write pointer to configuration data.
 * @return 0 on success < 0 on failure.
 */
static int mod_instantiate(CONF_SECTION *conf, void *instance)
{
	static bool version_done;

	CONF_SECTION *options;
	ldap_instance_t *inst = instance;

	inst->cs = conf;

	options = cf_section_sub_find(conf, "options");
	if (!options || !cf_pair_find(options, "chase_referrals")) {
		inst->chase_referrals_unset = true;	 /* use OpenLDAP defaults */
	}

	inst->xlat_name = cf_section_name2(conf);
	if (!inst->xlat_name) {
		inst->xlat_name = cf_section_name1(conf);
	}


	/*
	 *	Only needs to be done once, prevents races in environment
	 *	initialisation within libldap.
	 *
	 *	See: https://github.com/arr2036/ldapperf/issues/2
	 */
#ifdef HAVE_LDAP_INITIALIZE
	ldap_initialize(&inst->handle, "");
#else
	inst->handle = ldap_init("", 0);
#endif

	/*
	 *	Get version info from the LDAP API.
	 */
	if (!version_done) {
		static LDAPAPIInfo info;	/* static to quiet valgrind about this being uninitialised */
		int ldap_errno;

		version_done = true;

		ldap_errno = ldap_get_option(NULL, LDAP_OPT_API_INFO, &info);
		if (ldap_errno == LDAP_OPT_SUCCESS) {
			if (strcmp(info.ldapai_vendor_name, LDAP_VENDOR_NAME) != 0) {
				WARN("rlm_ldap: libldap vendor changed since the server was built");
				WARN("rlm_ldap: linked: %s, built: %s", info.ldapai_vendor_name, LDAP_VENDOR_NAME);
			}

			if (info.ldapai_vendor_version != LDAP_VENDOR_VERSION) {
				WARN("rlm_ldap: libldap version changed since the server was built");
				WARN("rlm_ldap: linked: %i, built: %i",
				     info.ldapai_vendor_version, LDAP_VENDOR_VERSION);
			}

			INFO("rlm_ldap: libldap vendor: %s, version: %i", info.ldapai_vendor_name,
			     info.ldapai_vendor_version);

			ldap_memfree(info.ldapai_vendor_name);
			ldap_memfree(info.ldapai_extensions);
		} else {
			DEBUG("rlm_ldap: Falling back to build time libldap version info.  Query for LDAP_OPT_API_INFO "
			      "returned: %i", ldap_errno);
			INFO("rlm_ldap: libldap vendor: %s, version: %i.%i.%i", LDAP_VENDOR_NAME,
			     LDAP_VENDOR_VERSION_MAJOR, LDAP_VENDOR_VERSION_MINOR, LDAP_VENDOR_VERSION_PATCH);
		}
	}

	/*
	 *	If the configuration parameters can't be parsed, then fail.
	 */
	if ((parse_sub_section(inst, conf, &inst->accounting, RLM_COMPONENT_ACCT) < 0) ||
	    (parse_sub_section(inst, conf, &inst->postauth, RLM_COMPONENT_POST_AUTH) < 0)) {
		cf_log_err_cs(conf, "Failed parsing configuration");

		goto error;
	}

	/*
	 *	Sanity checks for cacheable groups code.
	 */
	if (inst->cacheable_group_name && inst->groupobj_membership_filter) {
		if (!inst->groupobj_name_attr) {
			cf_log_err_cs(conf, "Directive 'group.name_attribute' must be set if cacheable "
				      "group names are enabled");

			goto error;
		}
	}

	/*
	 *	Split original server value out into URI, server and port
	 *	so whatever initialization function we use later will have
	 *	the server information in the format it needs.
	 */
	if (ldap_is_ldap_url(inst->server)) {
		LDAPURLDesc *ldap_url;
		int port;

		if (ldap_url_parse(inst->server, &ldap_url)){
			cf_log_err_cs(conf, "Parsing LDAP URL \"%s\" failed", inst->server);
			return -1;
		}

		/*
		 *	Figure out the port from the URL
		 */
		if (ldap_url->lud_port == 0) {
			if (strcmp(ldap_url->lud_scheme, "ldaps://") == 0) {
				if (inst->start_tls == true) {
				start_tls_error:
					cf_log_err_cs(conf, "ldaps:// scheme is not compatible with 'start_tls'");
					return -1;
				}
				port = 636;
			} else {
				port = 384;
			}
		} else {
			port = ldap_url->lud_port;
		}

		inst->uri = inst->server;
		inst->server = talloc_strdup(inst, ldap_url->lud_host);

		if ((inst->port != 384) && (port != inst->port)) {
			WARN("Non-default 'port' directive %i set to %i by LDAP URI", inst->port, port);
		}
		inst->port = port;

		/*
		 *	@todo We could set a few other top level
		 *	directives using the URL, like base_dn
		 *	and scope.
		 */

		ldap_free_urldesc(ldap_url);
	/*
	 *	We need to construct an LDAP URI
	 */
	} else {
		switch (inst->port) {
		default:
		case 384:
			inst->uri = talloc_asprintf(inst, "ldap://%s:%i/", inst->server, inst->port);
			break;

		case 636:
			if (inst->start_tls == true) goto start_tls_error;
			inst->uri = talloc_asprintf(inst, "ldaps://%s:%i/", inst->server, inst->port);
			break;
		}
	}

#ifdef LDAP_OPT_X_TLS_NEVER
	/*
	 *	Workaround for servers which support LDAPS but not START TLS
	 */
	if (inst->port == LDAPS_PORT || inst->tls_mode) {
		inst->tls_mode = LDAP_OPT_X_TLS_HARD;
	} else {
		inst->tls_mode = 0;
	}
#endif

	/*
	 *	Convert dereference strings to enumerated constants
	 */
	if (inst->dereference_str) {
		inst->dereference = fr_str2int(ldap_dereference, inst->dereference_str, -1);
		if (inst->dereference < 0) {
			cf_log_err_cs(conf, "Invalid 'dereference' value \"%s\", expected 'never', 'searching', "
				      "'finding' or 'always'", inst->dereference_str);
			goto error;
		}
	}

#if LDAP_SET_REBIND_PROC_ARGS != 3
	/*
	 *	The 2-argument rebind doesn't take an instance variable.  Our rebind function needs the instance
	 *	variable for the username, password, etc.
	 */
	if (inst->rebind == true) {
		cf_log_err_cs(conf, "Cannot use 'rebind' directive as this version of libldap "
			      "does not support the API that we need");

		goto error;
	}
#endif

	/*
	 *	Convert scope strings to enumerated constants
	 */
	inst->userobj_scope = fr_str2int(ldap_scope, inst->userobj_scope_str, -1);
	if (inst->userobj_scope < 0) {
		cf_log_err_cs(conf, "Invalid 'user.scope' value \"%s\", expected 'sub', 'one'"
#ifdef LDAP_SCOPE_CHILDREN
			      ", 'base' or 'children'"
#else
			      " or 'base'"
#endif
			 , inst->userobj_scope_str);
		goto error;
	}

	inst->groupobj_scope = fr_str2int(ldap_scope, inst->groupobj_scope_str, -1);
	if (inst->groupobj_scope < 0) {
		cf_log_err_cs(conf, "Invalid 'group.scope' value \"%s\", expected 'sub', 'one'"
#ifdef LDAP_SCOPE_CHILDREN
			      ", 'base' or 'children'"
#else
			      " or 'base'"
#endif
			 , inst->groupobj_scope_str);
		goto error;
	}

	inst->clientobj_scope = fr_str2int(ldap_scope, inst->clientobj_scope_str, -1);
	if (inst->clientobj_scope < 0) {
		cf_log_err_cs(conf, "Invalid 'client.scope' value \"%s\", expected 'sub', 'one'"
#ifdef LDAP_SCOPE_CHILDREN
			      ", 'base' or 'children'"
#else
			      " or 'base'"
#endif
			 , inst->clientobj_scope_str);
		goto error;
	}

	if (inst->tls_require_cert_str) {
#ifdef LDAP_OPT_X_TLS_NEVER
		/*
		 *	Convert cert strictness to enumerated constants
		 */
		inst->tls_require_cert = fr_str2int(ldap_tls_require_cert, inst->tls_require_cert_str, -1);
		if (inst->tls_require_cert < 0) {
			cf_log_err_cs(conf, "Invalid 'tls.require_cert' value \"%s\", expected 'never', "
				      "'demand', 'allow', 'try' or 'hard'", inst->tls_require_cert_str);
			goto error;
		}
#else
		cf_log_err_cs(conf, "Modifying 'tls.require_cert' is not supported by current "
			      "version of libldap. Please upgrade or substitute current libldap and "
			      "rebuild this module");

		goto error;
#endif
	}
	/*
	 *	Build the attribute map
	 */
	if (map_afrom_cs(&inst->user_map, cf_section_sub_find(inst->cs, "update"),
			 PAIR_LIST_REPLY, PAIR_LIST_REQUEST, rlm_ldap_map_verify, inst,
			 LDAP_MAX_ATTRMAP) < 0) {
		return -1;
	}

	/*
	 *	Group comparison checks.
	 */
	if (cf_section_name2(conf)) {
		static ATTR_FLAGS flags;
		char buffer[256];

		snprintf(buffer, sizeof(buffer), "%s-Ldap-Group", inst->xlat_name);
		if (dict_addattr(buffer, -1, 0, PW_TYPE_STRING, flags) < 0) {
			LDAP_ERR("Error creating group attribute: %s", fr_strerror());

			return -1;
		}
		inst->group_da = dict_attrbyname(buffer);
		if (!inst->group_da) {
			LDAP_ERR("Failed creating attribute %s", buffer);

			goto error;
		}

		paircompare_register(inst->group_da, dict_attrbyvalue(PW_USER_NAME, 0), false, rlm_ldap_groupcmp, inst);
	/*
	 *	Were the default instance
	 */
	} else {
		inst->group_da = dict_attrbyvalue(PW_LDAP_GROUP, 0);
		paircompare_register(dict_attrbyvalue(PW_LDAP_GROUP, 0), dict_attrbyvalue(PW_USER_NAME, 0),
				false, rlm_ldap_groupcmp, inst);
	}

	xlat_register(inst->xlat_name, ldap_xlat, rlm_ldap_escape_func, inst);

	/*
	 *	Setup the cache attribute
	 */
	if (inst->cache_attribute) {
		static ATTR_FLAGS flags;

		if (dict_addattr(inst->cache_attribute, -1, 0, PW_TYPE_STRING, flags) < 0) {
			LDAP_ERR("Error creating cache attribute: %s", fr_strerror());

			goto error;
		}
		inst->cache_da = dict_attrbyname(inst->cache_attribute);
	} else {
		inst->cache_da = inst->group_da;	/* Default to the group_da */
	}

	/*
	 *	Initialize the socket pool.
	 */
	inst->pool = fr_connection_pool_module_init(inst->cs, inst, mod_conn_create, NULL, NULL);
	if (!inst->pool) goto error;

	/*
	 *	Bulk load dynamic clients.
	 */
	if (inst->do_clients) {
		CONF_SECTION *cs;

		cs = cf_section_sub_find(inst->cs, "client");
		if (!cs) {
			cf_log_err_cs(conf, "Told to load clients but no client section found");
			goto error;
		}

		cs = cf_section_sub_find(cs, "attribute");
		if (!cs) {
			cf_log_err_cs(conf, "Told to load clients but no attribute section found");
			goto error;
		}

		if (rlm_ldap_client_load(inst, cs) < 0) {
			cf_log_err_cs(conf, "Error loading clients");

			return -1;
		}
	}

	return 0;

error:
	return -1;
}
Exemple #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;
}