Exemple #1
0
/*
** Perform a search operation.
** @return #1 Function to iterate over the result entries.
** @return #2 nil.
** @return #3 nil as first entry.
** The search result is defined as an upvalue of the iterator.
*/
static int lualdap_search (lua_State *L) {
	conn_data *conn = getconnection (L);
	ldap_pchar_t base;
	ldap_pchar_t filter;
	char *attrs[LUALDAP_MAX_ATTRS];
	int scope, attrsonly, msgid, rc, sizelimit;
	struct timeval st, *timeout;

	if (!lua_istable (L, 2))
		return luaL_error (L, LUALDAP_PREFIX"no search specification");
	if (!get_attrs_param (L, attrs))
		return 2;
	/* get other parameters */
	attrsonly = booltabparam (L, "attrsonly", 0);
	base = (ldap_pchar_t) strtabparam (L, "base", NULL);
	filter = (ldap_pchar_t) strtabparam (L, "filter", NULL);
	scope = string2scope (L, strtabparam (L, "scope", NULL));
	sizelimit = longtabparam (L, "sizelimit", LDAP_NO_LIMIT);
	timeout = get_timeout_param (L, &st);

	rc = ldap_search_ext (conn->ld, base, scope, filter, attrs, attrsonly,
		NULL, NULL, timeout, sizelimit, &msgid);
	if (rc != LDAP_SUCCESS)
		return luaL_error (L, LUALDAP_PREFIX"%s", ldap_err2string (rc));

	create_search (L, 1, msgid);
	lua_pushcclosure (L, next_message, 1);
	return 1;
}
Exemple #2
0
static krb5_error_code
LDAP_firstkey(krb5_context context, HDB *db, unsigned flags,
	      hdb_entry_ex *entry)
{
    krb5_error_code ret;
    int msgid;

    ret = LDAP__connect(context, db);
    if (ret)
	return ret;

    ret = LDAP_no_size_limit(context, HDB2LDAP(db));
    if (ret)
	return ret;

    ret = ldap_search_ext(HDB2LDAP(db), HDB2BASE(db),
			LDAP_SCOPE_SUBTREE,
			"(|(objectClass=krb5Principal)(objectClass=sambaSamAccount))",
			krb5kdcentry_attrs, 0,
			NULL, NULL, NULL, 0, &msgid);
    if (msgid < 0)
	return HDB_ERR_NOENTRY;

    HDBSETMSGID(db, msgid);

    return LDAP_seq(context, db, flags, entry);
}
Exemple #3
0
static int linphone_ldap_contact_provider_perform_search( LinphoneLDAPContactProvider* obj, LinphoneLDAPContactSearch* req)
{
	int ret = -1;
	struct timeval timeout = { obj->timeout, 0 };

	if( req->msgid == 0 ){
		ms_message ( "Calling ldap_search_ext with predicate '%s' on base '%s', ld %p, attrs '%s', maxres = %d", req->filter, obj->base_object, obj->ld, obj->attributes[0], obj->max_results );
		ret = ldap_search_ext(obj->ld,
						obj->base_object,// base from which to start
						LDAP_SCOPE_SUBTREE,
						req->filter,     // search predicate
						obj->attributes, // which attributes to get
						0,               // 0 = get attrs AND value, 1 = get attrs only
						NULL,
						NULL,
						&timeout,        // server timeout for the search
						obj->max_results,// max result number
						&req->msgid );

		if( ret != LDAP_SUCCESS ){
			ms_error("Error ldap_search_ext returned %d (%s)", ret, ldap_err2string(ret));
		} else {
			ms_message("LinphoneLDAPContactSearch created @%p : msgid %d", req, req->msgid);
		}

	} else {
		ms_warning( "LDAP Search already performed for %s, msgid %d", req->filter, req->msgid);
	}
	return ret;
}
Exemple #4
0
/***********************************************************************
 *      ldap_search_extW     (WLDAP32.@)
 *
 * Search a directory tree (asynchronous operation).
 *
 * PARAMS
 *  ld          [I] Pointer to an LDAP context.
 *  base        [I] Starting point for the search.
 *  scope       [I] Search scope. One of LDAP_SCOPE_BASE,
 *                  LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
 *  filter      [I] Search filter.
 *  attrs       [I] Attributes to return.
 *  attrsonly   [I] Return no values, only attributes.
 *  serverctrls [I] Array of LDAP server controls.
 *  clientctrls [I] Array of LDAP client controls.
 *  timelimit   [I] Timeout in seconds.
 *  sizelimit   [I] Maximum number of entries to return. Zero means unlimited.
 *  message     [O] Message ID of the search operation.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  Call ldap_result with the message ID to get the result of
 *  the operation. Cancel the operation by calling ldap_abandon
 *  with the message ID.
 */
ULONG CDECL ldap_search_extW( WLDAP32_LDAP *ld, PWCHAR base, ULONG scope,
    PWCHAR filter, PWCHAR attrs[], ULONG attrsonly, PLDAPControlW *serverctrls,
    PLDAPControlW *clientctrls, ULONG timelimit, ULONG sizelimit, ULONG *message )
{
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
#ifdef HAVE_LDAP
    char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
    LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
    struct timeval tv, *tvp = NULL;

    ret = WLDAP32_LDAP_NO_MEMORY;

    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n",
           ld, debugstr_w(base), scope, debugstr_w(filter), attrs, attrsonly,
           serverctrls, clientctrls, timelimit, sizelimit, message );

    if (!ld) return ~0u;

    if (base) {
        baseU = strWtoU( base );
        if (!baseU) goto exit;
    }
    if (filter) {
        filterU = strWtoU( filter );
        if (!filterU) goto exit;
    }
    if (attrs) {
        attrsU = strarrayWtoU( attrs );
        if (!attrsU) goto exit;
    }
    if (serverctrls) {
        serverctrlsU = controlarrayWtoU( serverctrls );
        if (!serverctrlsU) goto exit;
    }
    if (clientctrls) {
        clientctrlsU = controlarrayWtoU( clientctrls );
        if (!clientctrlsU) goto exit;
    }

    if (timelimit)
    {
        tv.tv_sec = timelimit;
        tv.tv_usec = 0;
        tvp = &tv;
    }

    ret = map_error( ldap_search_ext( ld, baseU, scope, filterU, attrsU, attrsonly,
                                      serverctrlsU, clientctrlsU, tvp, sizelimit, (int *)message ));

exit:
    strfreeU( baseU );
    strfreeU( filterU );
    strarrayfreeU( attrsU );
    controlarrayfreeU( serverctrlsU );
    controlarrayfreeU( clientctrlsU );

#endif
    return ret;
}
static void
export_retrieve_key (SeahorseLDAPSource *self,
                     GSimpleAsyncResult *res)
{
	ExportClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
	LDAPServerInfo *sinfo;
	gchar *filter;
	char *attrs[2];
	GSource *gsource;
	const gchar *fingerprint;
	GError *error = NULL;
	int length, rc;
	int ldap_op;

	if (closure->current_index > 0) {
		fingerprint = closure->fingerprints->pdata[closure->current_index];
		seahorse_progress_end (closure->cancellable, fingerprint);
	}

	closure->current_index++;

	/* All done, complete operation */
	if (closure->current_index == (gint)closure->fingerprints->len) {
		g_simple_async_result_complete (res);
		return;
	}

	fingerprint = closure->fingerprints->pdata[closure->current_index];
	seahorse_progress_begin (closure->cancellable, fingerprint);
	length = strlen (fingerprint);
	if (length > 16)
		fingerprint += (length - 16);

	filter = g_strdup_printf ("(pgpcertid=%.16s)", fingerprint);
	sinfo = get_ldap_server_info (self, TRUE);

	attrs[0] = sinfo->key_attr;
	attrs[1] = NULL;

	rc = ldap_search_ext (closure->ldap, sinfo->base_dn, LDAP_SCOPE_SUBTREE,
	                      filter, attrs, 0,
	                      NULL, NULL, NULL, 0, &ldap_op);
	g_free (filter);

	if (seahorse_ldap_source_propagate_error (self, rc, &error)) {
		g_simple_async_result_take_error (res, error);
		g_simple_async_result_complete (res);
		return;
	}

	gsource = seahorse_ldap_gsource_new (closure->ldap, ldap_op,
	                                     closure->cancellable);
	g_source_set_callback (gsource, (GSourceFunc)on_export_search_completed,
	                       g_object_ref (res), g_object_unref);
	g_source_attach (gsource, g_main_context_default ());
	g_source_unref (gsource);
}
static gboolean
on_connect_bind_completed (LDAPMessage *result,
                           gpointer user_data)
{
	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
	source_connect_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
	SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (g_async_result_get_source_object (user_data));
	LDAPServerInfo *sinfo;
	GError *error = NULL;
	char *message;
	int ldap_op;
	int code;
	int rc;

	g_return_val_if_fail (ldap_msgtype (result) == LDAP_RES_BIND, FALSE);

	/* The result of the bind operation */
	rc = ldap_parse_result (closure->ldap, result, &code, NULL, &message, NULL, NULL, 0);
	g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE);
	ldap_memfree (message);

	if (seahorse_ldap_source_propagate_error (self, rc, &error)) {
		g_simple_async_result_take_error (res, error);
		g_simple_async_result_complete_in_idle (res);
		return FALSE; /* don't call this callback again */
	}

	/* Check if we need server info */
	sinfo = get_ldap_server_info (self, FALSE);
	if (sinfo != NULL) {
		g_simple_async_result_complete_in_idle (res);
		seahorse_progress_end (closure->cancellable, res);
		return FALSE; /* don't call this callback again */
	}

	/* Retrieve the server info */
	rc = ldap_search_ext (closure->ldap, "cn=PGPServerInfo", LDAP_SCOPE_BASE,
	                      "(objectclass=*)", (char **)SERVER_ATTRIBUTES, 0,
	                      NULL, NULL, NULL, 0, &ldap_op);

	if (seahorse_ldap_source_propagate_error (self, rc, &error)) {
		g_simple_async_result_take_error (res, error);
		g_simple_async_result_complete_in_idle (res);
		return FALSE; /* don't call this callback again */

	} else {
		GSource *gsource = seahorse_ldap_gsource_new (closure->ldap, ldap_op,
		                                              closure->cancellable);
		g_source_set_callback (gsource, (GSourceFunc)on_connect_server_info_completed,
		                       g_object_ref (res), g_object_unref);
		g_source_attach (gsource, g_main_context_default ());
		g_source_unref (gsource);
	}

	return FALSE; /* don't call this callback again */
}
Exemple #7
0
/* ARGSUSED */
int _ns_ldap_search_ext(char *service, int flags,
	char *base, int scope, char *filter,
	char **attrs, int attrsonly, LDAPControl **serverctrls,
	LDAPControl **clientctrls, struct timeval *timeoutp,
	int sizelimit, int *msgidp)
{
	LDAP *ld = __s_api_getLDAPconn(flags);

	return (ldap_search_ext(ld, base, scope, filter,
		attrs, attrsonly, serverctrls,
		clientctrls, timeoutp, sizelimit, msgidp));
}
Exemple #8
0
void LdapSearch::search( const QString &search )
{
	if( !init() )
		return;

	char *attrs[] = { const_cast<char*>("userCertificate;binary"), 0 };

	int err = ldap_search_ext( d->ldap, "c=EE", LDAP_SCOPE_SUBTREE,
		const_cast<char*>(search.toLocal8Bit().constData()), attrs, 0, 0, 0, 0, 0, &d->msg_id );
	if( err )
		setLastError( tr("Failed to init ldap search"), err );
	else
		startTimer( 1000 );
}
Exemple #9
0
int l_search_ping(struct ldapsearch *s)
{
	char *attrs[2];
	struct timeval tv;
	LDAPMessage *result;
	int rc;
	int msgid;

	if (s->handle == NULL)
	{
		errno=ETIMEDOUT;  /* Timeout previously */
		return -1;
	}

	attrs[0]="objectClass";
	attrs[1]=NULL;

	tv.tv_sec=60*60;
	tv.tv_usec=0;

	if (ldap_search_ext(s->handle, s->base, LDAP_SCOPE_BASE,
			    "objectClass=*", attrs, 0, NULL, NULL, &tv,
			    1000000, &msgid) < 0)
		return -1;

	do
	{
		const char *timeout=getenv("LDAP_SEARCH_TIMEOUT");

		tv.tv_sec=atoi(timeout ? timeout:"30");
		tv.tv_usec=0;

		rc=ldap_result(s->handle, msgid, 0, &tv, &result);

		if (rc <= 0)
		{
			if (rc == 0)
				errno=ETIMEDOUT;

			ldap_unbind_ext(s->handle, NULL, NULL);
			s->handle=NULL;

			return -1;
		}

		ldap_msgfree(result);
	} while (rc != LDAP_RES_SEARCH_RESULT);
	return 0;
}
Exemple #10
0
static void
on_search_connect_completed (GObject *source,
                             GAsyncResult *result,
                             gpointer user_data)
{
	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
	source_search_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
	SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (source);
	GError *error = NULL;
	LDAPServerInfo *sinfo;
	int ldap_op;
	int rc;

	closure->ldap = seahorse_ldap_source_connect_finish (SEAHORSE_LDAP_SOURCE (source),
	                                                     result, &error);
	if (error != NULL) {
		g_simple_async_result_take_error (res, error);
		g_simple_async_result_complete (res);
		g_object_unref (res);
		return;
	}

	sinfo = get_ldap_server_info (self, TRUE);

	g_debug ("Searching Server ... base: %s, filter: %s",
	         sinfo->base_dn, closure->filter);

	rc = ldap_search_ext (closure->ldap, sinfo->base_dn, LDAP_SCOPE_SUBTREE,
	                      closure->filter, (char **)PGP_ATTRIBUTES, 0,
	                      NULL, NULL, NULL, 0, &ldap_op);

	if (seahorse_ldap_source_propagate_error (self, rc, &error)) {
		g_simple_async_result_take_error (res, error);
		g_simple_async_result_complete (res);

	} else {
		GSource *gsource = seahorse_ldap_gsource_new (closure->ldap, ldap_op,
		                                     closure->cancellable);
		g_source_set_callback (gsource, (GSourceFunc)on_search_search_completed,
		                       g_object_ref (res), g_object_unref);
		g_source_attach (gsource, g_main_context_default ());
		g_source_unref (gsource);
	}

	g_object_unref (res);
}
Exemple #11
0
/***********************************************************************
 *      ldap_searchW     (WLDAP32.@)
 *
 * Search a directory tree (asynchronous operation).
 *
 * PARAMS
 *  ld        [I] Pointer to an LDAP context.
 *  base      [I] Starting point for the search.
 *  scope     [I] Search scope. One of LDAP_SCOPE_BASE,
 *                LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
 *  filter    [I] Search filter.
 *  attrs     [I] Attributes to return.
 *  attrsonly [I] Return no values, only attributes.
 *
 * RETURNS
 *  Success: Message ID of the search operation.
 *  Failure: ~0u
 *
 * NOTES
 *  Call ldap_result with the message ID to get the result of
 *  the operation. Cancel the operation by calling ldap_abandon
 *  with the message ID.
 */
ULONG CDECL ldap_searchW( WLDAP32_LDAP *ld, PWCHAR base, ULONG scope, PWCHAR filter,
    PWCHAR attrs[], ULONG attrsonly )
{
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
#ifdef HAVE_LDAP
    char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
    int msg;

    ret = WLDAP32_LDAP_NO_MEMORY;

    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x)\n", ld, debugstr_w(base),
           scope, debugstr_w(filter), attrs, attrsonly );

    if (!ld) return ~0u;

    if (base) {
        baseU = strWtoU( base );
        if (!baseU) goto exit;
    }
    if (filter) {
        filterU = strWtoU( filter );
        if (!filterU) goto exit;
    }
    if (attrs) {
        attrsU = strarrayWtoU( attrs );
        if (!attrsU) goto exit;
    }

    ret = ldap_search_ext( ld, baseU, scope, filterU, attrsU, attrsonly,
                           NULL, NULL, NULL, 0, &msg );

    if (ret == LDAP_SUCCESS)
        ret = msg;
    else
        ret = ~0u;

exit:
    strfreeU( baseU );
    strfreeU( filterU );
    strarrayfreeU( attrsU );

#endif
    return ret;
}
Exemple #12
0
static CURLcode ldap_do(struct connectdata *conn, bool *done)
{
  ldapconninfo *li = conn->proto.generic;
  ldapreqinfo *lr;
  CURLcode status = CURLE_OK;
  int rc = 0;
  LDAPURLDesc *ludp = NULL;
  int msgid;
  struct SessionHandle *data=conn->data;

  connkeep(conn, "OpenLDAP do");

  infof(data, "LDAP local: %s\n", data->change.url);

  rc = ldap_url_parse(data->change.url, &ludp);
  if(rc != LDAP_URL_SUCCESS) {
    const char *msg = "url parsing problem";
    status = CURLE_URL_MALFORMAT;
    if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
      if(rc == LDAP_URL_ERR_MEM)
        status = CURLE_OUT_OF_MEMORY;
      msg = url_errs[rc];
    }
    failf(conn->data, "LDAP local: %s", msg);
    return status;
  }

  rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope,
                       ludp->lud_filter, ludp->lud_attrs, 0,
                       NULL, NULL, NULL, 0, &msgid);
  ldap_free_urldesc(ludp);
  if(rc != LDAP_SUCCESS) {
    failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
    return CURLE_LDAP_SEARCH_FAILED;
  }
  lr = calloc(1, sizeof(ldapreqinfo));
  if(!lr)
    return CURLE_OUT_OF_MEMORY;
  lr->msgid = msgid;
  data->req.protop = lr;
  Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
  *done = TRUE;
  return CURLE_OK;
}
/// connects and binds to LDAP server
/// @param[in] ld    refernce to LDAP socket data
/// @param[in] cnf   reference to common configuration struct
int ldaputils_search(LDAP * ld, LdapUtilsConfig * cnf, LDAPMessage ** resp)
{
   int rc;
   int err;
   int msgid;

   if ((err = ldap_search_ext(ld, cnf->basedn, cnf->scope, cnf->filter, cnf->attrs, 0, NULL, NULL, NULL, -1, &msgid)))
   {
      fprintf(stderr, "%s: ldap_search_ext_s(): %s\n", PROGRAM_NAME, ldap_err2string(err));
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(-1);
   };

   switch((err = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, resp)))
   {
      case 0:
         break;
      case -1:
         fprintf(stderr, "%s: ldap_result(): %s\n", PROGRAM_NAME, ldap_err2string(err));
         ldap_unbind_ext_s(ld, NULL, NULL);
         return(-1);
      default:
         break;
   };

   rc = ldap_parse_result(ld, *resp, &err, NULL, NULL, NULL, NULL, 0);
   if (rc != LDAP_SUCCESS)
   {
      fprintf(stderr, "%s: ldap_parse_result(): %s\n", PROGRAM_NAME, ldap_err2string(rc));
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(-1);
   };
   if (err != LDAP_SUCCESS)
   {
      fprintf(stderr, "%s: ldap_parse_result(): %s\n", PROGRAM_NAME, ldap_err2string(err));
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(-1);
   };
   
   return(0);
}
Exemple #14
0
static LDAPMessage *
_dico_ldap_search(struct _dico_ldap_handle *lp, const char *filter_pat,
		  const char *attr, const char *user)
{
    int rc;
    char *filter;
    LDAPMessage *res;
    ber_int_t msgid;
    char *attrs[2];

    attrs[0] = (char*) attr;
    attrs[1] = NULL;

    if (filter_pat) {
	filter = _dico_ldap_expand_user(filter_pat, user);
	if (!filter) {
	    dico_log(L_ERR, ENOMEM, "_dico_ldap_expand_user");
	    return NULL;
	}
    } else
	filter = NULL;
    rc = ldap_search_ext(lp->ldap, lp->base, LDAP_SCOPE_SUBTREE,
			 filter, attrs, 0,
			 NULL, NULL, NULL, -1, &msgid);
    if (filter)
	free(filter);

    if (rc != LDAP_SUCCESS) {
	dico_log(L_ERR, 0, "ldap_search_ext: %s", ldap_err2string(rc));
	/*if (rc == LDAP_NO_SUCH_OBJECT)*/
	return NULL;
    }

    rc = ldap_result(lp->ldap, msgid, LDAP_MSG_ALL, NULL, &res);
    if (rc < 0) {
	dico_log(L_ERR, 0, "ldap_result failed");
	return NULL;
    }
    return res;
}
/*
 * ldap_search - initiate an ldap search operation.  Parameters:
 *
 *	ld		LDAP descriptor
 *	base		DN of the base object
 *	scope		the search scope - one of LDAP_SCOPE_BASE,
 *			    LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE
 *	filter		a string containing the search filter
 *			(e.g., "(|(cn=bob)(sn=bob))")
 *	attrs		list of attribute types to return for matches
 *	attrsonly	1 => attributes only 0 => attributes and values
 *
 * Example:
 *	char	*attrs[] = { "mail", "title", 0 };
 *	msgid = ldap_search( ld, "c=us@o=UM", LDAP_SCOPE_SUBTREE, "cn~=bob",
 *	    attrs, attrsonly );
 */
int
LDAP_CALL
ldap_search(
    LDAP 	*ld,
    const char 	*base,
    int 	scope,
    const char 	*filter,
    char 	**attrs,
    int 	attrsonly
)
{
	int		msgid;

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

	if ( ldap_search_ext( ld, base, scope, filter, attrs, attrsonly, NULL,
	    NULL, NULL, -1, &msgid ) == LDAP_SUCCESS ) {
		return( msgid );
	} else {
		return( -1 );	/* error is in ld handle */
	}
}
Exemple #16
0
int
ldap_search_ext_s(
	LDAP *ld,
	LDAP_CONST char *base,
	int scope,
	LDAP_CONST char *filter,
	char **attrs,
	int attrsonly,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	struct timeval *timeout,
	int sizelimit,
	LDAPMessage **res )
{
	int rc;
	int	msgid;

	rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
		sctrls, cctrls, timeout, sizelimit, &msgid );

	if ( rc != LDAP_SUCCESS ) {
		return( rc );
	}

	rc = ldap_result( ld, msgid, 1, timeout, res );

	if( rc <= 0 ) {
		/* error(-1) or timeout(0) */
		return( ld->ld_errno );
	}

	if( rc == LDAP_RES_SEARCH_REFERENCE || rc == LDAP_RES_EXTENDED_PARTIAL ) {
		return( ld->ld_errno );
	}

	return( ldap_result2error( ld, *res, 0 ) );
}
Exemple #17
0
NS_IMETHODIMP
nsLDAPOperation::SearchExt(const nsACString& aBaseDn, PRInt32 aScope,
                           const nsACString& aFilter,
                           const nsACString &aAttributes,
                           PRIntervalTime aTimeOut, PRInt32 aSizeLimit)
{
    if (!mMessageListener) {
        NS_ERROR("nsLDAPOperation::SearchExt(): mMessageListener not set");
        return NS_ERROR_NOT_INITIALIZED;
    }

    // XXX add control logging
    PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
           ("nsLDAPOperation::SearchExt(): called with aBaseDn = '%s'; "
            "aFilter = '%s'; aAttributes = %s; aSizeLimit = %d",
            PromiseFlatCString(aBaseDn).get(),
            PromiseFlatCString(aFilter).get(),
            PromiseFlatCString(aAttributes).get(), aSizeLimit));

    LDAPControl **serverctls = 0;
    nsresult rv;
    if (mServerControls) {
        rv = convertControlArray(mServerControls, &serverctls);
        if (NS_FAILED(rv)) {
            PR_LOG(gLDAPLogModule, PR_LOG_ERROR,
                   ("nsLDAPOperation::SearchExt(): error converting server "
                    "control array: %x", rv));
            return rv;
        }
    }

    LDAPControl **clientctls = 0;
    if (mClientControls) {
        rv = convertControlArray(mClientControls, &clientctls);
        if (NS_FAILED(rv)) {
            PR_LOG(gLDAPLogModule, PR_LOG_ERROR,
                   ("nsLDAPOperation::SearchExt(): error converting client "
                    "control array: %x", rv));
            ldap_controls_free(serverctls);
            return rv;
        }
    }

    // Convert our comma separated string to one that the C-SDK will like, i.e.
    // convert to a char array and add a last NULL element.
    nsTArray<nsCString> attrArray;
    ParseString(aAttributes, ',', attrArray);
    char **attrs = nsnull;
    PRUint32 origLength = attrArray.Length();
    if (origLength)
    {
      attrs = static_cast<char **> (NS_Alloc((origLength + 1) * sizeof(char *)));
      if (!attrs)
        return NS_ERROR_OUT_OF_MEMORY;

      for (PRUint32 i = 0; i < origLength; ++i)
        attrs[i] = ToNewCString(attrArray[i]);

      attrs[origLength] = 0;
    }

    // XXX deal with timeout here
    int retVal = ldap_search_ext(mConnectionHandle,
                                 PromiseFlatCString(aBaseDn).get(),
                                 aScope, PromiseFlatCString(aFilter).get(),
                                 attrs, 0, serverctls, clientctls, 0,
                                 aSizeLimit, &mMsgID);

    // clean up
    ldap_controls_free(serverctls);
    ldap_controls_free(clientctls);
    // The last entry is null, so no need to free that.
    NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(origLength, attrs);

    rv = TranslateLDAPErrorToNSError(retVal);
    NS_ENSURE_SUCCESS(rv, rv);

    // make sure the connection knows where to call back once the messages
    // for this operation start coming in
    //
    rv = mConnection->AddPendingOperation(mMsgID, this);
    if (NS_FAILED(rv)) {
        switch (rv) {
        case NS_ERROR_OUT_OF_MEMORY:
            (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
            return NS_ERROR_OUT_OF_MEMORY;

        default:
            (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
            NS_ERROR("nsLDAPOperation::SearchExt(): unexpected error in "
                     "mConnection->AddPendingOperation");
            return NS_ERROR_UNEXPECTED;
        }
    }

    return NS_OK;
}
Exemple #18
0
extern "C" void *
openSource(Source * source)

{
	URI u;
	ldap_handle * h;
	int version;
	int rc;
	int i;
	char * s;
	int msgid;
	std::string locfilter;
	struct berval passwd;
	struct timeval tv;

	if (!source->uri.length())
		throw std::runtime_error("LDAP loader requires an LDAP URI");

	//	Create the handle.

	h = new ldap_handle();
	h->source = source;

	//	Extract the binddn:password from the URI and rebuild
	//		an authentication-less URI.

	try {
		if (!u.parse(source->uri))
			throw std::runtime_error("Cannot parse URI");

		if (u.user().empty() && u.password().empty())
			h->binddn = u.unescape(u.userinfo());
		else {
			h->binddn = u.user();
			h->password = u.password();
			}

		u.userinfo("");

		//	Parse the LDAP URI.

		if ((rc = ldap_url_parse(std::string(u).c_str(), &h->uri)) !=
		    LDAP_SUCCESS)
			throw ldap_error(rc);

		if (!h->uri->lud_attrs[0])
			throw std::runtime_error(
			    "LDAP url should select at least one attribute");

		//	Connect to LDAP server.

		rc = ldap_initialize(&h->ldap, ((std::string(h->uri->lud_scheme?
		    h->uri->lud_scheme: "ldap")) + "://" +
		    (h->uri->lud_host? h->uri->lud_host: "") +
		    (h->uri->lud_port? ":" +
		    std::to_string(h->uri->lud_port): "")).c_str());

		if (rc != LDAP_SUCCESS)
			throw ldap_error(rc);

		//	Set a very low timeout: connection should be quick.

		tv.tv_sec = 5;
		tv.tv_usec = 0;
		ldap_set_option(h->ldap, LDAP_OPT_NETWORK_TIMEOUT, &tv);

		//	Bind if needed.

		if (ldap_get_option(h->ldap,
		    LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS)
			version = LDAP_VERSION2;	// Bind is mandatory.

		rc = LDAP_SUCCESS;

		if (!h->binddn.length()) {
			if (version >= LDAP_VERSION2) {
				//	Anonymous bind is mandatory for
				//		version 2.

				rc = ldap_sasl_bind_s(h->ldap, "",
				    LDAP_SASL_SIMPLE, NULL, NULL, NULL, NULL);
				}
			}
		else {
			passwd.bv_val = (char *) h->password.c_str();
			passwd.bv_len = h->password.length();
			rc = ldap_sasl_bind_s(h->ldap, h->binddn.c_str(),
			    LDAP_SASL_SIMPLE, &passwd, NULL, NULL, NULL);
			}

		if (rc != LDAP_SUCCESS)
			throw ldap_error(rc);

		//	Update the given filter to not select entries not
		//		providing mail address attributes.

		locfilter = h->uri->lud_filter;

		if (locfilter.length()) {
			if (locfilter[0] != '(')
				locfilter = std::string("(") + locfilter + ")";

			locfilter = std::string("(&") + locfilter;
			}

		if (h->uri->lud_attrs[1])
			locfilter += "(|";

		for (i = 0; (s = h->uri->lud_attrs[i]); i++)
			locfilter = locfilter + "(" + s + "=*)";

		if (h->uri->lud_attrs[1])
			locfilter += ')';

		if (h->uri->lud_filter)
			locfilter += ')';

		rc = ldap_search_ext(h->ldap, h->uri->lud_dn, h->uri->lud_scope,
		    locfilter.c_str(), h->uri->lud_attrs, 0,
		    NULL, NULL, NULL, 0x7FFFFFFF, &msgid);

		if (rc != LDAP_SUCCESS)
			throw ldap_error(rc);
		}
	catch (...) {
		delete h;
		throw;
		}

	return h;
}
Exemple #19
0
/*
 * initialize the sync
 */
int
ldap_sync_init( ldap_sync_t *ls, int mode )
{
	LDAPControl	ctrl = { 0 },
			*ctrls[ 2 ];
	BerElement	*ber = NULL;
	int		rc;
	struct timeval	tv = { 0 },
			*tvp = NULL;
	LDAPMessage	*res = NULL;

#ifdef LDAP_SYNC_TRACE
	fprintf( stderr, "ldap_sync_init(%s)...\n",
		mode == LDAP_SYNC_REFRESH_AND_PERSIST ?
			"LDAP_SYNC_REFRESH_AND_PERSIST" :
			( mode == LDAP_SYNC_REFRESH_ONLY ?
				"LDAP_SYNC_REFRESH_ONLY" : "unknown" ) );
#endif /* LDAP_SYNC_TRACE */

	assert( ls != NULL );
	assert( ls->ls_ld != NULL );

	/* support both refreshOnly and refreshAndPersist */
	switch ( mode ) {
	case LDAP_SYNC_REFRESH_AND_PERSIST:
	case LDAP_SYNC_REFRESH_ONLY:
		break;

	default:
		fprintf( stderr, "ldap_sync_init: unknown mode=%d\n", mode );
		return LDAP_PARAM_ERROR;
	}

	/* check consistency of cookie and reloadHint at initial refresh */
	if ( ls->ls_cookie.bv_val == NULL && ls->ls_reloadHint != 0 ) {
		fprintf( stderr, "ldap_sync_init: inconsistent cookie/rhint\n" );
		return LDAP_PARAM_ERROR;
	}

	ctrls[ 0 ] = &ctrl;
	ctrls[ 1 ] = NULL;

	/* prepare the Sync Request control */
	ber = ber_alloc_t( LBER_USE_DER );
#ifdef LDAP_SYNC_TRACE
	fprintf( stderr, "%sber_alloc_t() %s= NULL\n",
		ber == NULL ? "!!! " : "",
		ber == NULL ? "=" : "!" );
#endif /* LDAP_SYNC_TRACE */
	if ( ber == NULL ) {
		rc = LDAP_NO_MEMORY;
		goto done;
	}

	ls->ls_refreshPhase = LDAP_SYNC_CAPI_NONE;

	if ( ls->ls_cookie.bv_val != NULL ) {
		ber_printf( ber, "{eOb}", mode,
			&ls->ls_cookie, ls->ls_reloadHint );

	} else {
		ber_printf( ber, "{eb}", mode, ls->ls_reloadHint );
	}

	rc = ber_flatten2( ber, &ctrl.ldctl_value, 0 );
#ifdef LDAP_SYNC_TRACE
	fprintf( stderr,
		"%sber_flatten2() == %d\n",
		rc ? "!!! " : "",
		rc );
#endif /* LDAP_SYNC_TRACE */
	if ( rc < 0 ) {
		rc = LDAP_OTHER;
                goto done;
        }

	/* make the control critical, as we cannot proceed without */
	ctrl.ldctl_oid = LDAP_CONTROL_SYNC;
	ctrl.ldctl_iscritical = 1;

	/* timelimit? */
	if ( ls->ls_timelimit ) {
		tv.tv_sec = ls->ls_timelimit;
		tvp = &tv;
	}

	/* actually run the search */
	rc = ldap_search_ext( ls->ls_ld,
		ls->ls_base, ls->ls_scope, ls->ls_filter,
		ls->ls_attrs, 0, ctrls, NULL,
		tvp, ls->ls_sizelimit, &ls->ls_msgid );
#ifdef LDAP_SYNC_TRACE
	fprintf( stderr,
		"%sldap_search_ext(\"%s\", %d, \"%s\") == %d\n",
		rc ? "!!! " : "",
		ls->ls_base, ls->ls_scope, ls->ls_filter, rc );
#endif /* LDAP_SYNC_TRACE */
	if ( rc != LDAP_SUCCESS ) {
		goto done;
	}

	/* initial content/content update phase */
	for ( ; ; ) {
		LDAPMessage	*msg = NULL;

		/* NOTE: this very short timeout is just to let
		 * ldap_result() yield long enough to get something */
		tv.tv_sec = 0;
		tv.tv_usec = 100000;

		rc = ldap_result( ls->ls_ld, ls->ls_msgid,
			LDAP_MSG_RECEIVED, &tv, &res );
#ifdef LDAP_SYNC_TRACE
		fprintf( stderr,
			"\t%sldap_result(%d) == %d\n",
			rc == -1 ? "!!! " : "",
			ls->ls_msgid, rc );
#endif /* LDAP_SYNC_TRACE */
		switch ( rc ) {
		case 0:
			/*
			 * timeout
			 *
			 * TODO: can do something else in the meanwhile)
			 */
			break;

		case -1:
			/* smtg bad! */
			goto done;

		default:
			for ( msg = ldap_first_message( ls->ls_ld, res );
				msg != NULL;
				msg = ldap_next_message( ls->ls_ld, msg ) )
			{
				int	refreshDone;

				switch ( ldap_msgtype( msg ) ) {
				case LDAP_RES_SEARCH_ENTRY:
					rc = ldap_sync_search_entry( ls, res );
					break;

				case LDAP_RES_SEARCH_REFERENCE:
					rc = ldap_sync_search_reference( ls, res );
					break;

				case LDAP_RES_SEARCH_RESULT:
					rc = ldap_sync_search_result( ls, res );
					goto done_search;

				case LDAP_RES_INTERMEDIATE:
					rc = ldap_sync_search_intermediate( ls, res, &refreshDone );
					if ( rc != LDAP_SUCCESS || refreshDone ) {
						goto done_search;
					}
					break;

				default:
#ifdef LDAP_SYNC_TRACE
					fprintf( stderr, "\tgot something unexpected...\n" );
#endif /* LDAP_SYNC_TRACE */

					ldap_msgfree( res );

					rc = LDAP_OTHER;
					goto done;
				}
			}
			ldap_msgfree( res );
			res = NULL;
			break;
		}
	}

done_search:;
	ldap_msgfree( res );

done:;
	if ( ber != NULL ) {
		ber_free( ber, 1 );
	}

	return rc;
}
/*
 * Returns an LDAP error code.
 */
static int
docompare( LDAP *ld1, LDAP *ld2, char *base )
{
    int			rc, msgid;
    LDAPMessage		*res, *e;
    LDAPControl		*ctrls[2], **serverctrls;

    if ( ldaptool_verbose ) {
        printf( "Base: %s\n\n", base );
    }
    if ( ldaptool_not ) {
	return( LDAP_SUCCESS );
    }

    if (( ctrls[0] = ldaptool_create_manage_dsait_control()) != NULL ) {
	ctrls[1] = NULL;
	serverctrls = ctrls;
    } else {
	serverctrls = NULL;
    }

    if ( ldap_search_ext( ld1, base, scope, "objectClass=*", NULL,
	    0, serverctrls, NULL, NULL, -1, &msgid ) != LDAP_SUCCESS ) {
	return( ldaptool_print_lderror( ld1, "ldap_search",
	    LDAPTOOL_CHECK4SSL_IF_APPROP ));
    }
/* XXXmcs: this code should be modified to display referrals and references */
    while ( (rc = ldap_result( ld1, LDAP_RES_ANY, 0, NULL, &res )) == 
        LDAP_RES_SEARCH_ENTRY ) {
        e = ldap_first_entry( ld1, res );
        rc = cmp2( ld1, ld2, e , 0);
        ldap_msgfree( res );
    }
    if ( rc == -1 ) {
	return( ldaptool_print_lderror( ld1, "ldap_result",
		LDAPTOOL_CHECK4SSL_IF_APPROP ));
    }
    if (( rc = ldap_result2error( ld1, res, 0 )) != LDAP_SUCCESS ) {
        (void)ldaptool_print_lderror( ld1, "ldap_search",
		LDAPTOOL_CHECK4SSL_IF_APPROP );
    }
    ldap_msgfree( res );

    if ( ldap_search_ext( ld2, base, scope, "objectClass=*", NULL,
	    0, serverctrls, NULL, NULL, -1, &msgid  ) == -1 ) {
	return( ldaptool_print_lderror( ld2, "ldap_search",
		LDAPTOOL_CHECK4SSL_IF_APPROP ));
    }
/* XXXmcs: this code should be modified to display referrals and references */
    while ( (rc = ldap_result( ld2, LDAP_RES_ANY, 0, NULL, &res )) == 
	    LDAP_RES_SEARCH_ENTRY ) {
	e = ldap_first_entry( ld2, res );
        rc = cmp2( ld2, ld1, e , 1);
        ldap_msgfree( res );
    }
    if ( rc == -1 ) {
	return( ldaptool_print_lderror( ld2, "ldap_result",
		LDAPTOOL_CHECK4SSL_IF_APPROP ));
    }
    if (( rc = ldap_result2error( ld1, res, 0 )) != LDAP_SUCCESS ) {
        (void)ldaptool_print_lderror( ld1, "ldap_search",
		LDAPTOOL_CHECK4SSL_IF_APPROP );
    }
    ldap_msgfree( res );

    return( rc );
}
Exemple #21
0
static
DWORD
LWNetSrvPingCLdapBegin(
    IN PLWNET_CLDAP_CONNECTION_CONTEXT pContext,
    IN PDNS_SERVER_INFO pServerInfo,
    IN PCSTR pszDnsDomainName,
    IN DWORD dwTimeout
)
{
    DWORD dwError = 0;
    PSTR pszQuery = NULL;
    PSTR szAttributeList[] = { NETLOGON_LDAP_ATTRIBUTE_NAME, NULL };
    struct timeval timeout = {0};
    LDAP *ld = NULL;

    pContext->hDirectory = NULL;
    pContext->pServerInfo = pServerInfo;

    dwError = LwAllocateStringPrintf(&pszQuery,
                                     "(&(DnsDomain=%s)(NtVer=\\06\\00\\00\\80))",
                                     pszDnsDomainName);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LwCLdapOpenDirectory(pServerInfo->pszAddress, &pContext->hDirectory);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LwLdapBindDirectoryAnonymous(pContext->hDirectory);
    BAIL_ON_LWNET_ERROR(dwError);

    timeout.tv_sec = 0;
    timeout.tv_usec = dwTimeout;

    dwError = LWNetGetSystemTimeInMs(&pContext->StartTime);
    BAIL_ON_LWNET_ERROR(dwError);

    ld = LwLdapGetSession(pContext->hDirectory);

    dwError = ldap_search_ext(
                  ld,
                  "",
                  LDAP_SCOPE_BASE,
                  pszQuery,
                  szAttributeList,
                  0,
                  NULL,
                  NULL,
                  &timeout,
                  0,
                  &pContext->msgid);
    dwError = LwMapLdapErrorToLwError(dwError);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = ldap_get_option(
                  ld,
                  LDAP_OPT_DESC,
                  &pContext->fd);
    dwError = LwMapLdapErrorToLwError(dwError);
    BAIL_ON_LWNET_ERROR(dwError);

error:
    if (dwError)
    {
        if (pContext->hDirectory)
        {
            LWNetSrvPingCLdapEnd(pContext);
        }
    }

    LWNET_SAFE_FREE_STRING(pszQuery);

    return dwError;
}
Exemple #22
0
/** Search for something in the LDAP directory
 *
 * Binds as the administrative user and performs a search, dealing with any errors.
 *
 * @param[out] result		Where to store the result. Must be freed with ldap_msgfree
 *				if LDAP_PROC_SUCCESS is returned.
 *				May be NULL in which case result will be automatically freed after use.
 * @param[in] request		Current request.
 * @param[in,out] pconn		to use. May change as this function calls functions which auto re-connect.
 * @param[in] dn		to use as base for the search.
 * @param[in] scope		to use (LDAP_SCOPE_BASE, LDAP_SCOPE_ONE, LDAP_SCOPE_SUB).
 * @param[in] filter		to use, should be pre-escaped.
 * @param[in] attrs		to retrieve.
 * @param[in] serverctrls	Search controls to pass to the server.  May be NULL.
 * @param[in] clientctrls	Search controls for ldap_search.  May be NULL.
 * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values.
 */
fr_ldap_rcode_t fr_ldap_search(LDAPMessage **result, REQUEST *request,
			       fr_ldap_connection_t **pconn,
			       char const *dn, int scope, char const *filter, char const * const *attrs,
			       LDAPControl **serverctrls, LDAPControl **clientctrls)
{
	fr_ldap_rcode_t			status = LDAP_PROC_ERROR;
	LDAPMessage			*our_result = NULL;

	fr_ldap_config_t const	*handle_config = (*pconn)->config;

	int				msgid;		// Message id returned by
							// ldap_search_ext.

	int				count = 0;	// Number of results we got.

	struct timeval			tv;		// Holds timeout values.

	LDAPControl			*our_serverctrls[LDAP_MAX_CONTROLS];
	LDAPControl			*our_clientctrls[LDAP_MAX_CONTROLS];

	fr_ldap_control_merge(our_serverctrls, our_clientctrls,
			      sizeof(our_serverctrls) / sizeof(*our_serverctrls),
			      sizeof(our_clientctrls) / sizeof(*our_clientctrls),
			      *pconn, serverctrls, clientctrls);

	rad_assert(*pconn && (*pconn)->handle);

	if (DEBUG_ENABLED4 || (request && RDEBUG_ENABLED4)) {
		fr_ldap_timeout_debug(request, *pconn, NULL, __FUNCTION__);
	}

	/*
	 *	OpenLDAP library doesn't declare attrs array as const, but
	 *	it really should be *sigh*.
	 */
	char **search_attrs;
	memcpy(&search_attrs, &attrs, sizeof(attrs));

	/*
	 *	Do all searches as the admin user.
	 */
	if ((*pconn)->rebound) {
		status = fr_ldap_bind(request, pconn,
				      (*pconn)->config->admin_identity, (*pconn)->config->admin_password,
				      &(*pconn)->config->admin_sasl, NULL,
				      NULL, NULL);
		if (status != LDAP_PROC_SUCCESS) return LDAP_PROC_ERROR;

		rad_assert(*pconn);

		(*pconn)->rebound = false;
	}

	if (filter) {
		ROPTIONAL(RDEBUG2, DEBUG2, "Performing search in \"%s\" with filter \"%s\", scope \"%s\"", dn, filter,
			  fr_int2str(fr_ldap_scope, scope, "<INVALID>"));
	} else {
		ROPTIONAL(RDEBUG2, DEBUG2, "Performing unfiltered search in \"%s\", scope \"%s\"", dn,
			  fr_int2str(fr_ldap_scope, scope, "<INVALID>"));
	}
	/*
	 *	If LDAP search produced an error it should also be logged
	 *	to the ld. result should pick it up without us
	 *	having to pass it explicitly.
	 */
	memset(&tv, 0, sizeof(tv));

	(void) ldap_search_ext((*pconn)->handle, dn, scope, filter, search_attrs,
			       0, our_serverctrls, our_clientctrls, NULL, 0, &msgid);

	ROPTIONAL(RDEBUG2, DEBUG2, "Waiting for search result...");
	status = fr_ldap_result(&our_result, NULL, *pconn, msgid, 1, dn, NULL);
	switch (status) {
	case LDAP_PROC_SUCCESS:
		break;

	default:
		ROPTIONAL(RPEDEBUG, PERROR, "Failed performing search");

		goto finish;
	}

	count = ldap_count_entries((*pconn)->handle, our_result);
	if (count < 0) {
		ROPTIONAL(REDEBUG, ERROR, "Error counting results: %s", fr_ldap_error_str(*pconn));
		status = LDAP_PROC_ERROR;

		ldap_msgfree(our_result);
		our_result = NULL;
	} else if (count == 0) {
		ROPTIONAL(RDEBUG2, DEBUG2, "Search returned no results");
		status = LDAP_PROC_NO_RESULT;

		ldap_msgfree(our_result);
		our_result = NULL;
	}

finish:

	/*
	 *	We always need to get the result to count entries, but the caller
	 *	may not of requested one. If that's the case, free it, else write
	 *	it to where our caller said.
	 */
	if (!result) {
		if (our_result) ldap_msgfree(our_result);
	} else {
		*result = our_result;
	}

	return status;
}
Exemple #23
0
/** Search for something in the LDAP directory
 *
 * Binds as the administrative user and performs a search, dealing with any errors.
 *
 * @param[out] msgid		to match response to request.
 * @param[in] request		Current request.
 * @param[in,out] pconn		to use. May change as this function calls functions which auto re-connect.
 * @param[in] dn		to use as base for the search.
 * @param[in] scope		to use (LDAP_SCOPE_BASE, LDAP_SCOPE_ONE, LDAP_SCOPE_SUB).
 * @param[in] filter		to use, should be pre-escaped.
 * @param[in] attrs		to retrieve.
 * @param[in] serverctrls	Search controls to pass to the server.  May be NULL.
 * @param[in] clientctrls	Search controls for ldap_search.  May be NULL.
 * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values.
 */
fr_ldap_rcode_t fr_ldap_search_async(int *msgid, REQUEST *request,
				     fr_ldap_connection_t **pconn,
				     char const *dn, int scope, char const *filter, char const * const *attrs,
				     LDAPControl **serverctrls, LDAPControl **clientctrls)
{
	fr_ldap_rcode_t			status = LDAP_PROC_ERROR;

	fr_ldap_config_t const	*handle_config = (*pconn)->config;

	struct timeval			tv;		// Holds timeout values.

	LDAPControl			*our_serverctrls[LDAP_MAX_CONTROLS];
	LDAPControl			*our_clientctrls[LDAP_MAX_CONTROLS];

	fr_ldap_control_merge(our_serverctrls, our_clientctrls,
			      sizeof(our_serverctrls) / sizeof(*our_serverctrls),
			      sizeof(our_clientctrls) / sizeof(*our_clientctrls),
			      *pconn, serverctrls, clientctrls);

	rad_assert(*pconn && (*pconn)->handle);

	if (DEBUG_ENABLED4 || (request && RDEBUG_ENABLED4)) fr_ldap_timeout_debug(request, *pconn, NULL, __FUNCTION__);

	/*
	 *	OpenLDAP library doesn't declare attrs array as const, but
	 *	it really should be *sigh*.
	 */
	char **search_attrs;
	memcpy(&search_attrs, &attrs, sizeof(attrs));

	/*
	 *	Do all searches as the admin user.
	 */
	if ((*pconn)->rebound) {
		status = fr_ldap_bind(request, pconn,
				      (*pconn)->config->admin_identity, (*pconn)->config->admin_password,
				      &(*pconn)->config->admin_sasl, NULL,
				      NULL, NULL);
		if (status != LDAP_PROC_SUCCESS) return LDAP_PROC_ERROR;

		rad_assert(*pconn);

		(*pconn)->rebound = false;
	}

	if (filter) {
		ROPTIONAL(RDEBUG2, DEBUG2, "Performing search in \"%s\" with filter \"%s\", scope \"%s\"", dn, filter,
			  fr_int2str(fr_ldap_scope, scope, "<INVALID>"));
	} else {
		ROPTIONAL(RDEBUG2, DEBUG2, "Performing unfiltered search in \"%s\", scope \"%s\"", dn,
			  fr_int2str(fr_ldap_scope, scope, "<INVALID>"));
	}
	/*
	 *	If LDAP search produced an error it should also be logged
	 *	to the ld. result should pick it up without us
	 *	having to pass it explicitly.
	 */
	memset(&tv, 0, sizeof(tv));

	if (ldap_search_ext((*pconn)->handle, dn, scope, filter, search_attrs,
			    0, our_serverctrls, our_clientctrls, NULL, 0, msgid) != LDAP_SUCCESS) {
		int ldap_errno;

		ldap_get_option((*pconn)->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
		ERROR("Failed performing search: %s", ldap_err2string(ldap_errno));

		return LDAP_PROC_ERROR;
	}

	return LDAP_PROC_SUCCESS;
}
Exemple #24
0
void
OPENLDAP::Book::refresh_bound ()
{
  int result = LDAP_SUCCESS;
  struct timeval timeout = { 1, 0}; /* block 1s */
  LDAPMessage *msg_entry = NULL;
  int msgid;
  std::string filter, fterm;
  const char *fstr;
  size_t pos;

  if (bookinfo.sasl)
    goto sasl_bound;

  result = ldap_result (ldap_context, LDAP_RES_ANY, LDAP_MSG_ALL,
			&timeout, &msg_entry);

  if (result <= 0) {

    if (patience == 3) {
      patience--;
      Ekiga::Runtime::run_in_main (boost::bind (&OPENLDAP::Book::refresh_bound, this), 12);
    } else if (patience == 2) {

      patience--;
      Ekiga::Runtime::run_in_main (boost::bind (&OPENLDAP::Book::refresh_bound, this), 21);
    } else if (patience == 1) {

      patience--;
      Ekiga::Runtime::run_in_main (boost::bind (&OPENLDAP::Book::refresh_bound, this), 30);
    } else { // patience == 0

      status = std::string (_("Could not connect to server"));
      updated (this->shared_from_this ());

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

    if (msg_entry != NULL)
      ldap_msgfree (msg_entry);

    return;
  }
  (void) ldap_msgfree (msg_entry);

 sasl_bound:
  if (!search_filter.empty ()) {
    if (search_filter[0] == '(' &&
        search_filter[search_filter.length()-1] == ')') {
      fstr = search_filter.c_str();
      goto do_search;
    }
    fterm = "*" + search_filter + "*";
  } else {
    fterm = "*";
  }
  if (bookinfo.urld->lud_filter != NULL)
    filter = std::string (bookinfo.urld->lud_filter);
  else
    filter="";
  pos = 0;
  while ((pos=filter.find('$', pos)) != std::string::npos) {
    filter.replace (pos, 1, fterm);
    pos += fterm.length();
  }
  fstr = filter.c_str();

 do_search:
  msgid = ldap_search_ext (ldap_context,
			   bookinfo.urld->lud_dn,
			   bookinfo.urld->lud_scope,
			   fstr,
			   bookinfo.urld->lud_attrs,
			   0, /* attrsonly */
			   NULL, NULL,
			   NULL, 0, &msgid);

  if (msgid == -1) {

    status = std::string (_("Could not search"));
    updated (this->shared_from_this ());

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

    status = std::string (_("Waiting for search results"));
    updated (this->shared_from_this ());
  }

  patience = 3;
  refresh_result ();
}
int
main( int argc, char **argv )
{
    LDAP	    	*ld;
    LDAPMessage	    	*result, *e;
    BerElement	    	*ber;
    char	    	*a, *dn;
    char	  	**vals;
    int		    	i;
    int		   	rc;
    int			finished;
    int			msgid;
    int			num_entries = 0;
    int			version = LDAP_VERSION3;
    LDAPControl		*ctrls[2], *psctrl, **ectrls;

    /* arrange to use LDAP version 3 */
    if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version ) != 0 ) {
	perror( "ldap_set_option" );
	return( 1 );
    }

    /* get a handle to an LDAP connection */
    if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) {
	perror( "ldap_init" );
	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" );
	ldap_unbind( ld );
	return( 1 );
    }

    /* construct the Persistent Search control */
    if ( ldap_create_persistentsearch_control( ld, LDAP_CHANGETYPE_ANY,
		1 /* changesOnly */, 1 /* request entry change controls */,
		1 /* critical */, &psctrl ) != LDAP_SUCCESS ) {
	ldap_perror( ld, "ldap_create_persistentsearch_control" );
	ldap_unbind( ld );
	return( 1 );
    }
    ctrls[0] = psctrl;
    ctrls[1] = NULL;

    /* issue a persistent search for all entries with surname of Jensen */
    if ( LDAP_SUCCESS != ldap_search_ext( ld, MY_SEARCHBASE,
	    LDAP_SCOPE_SUBTREE, MY_FILTER, NULL /* all attrs */,
	    0 /* get attrs and values */, ctrls, NULL /* no client ctrls */,
	    NULL /* no timeout */, 0 /* no sizelimit */, &msgid )) {
	ldap_perror( ld, "ldap_search_ext" );
	ldap_unbind( ld );
	return( 1 );
    }

    ldap_control_free( psctrl );	/* no longer needed */

    /*
     * Loop, polling for results until finished.
     * Since this is a persistent search, this loop won't end until the
     * server shuts down or we lose the connection for some other reason.
     * We could abandon the persistent search or close the connection of
     * course, but we don't in this example.
     */
    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, NULL /* no timeout */, &result );
	switch ( rc ) {
	case -1:
	    /* some error occurred */
	    ldap_perror( ld, "ldap_result" );
	    ldap_unbind( ld );
	    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;
	    }
	    num_entries++;

	    /* for each entry print out name */
	    if (( dn = ldap_get_dn( ld, e )) != NULL ) {
		printf( "dn: %s\n", dn );
		ldap_memfree( dn );
	    }

	    /* print entry change info. if it was returned */
	    if ( LDAP_SUCCESS == ldap_get_entry_controls( ld, e, &ectrls )) {
		int         chgnumpresent;
        ber_int_t   chgtype;
		ber_int_t   chgnum;
		char        *prevdn;

		if ( LDAP_SUCCESS == ldap_parse_entrychange_control( ld,
			ectrls, &chgtype, &prevdn, &chgnumpresent, &chgnum )) {
		    printf( "changeType: %s\n",
			    changetype_num2string( chgtype ));
		    if ( prevdn != NULL ) {
			printf( "previousDN: %s\n", prevdn );
			ldap_memfree( prevdn );
		    }
		    if ( chgnumpresent ) {
			printf( "changeNumber: %d\n", chgnum );
		    }
		    ldap_controls_free( ectrls );
		}
	    }

	    /* print out all attrs and values */
	    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 );
	}
    }

    /* All done.  Print a summary. */
    printf( "%d entries retrieved.\n", num_entries );
    ldap_unbind( ld );
    return( 0 );
}
Exemple #26
0
/*
 * ldap_load:
 * opens the connection only if needed.
 */
static LibBalsaABErr
libbalsa_address_book_ldap_load(LibBalsaAddressBook * ab,
                                const gchar *filter,
                                LibBalsaAddressBookLoadFunc callback,
                                gpointer closure)
{
    LibBalsaAddressBookLdap *ldap_ab;
    LibBalsaAddress *address;
    LDAPMessage *msg, *result;
    int msgid, rc, attempt;
    gchar *ldap_filter;

    g_return_val_if_fail ( LIBBALSA_IS_ADDRESS_BOOK_LDAP(ab), LBABERR_OK);

    if (callback == NULL)
	return LBABERR_OK;

    ldap_ab = LIBBALSA_ADDRESS_BOOK_LDAP(ab);
    /*
     * Connect to the server.
     */
    for(attempt=0; attempt<2; attempt++) {
        if (ldap_ab->directory == NULL) {
            if ((rc=libbalsa_address_book_ldap_open_connection(ldap_ab))
                != LDAP_SUCCESS)
                return LBABERR_CANNOT_CONNECT;
        }
        
        /* 
         * Attempt to search for e-mail addresses. It returns success 
         * or failure, but not all the matches. 
         * we use the asynchronous lookup to fetch the results in chunks
         * in case we exceed administrative limits.
         */ 
        /* g_print("Performing full lookup…\n"); */
        ldap_filter = filter 
            ? g_strdup_printf("(&(objectClass=organizationalPerson)(mail=*)"
                              "(|(cn=%s*)(sn=%s*)(mail=%s*@*)))",
                              filter, filter, filter)
            : g_strdup("(&(objectClass=organizationalPerson)(mail=*))");
	if(DEBUG_LDAP)
	    g_print("Send LDAP request: %s (basedn=%s)\n", ldap_filter,
		    ldap_ab->base_dn);
        if(ldap_search_ext(ldap_ab->directory, ldap_ab->base_dn,
                           LDAP_SCOPE_SUBTREE, 
                           ldap_filter, book_attrs, 0, NULL, NULL,
                           NULL, ABL_SIZE_LIMIT, &msgid) != LDAP_SUCCESS) {
            libbalsa_address_book_ldap_close_connection(ldap_ab);
            continue; /* try again */
        }
        /* 
         * Now loop over all the results, and spit out the output.
         */
        
        while((rc=ldap_result(ldap_ab->directory, msgid, 
                              LDAP_MSG_ONE, NULL, &result))>0) {
            msg = ldap_first_entry(ldap_ab->directory, result);
            if (!msg || ldap_msgtype( msg ) == LDAP_RES_SEARCH_RESULT)
                break;
            address = libbalsa_address_book_ldap_get_address(ab, msg);
            callback(ab, address, closure);
            g_object_unref(address);
        }
        if(rc == -1) { /* try again */
            libbalsa_address_book_ldap_close_connection(ldap_ab);
            continue;
	}
        callback(ab, NULL, closure);
        ldap_msgfree(result);
        libbalsa_address_book_set_status(ab, NULL);
        return LBABERR_OK;
    }
    /* we have tried and failed... */
    /* extended status? */
    return LBABERR_CANNOT_SEARCH;
}
static void
do_search( char *uri, char *manager, struct berval *passwd,
	char *sbase, int scope, char *filter, LDAP **ldp,
	char **attrs, int noattrs, int nobind,
	int innerloop, int maxretries, int delay, int force, int chaserefs )
{
	LDAP	*ld = ldp ? *ldp : NULL;
	int  	i = 0, do_retry = maxretries;
	int     rc = LDAP_SUCCESS;
	int	version = LDAP_VERSION3;
	char	buf[ BUFSIZ ];
	int		*msgids = NULL, active = 0;

	/* make room for msgid */
	if ( swamp > 1 ) {
		msgids = (int *)calloc( sizeof(int), innerloop );
	}

retry:;
	if ( ld == NULL ) {
		ldap_initialize( &ld, uri );
		if ( ld == NULL ) {
			tester_perror( "ldap_initialize", NULL );
			exit( EXIT_FAILURE );
		}

		(void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
		(void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
			chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );

		if ( do_retry == maxretries ) {
			fprintf( stderr,
				"PID=%ld - Search(%d): "
				"base=\"%s\" scope=%s filter=\"%s\" "
				"attrs=%s%s.\n",
				(long) pid, innerloop,
				sbase, ldap_pvt_scope2str( scope ), filter,
				attrs[0], attrs[1] ? " (more...)" : "" );
		}

		if ( nobind == 0 ) {
			rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
			if ( rc != LDAP_SUCCESS ) {
				snprintf( buf, sizeof( buf ),
					"bindDN=\"%s\"", manager );
				tester_ldap_error( ld, "ldap_sasl_bind_s", buf );
				switch ( rc ) {
				case LDAP_BUSY:
				case LDAP_UNAVAILABLE:
					if ( do_retry > 0 ) {
						ldap_unbind_ext( ld, NULL, NULL );
						ld = NULL;
						do_retry--;
						if ( delay != 0 ) {
						    sleep( delay );
						}
						goto retry;
					}
				/* fallthru */
				default:
					break;
				}
				exit( EXIT_FAILURE );
			}
		}
	}

	if ( swamp > 1 ) {
		do {
			LDAPMessage *res = NULL;
			int j, msgid;

			if ( i < innerloop ) {
				rc = ldap_search_ext( ld, sbase, scope,
						filter, NULL, noattrs, NULL, NULL,
						NULL, LDAP_NO_LIMIT, &msgids[i] );

				active++;
#if 0
				fprintf( stderr,
					">>> PID=%ld - Search maxloop=%d cnt=%d active=%d msgid=%d: "
					"base=\"%s\" scope=%s filter=\"%s\"\n",
					(long) pid, innerloop, i, active, msgids[i],
					sbase, ldap_pvt_scope2str( scope ), filter );
#endif
				i++;

				if ( rc ) {
					int first = tester_ignore_err( rc );
					/* if ignore.. */
					if ( first ) {
						/* only log if first occurrence */
						if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
							tester_ldap_error( ld, "ldap_search_ext", NULL );
						}
						continue;
					}
		
					/* busy needs special handling */
					snprintf( buf, sizeof( buf ),
						"base=\"%s\" filter=\"%s\"\n",
						sbase, filter );
					tester_ldap_error( ld, "ldap_search_ext", buf );
					if ( rc == LDAP_BUSY && do_retry > 0 ) {
						ldap_unbind_ext( ld, NULL, NULL );
						ld = NULL;
						do_retry--;
						goto retry;
					}
					break;
				}

				if ( swamp > 2 ) {
					continue;
				}
			}

			rc = ldap_result( ld, LDAP_RES_ANY, 0, NULL, &res );
			switch ( rc ) {
			case -1:
				/* gone really bad */
				goto cleanup;
	
			case 0:
				/* timeout (impossible) */
				break;
	
			case LDAP_RES_SEARCH_ENTRY:
			case LDAP_RES_SEARCH_REFERENCE:
				/* ignore */
				break;
	
			case LDAP_RES_SEARCH_RESULT:
				/* just remove, no error checking (TODO?) */
				msgid = ldap_msgid( res );
				ldap_parse_result( ld, res, &rc, NULL, NULL, NULL, NULL, 1 );
				res = NULL;

				/* linear search, bah */
				for ( j = 0; j < i; j++ ) {
					if ( msgids[ j ] == msgid ) {
						msgids[ j ] = -1;
						active--;
#if 0
						fprintf( stderr,
							"<<< PID=%ld - SearchDone maxloop=%d cnt=%d active=%d msgid=%d: "
							"base=\"%s\" scope=%s filter=\"%s\"\n",
							(long) pid, innerloop, j, active, msgid,
							sbase, ldap_pvt_scope2str( scope ), filter );
#endif
						break;
					}
				}
				break;

			default:
				/* other messages unexpected */
				fprintf( stderr,
					"### PID=%ld - Search(%d): "
					"base=\"%s\" scope=%s filter=\"%s\" "
					"attrs=%s%s. unexpected response tag=%d\n",
					(long) pid, innerloop,
					sbase, ldap_pvt_scope2str( scope ), filter,
					attrs[0], attrs[1] ? " (more...)" : "", rc );
				break;
			}

			if ( res != NULL ) {
				ldap_msgfree( res );
			}
		} while ( i < innerloop || active > 0 );

	} else {
		for ( ; i < innerloop; i++ ) {
			LDAPMessage *res = NULL;

			if (swamp) {
				int msgid;
				rc = ldap_search_ext( ld, sbase, scope,
						filter, NULL, noattrs, NULL, NULL,
						NULL, LDAP_NO_LIMIT, &msgid );
				if ( rc == LDAP_SUCCESS ) continue;
				else break;
			}
	
			rc = ldap_search_ext_s( ld, sbase, scope,
					filter, attrs, noattrs, NULL, NULL,
					NULL, LDAP_NO_LIMIT, &res );
			if ( res != NULL ) {
				ldap_msgfree( res );
			}
	
			if ( rc ) {
				int first = tester_ignore_err( rc );
				/* if ignore.. */
				if ( first ) {
					/* only log if first occurrence */
					if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
						tester_ldap_error( ld, "ldap_search_ext_s", NULL );
					}
					continue;
				}
	
				/* busy needs special handling */
				snprintf( buf, sizeof( buf ),
					"base=\"%s\" filter=\"%s\"\n",
					sbase, filter );
				tester_ldap_error( ld, "ldap_search_ext_s", buf );
				if ( rc == LDAP_BUSY && do_retry > 0 ) {
					ldap_unbind_ext( ld, NULL, NULL );
					ld = NULL;
					do_retry--;
					goto retry;
				}
				break;
			}
		}
	}

cleanup:;
	if ( msgids != NULL ) {
		free( msgids );
	}

	if ( ldp != NULL ) {
		*ldp = ld;

	} else {
		fprintf( stderr, "  PID=%ld - Search done (%d).\n", (long) pid, rc );

		if ( ld != NULL ) {
			ldap_unbind_ext( ld, NULL, NULL );
		}
	}
}
Exemple #28
0
static int
do_base( char *uri, char *dn, struct berval *pass, char *base, char *filter, char *pwattr,
	int maxloop, int force, int chaserefs, int noinit, int delay,
	int action_type, void *action )
{
	LDAP	*ld = NULL;
	int  	i = 0;
	int     rc = LDAP_SUCCESS;
	ber_int_t msgid;
	LDAPMessage *res, *msg;
	char **dns = NULL;
	struct berval *creds = NULL;
	char *attrs[] = { LDAP_NO_ATTRS, NULL };
	int ndns = 0;
#ifdef _WIN32
	DWORD beg, end;
#else
	struct timeval beg, end;
#endif
	int version = LDAP_VERSION3;
	char *nullstr = "";

	ldap_initialize( &ld, uri );
	if ( ld == NULL ) {
		tester_perror( "ldap_initialize", NULL );
		exit( EXIT_FAILURE );
	}

	(void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
	(void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
		chaserefs ? LDAP_OPT_ON: LDAP_OPT_OFF );

	rc = ldap_sasl_bind_s( ld, dn, LDAP_SASL_SIMPLE, pass, NULL, NULL, NULL );
	if ( rc != LDAP_SUCCESS ) {
		tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
		exit( EXIT_FAILURE );
	}

	fprintf( stderr, "PID=%ld - Bind(%d): base=\"%s\", filter=\"%s\" attr=\"%s\".\n",
			(long) pid, maxloop, base, filter, pwattr );

	if ( pwattr != NULL ) {
		attrs[ 0 ] = pwattr;
	}
	rc = ldap_search_ext( ld, base, LDAP_SCOPE_SUBTREE,
			filter, attrs, 0, NULL, NULL, 0, 0, &msgid );
	if ( rc != LDAP_SUCCESS ) {
		tester_ldap_error( ld, "ldap_search_ext", NULL );
		exit( EXIT_FAILURE );
	}

	while ( ( rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res ) ) > 0 )
	{
		BerElement *ber;
		struct berval bv;
		int done = 0;

		for ( msg = ldap_first_message( ld, res ); msg;
			msg = ldap_next_message( ld, msg ) )
		{
			switch ( ldap_msgtype( msg ) ) {
			case LDAP_RES_SEARCH_ENTRY:
				rc = ldap_get_dn_ber( ld, msg, &ber, &bv );
				dns = realloc( dns, (ndns + 1)*sizeof(char *) );
				dns[ndns] = ber_strdup( bv.bv_val );
				if ( pwattr != NULL ) {
					struct berval	**values = ldap_get_values_len( ld, msg, pwattr );

					creds = realloc( creds, (ndns + 1)*sizeof(struct berval) );
					if ( values == NULL ) {
novals:;
						creds[ndns].bv_len = 0;
						creds[ndns].bv_val = nullstr;

					} else {
						static struct berval	cleartext = BER_BVC( "{CLEARTEXT} " );
						struct berval		value = *values[ 0 ];

						if ( value.bv_val[ 0 ] == '{' ) {
							char *end = ber_bvchr( &value, '}' );

							if ( end ) {
								if ( ber_bvcmp( &value, &cleartext ) == 0 ) {
									value.bv_val += cleartext.bv_len;
									value.bv_len -= cleartext.bv_len;

								} else {
									ldap_value_free_len( values );
									goto novals;
								}
							}

						}

						ber_dupbv( &creds[ndns], &value );
						ldap_value_free_len( values );
					}
				}
				ndns++;
				ber_free( ber, 0 );
				break;

			case LDAP_RES_SEARCH_RESULT:
				done = 1;
				break;
			}
			if ( done )
				break;
		}
		ldap_msgfree( res );
		if ( done ) break;
	}

#ifdef _WIN32
	beg = GetTickCount();
#else
	gettimeofday( &beg, NULL );
#endif

	if ( ndns == 0 ) {
		tester_error( "No DNs" );
		return 1;
	}

	fprintf( stderr, "  PID=%ld - Bind base=\"%s\" filter=\"%s\" got %d values.\n",
		(long) pid, base, filter, ndns );

	/* Ok, got list of DNs, now start binding to each */
	for ( i = 0; i < maxloop; i++ ) {
		int		j;
		struct berval	cred = { 0, NULL };


#if 0	/* use high-order bits for better randomness (Numerical Recipes in "C") */
		j = rand() % ndns;
#endif
		j = ((double)ndns)*rand()/(RAND_MAX + 1.0);

		if ( creds && !BER_BVISEMPTY( &creds[j] ) ) {
			cred = creds[j];
		}

		if ( do_bind( uri, dns[j], &cred, 1, force, chaserefs, noinit, &ld,
			action_type, action ) && !force )
		{
			break;
		}

		if ( delay ) {
			sleep( delay );
		}
	}

	if ( ld != NULL ) {
		ldap_unbind_ext( ld, NULL, NULL );
		ld = NULL;
	}

#ifdef _WIN32
	end = GetTickCount();
	end -= beg;

	fprintf( stderr, "  PID=%ld - Bind done %d in %d.%03d seconds.\n",
		(long) pid, i, end / 1000, end % 1000 );
#else
	gettimeofday( &end, NULL );
	end.tv_usec -= beg.tv_usec;
	if (end.tv_usec < 0 ) {
		end.tv_usec += 1000000;
		end.tv_sec -= 1;
	}
	end.tv_sec -= beg.tv_sec;

	fprintf( stderr, "  PID=%ld - Bind done %d in %ld.%06ld seconds.\n",
		(long) pid, i, (long) end.tv_sec, (long) end.tv_usec );
#endif

	if ( dns ) {
		for ( i = 0; i < ndns; i++ ) {
			ber_memfree( dns[i] );
		}
		free( dns );
	}

	if ( creds ) {
		for ( i = 0; i < ndns; i++ ) {
			if ( creds[i].bv_val != nullstr ) {
				ber_memfree( creds[i].bv_val );
			}
		}
		free( creds );
	}

	return 0;
}
Exemple #29
0
static int
_mu_ldap_search (LDAP *ld, const char *filter_pat, const char *key,
		 struct mu_auth_data **return_data)
{
  int rc;
  char **attrs;
  size_t nattrs;
  LDAPMessage *res, *msg;
  ber_int_t msgid;
  const char *env[3];
  struct mu_wordsplit ws;

  rc = _construct_attr_array (&nattrs, &attrs);
  if (rc)
    return rc;

  env[0] = "user";
  env[1] = key;
  env[2] = NULL;

  ws.ws_env = env;
  if (mu_wordsplit (filter_pat, &ws,
		    MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
		    MU_WRDSF_ENV | MU_WRDSF_ENV_KV))
    {
      mu_error (_("cannot expand line `%s': %s"), filter_pat,
		mu_wordsplit_strerror (&ws));
      return MU_ERR_FAILURE;
    }
  else if (ws.ws_wordc == 0)
    {
      mu_error (_("expanding %s yields empty string"), filter_pat);
      mu_wordsplit_free (&ws);
      mu_argcv_free (nattrs, attrs);
      return MU_ERR_FAILURE;
    }
  
  rc = ldap_search_ext (ld, ldap_param.base, LDAP_SCOPE_SUBTREE,
			ws.ws_wordv[0], attrs, 0,
			NULL, NULL, NULL, -1, &msgid);
  mu_wordsplit_free (&ws);
  mu_argcv_free (nattrs, attrs);

  if (rc != LDAP_SUCCESS)
    {
      mu_error ("ldap_search_ext: %s", ldap_err2string (rc));
      if (rc == LDAP_NO_SUCH_OBJECT)
	return MU_ERR_NOENT;
      else
	return MU_ERR_FAILURE;
    }

  rc = ldap_result (ld, msgid, LDAP_MSG_ALL, NULL, &res );
  if (rc < 0)
    {
      mu_error ("ldap_result failed");
      return MU_ERR_FAILURE;
    }

  rc = ldap_count_entries (ld, res);
  if (rc == 0)
    {
      mu_error ("not enough entires");
      return MU_ERR_NOENT;
    }
  if (rc > 1)
    mu_error ("LDAP: too many entries for key %s", key);
      

  msg = ldap_first_entry (ld, res);
  rc = _mu_entry_to_auth_data (ld, msg, return_data);
  ldap_msgfree (res);
  
  return rc;
}
Exemple #30
0
int ld_cmd_exec(db_res_t* res, db_cmd_t* cmd)
{
	db_con_t* con;
	struct ld_res* lres;
	struct ld_cmd* lcmd;
	struct ld_con* lcon;
	char* filter, *err_desc;
	int ret, err;
	LDAPMessage *msg, *resmsg;
	int reconn_cnt;
	int msgid;
	char *oid;
	struct berval *data;
	struct timeval restimeout;

	filter = NULL;
	err_desc = NULL;
	resmsg = NULL;

	/* First things first: retrieve connection info from the currently active
	 * connection and also mysql payload from the database command
	 */
	con = cmd->ctx->con[db_payload_idx];
	lcmd = DB_GET_PAYLOAD(cmd);
	lcon = DB_GET_PAYLOAD(con);
	
	reconn_cnt = ld_reconnect_attempt;

	if (ld_prepare_ldap_filter(&filter, cmd, &lcmd->filter) < 0) {
		ERR("ldap: Error while building LDAP search filter\n");
		goto error;
	}

	DBG("ldap: ldap_search(base:'%s', filter:'%s')\n", lcmd->base, filter);
	do {
		if (lcon->flags & LD_CONNECTED) {
			ldap_set_option(lcon->con, LDAP_OPT_DEREF, ((void *)&lcmd->chase_references));
			/* there is alternative method using LDAP_CONTROL_REFERRALS per request but is not well documented */
			ldap_set_option(lcon->con, LDAP_OPT_REFERRALS, lcmd->chase_referrals?LDAP_OPT_ON:LDAP_OPT_OFF);
		
			ret = ldap_search_ext(lcon->con, lcmd->base, lcmd->scope, filter,
								  lcmd->result, 0, NULL, NULL,
								  lcmd->timelimit.tv_sec ? &lcmd->timelimit : NULL,
								  lcmd->sizelimit,
								  &msgid);
			if (ret != LDAP_SUCCESS) {
				ERR("ldap: Error while searching: %s\n", ldap_err2string(ret));
				goto error;
			}

			/*
			 openldap v2.3 library workaround for unsolicited messages:
			 if only unsolicited messages are available then ldap_result of
			 v2.3 library waits forever
			*/
			memset(&restimeout, 0, sizeof(restimeout));
			restimeout.tv_sec = 5;
			ret = ldap_result(lcon->con,
							  LDAP_RES_ANY,
							  LDAP_MSG_ALL,
							  &restimeout,
							  &resmsg);
		} else {
			/* force it to reconnect */
			ret = -1;
		}

		if (ret <= 0) {
			ERR("ldap: Error in ldap_search: %s\n", ret < 0 ? ldap_err2string(ret) : "timeout");
			if (ret == LDAP_SERVER_DOWN) {
				lcon->flags &= ~LD_CONNECTED;
				do {
					if (!reconn_cnt) {
						ERR("ldap: maximum reconnection attempt reached! giving up\n");
						goto error;
					}
					reconn_cnt--;
					err = ld_con_connect(con);
				} while (err != 0);
			} else {
				goto error;
			}
		}
	} while (ret <= 0);

	/* looking for unsolicited messages */
	for (msg = ldap_first_message(lcon->con, resmsg);
		 msg != NULL;
		 msg = ldap_next_message(lcon->con, msg)) {
		if (ldap_msgtype(msg) == LDAP_RES_EXTENDED) {
			if (ldap_parse_extended_result(lcon->con,
										   msg,
										   &oid,
										   &data,
										   0) != LDAP_SUCCESS) {
				ERR("ldap: Error while parsing extended result\n");
 				goto error;
			}
			if (oid != NULL) {
				if (strcmp(oid, LDAP_NOTICE_OF_DISCONNECTION) == 0) {
					WARN("ldap: Notice of Disconnection (OID: %s)\n", oid);
				} else {
					WARN("ldap: Unsolicited message received. OID: %s\n", oid);
				}
				ldap_memfree(oid);
			}
			if (data != NULL) {
				WARN("ldap: Unsolicited message data: %.*s\n",
					 (int)data->bv_len, data->bv_val);
				ber_bvfree(data);
			}
		}
	}

	ret = ldap_parse_result(lcon->con, resmsg, &err, NULL, &err_desc, NULL, NULL, 0);
	if (ret != LDAP_SUCCESS) {
		ERR("ldap: Error while reading result status: %s\n",
			ldap_err2string(ret));
		goto error;
	}

	if (err != LDAP_SUCCESS) {
		ERR("ldap: LDAP server reports error: %s\n", ldap_err2string(err));
		goto error;
	}

	if (res) {
		lres = DB_GET_PAYLOAD(res);
		lres->msg = resmsg;
	} else if (resmsg) {
		ldap_msgfree(resmsg);
	}

	if (filter) pkg_free(filter);
	if (err_desc) ldap_memfree(err_desc);
	return 0;

 error:
	if (filter) pkg_free(filter);
	if (resmsg) ldap_msgfree(resmsg);
	if (err_desc) ldap_memfree(err_desc);
	return -1;
}