Exemplo n.º 1
0
krb5_error_code ipadb_simple_search(struct ipadb_context *ipactx,
                                    char *basedn, int scope,
                                    char *filter, char **attrs,
                                    LDAPMessage **res)
{
    int ret;

    ret = ipadb_check_connection(ipactx);
    if (ret != 0)
        return ipadb_simple_ldap_to_kerr(ret);

    ret = ldap_search_ext_s(ipactx->lcontext, basedn, scope,
                            filter, attrs, 0, NULL, NULL,
                            &std_timeout, LDAP_NO_LIMIT,
                            res);

    /* first test if we need to retry to connect */
    if (ret != 0 &&
        ipadb_need_retry(ipactx, ret)) {
        ldap_msgfree(*res);
        ret = ldap_search_ext_s(ipactx->lcontext, basedn, scope,
                                filter, attrs, 0, NULL, NULL,
                                &std_timeout, LDAP_NO_LIMIT,
                                res);
    }

    return ipadb_simple_ldap_to_kerr(ret);
}
Exemplo n.º 2
0
krb5_error_code ipadb_multibase_search(struct ipadb_context *ipactx,
                                       char **basedns, int scope,
                                       char *filter, char **attrs,
                                       struct ipadb_multires **res,
                                       bool any)
{
    int ret;

    ret = ipadb_multires_init(ipactx->lcontext, res);
    if (ret != 0) return ret;

    ret = ipadb_check_connection(ipactx);
    if (ret != 0)
        return ipadb_simple_ldap_to_kerr(ret);

    for (int b = 0; basedns[b]; b++) {
        LDAPMessage *r;
        ret = ldap_search_ext_s(ipactx->lcontext, basedns[b], scope,
                                filter, attrs, 0, NULL, NULL,
                                &std_timeout, LDAP_NO_LIMIT, &r);

        /* first test if we need to retry to connect */
        if (ret != 0 &&
            ipadb_need_retry(ipactx, ret)) {
            ldap_msgfree(r);
            ret = ldap_search_ext_s(ipactx->lcontext, basedns[b], scope,
                                    filter, attrs, 0, NULL, NULL,
                                    &std_timeout, LDAP_NO_LIMIT, &r);
        }

        if (ret != 0) break;

        if (ldap_count_entries(ipactx->lcontext, r) > 0) {
            void *tmp = realloc((*res)->res, (((*res)->count + 1) *
                                                sizeof(LDAPMessage *)));
            if (tmp == NULL) {
                ret = ENOMEM;
                break;
            }
            (*res)->res = tmp;
            (*res)->res[(*res)->count] = r;
            (*res)->count++;

            if (any) break;
        }
    }

    if (ret != 0) {
        ipadb_multires_free(*res);
        *res = NULL;
    }

    return ipadb_simple_ldap_to_kerr(ret);
}
Exemplo n.º 3
0
char *ReadLDAPValue(const char *Filter, char *Value)
{
	LDAPMessage	*res, *res2;
	struct berval **attrValues;
	char	*attrNames[] = {Value,NULL};
	char	*ret;
	struct timeval	timeout;
	 int	rv;
	
	timeout.tv_sec = 5;
	timeout.tv_usec = 0;
	
	rv = ldap_search_ext_s(gpLDAP, "", LDAP_SCOPE_BASE, Filter,
		attrNames, 0, NULL, NULL, &timeout, 1, &res
		);
	printf("ReadLDAPValue: rv = %i\n", rv);
	if(rv) {
		fprintf(stderr, "LDAP Error reading '%s' with filter '%s'\n%s\n",
			Value, Filter,
			ldap_err2string(rv)
			);
		return NULL;
	}
	
	res2 = ldap_first_entry(gpLDAP, res);
	attrValues = ldap_get_values_len(gpLDAP, res2, Value);
	
	ret = strndup(attrValues[0]->bv_val, attrValues[0]->bv_len);
	
	ldap_value_free_len(attrValues);
	
	
	return ret;
}
Exemplo n.º 4
0
BOOLEAN
VdcIfDNExist(
    LDAP* pLd,
    PCSTR pszDN)
{
    DWORD           dwError = 0;
    LDAPMessage*    pSearchRes = NULL;

    dwError = ldap_search_ext_s(
                            pLd,
                            pszDN,         /* base */
                            LDAP_SCOPE_BASE,
                            NULL,       /* filter */
                            NULL,       /* attrs */
                            FALSE,      /* attrsonly */
                            NULL,       /* serverctrls */
                            NULL,       /* clientctrls */
                            NULL,       /* timeout */
                            0,          /* sizelimit */
                            &pSearchRes);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    if (pSearchRes)
    {
        ldap_msgfree(pSearchRes);
    }
    return dwError == 0;
error:
    goto cleanup;
}
Exemplo n.º 5
0
Arquivo: ldap.c Projeto: Mujj/tsps
int tsps_ldap_get_userid(const char *user)
{
	char user_filt[128];
	int res;
	char *attrs[] = { "uidNumber", NULL };
	LDAPMessage *vals = NULL;
	LDAPMessage *val;
	int uidnum = -1;

	snprintf(user_filt, sizeof(user_filt), "(uid=%s)", user);
	
	res = ldap_search_ext_s(ldp, server.ldap_user_base,
		LDAP_SCOPE_ONELEVEL, user_filt, attrs, 0, NULL, NULL,
		NULL, 0, &vals);
	if (res != LDAP_SUCCESS) {
		fprintf(stderr, "LDAP search error: %s\n",
			ldap_err2string(res));
		return -1;
	}

	for (val = ldap_first_message(ldp, vals); val;
			val = ldap_next_message(ldp, val)) {
		struct berval **uid_val =
			ldap_get_values_len(ldp, val, "uidNumber");

		if (uid_val) {
			uidnum = (int)strtol(uid_val[0]->bv_val, NULL, 0);
			ldap_value_free_len(uid_val);
			break;
		}
	}

	ldap_msgfree(vals);
	return uidnum;
}
Exemplo n.º 6
0
/*
 * Given a list of naming contexts check each one to see if it has
 * an IPA v2 server in it. The first one we find wins.
 */
static int
check_ipa_server(LDAP *ld, char **ldap_base, struct berval **vals)
{
    struct berval **infovals;
    LDAPMessage *entry, *res = NULL;
    char *info_attrs[] = {"info", NULL};
    int i, ret = 0;

    for (i = 0; !*ldap_base && vals[i]; i++) {
        ret = ldap_search_ext_s(ld, vals[i]->bv_val,
                                LDAP_SCOPE_BASE, "(info=IPA*)", info_attrs,
                                0, NULL, NULL, NULL, 0, &res);

        if (ret != LDAP_SUCCESS) {
            break;
        }

        entry = ldap_first_entry(ld, res);
        infovals = ldap_get_values_len(ld, entry, info_attrs[0]);
        if (!strcmp(infovals[0]->bv_val, "IPA V2.0"))
            *ldap_base = strdup(vals[i]->bv_val);
        ldap_msgfree(res);
        res = NULL;
    }

    return ret;
}
Exemplo n.º 7
0
static int
ldaplookup_search_s(
	LDAP *ld,
	LDAP_CONST char *base,
	int scope,
	LDAP_CONST char *filter,
	char **attrs,
	int attrsonly,
	LDAPMessage **res
) {
	int result;
#ifdef HAVE_LDAP_SEARCH_EXT_S
	result = ldap_search_ext_s(ld, base,
		scope, filter, attrs, attrsonly,
		NULL, NULL, NULL, 0, res);
#else
	result = ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res);
#endif

#ifdef TRACE_BY_LDAP
fprintf(stderr, "TRACE_BY_LDAP ldaplookup_search_s:"
"\n base=%s\n filter=%s\n"
" ldap_search_{XXX}s return 0x%x(%s)\n"
, base, filter
, result, ldap_err2string(result));
#endif
	return(result);
}
Exemplo n.º 8
0
/**
 * Attempt to discover the base DN for a server using LDAP version 3.
 * \param  ld  LDAP handle for a connected server.
 * \param  tov Timeout value (seconds), or 0 for none, default 30 secs.
 * \return List of Base DN's, or NULL if could not read. List should be
 *         g_free() when done.
 */
static GList *ldaputil_test_v3( LDAP *ld, gint tov ) {
	GList *baseDN = NULL;
	gint rc, i;
	LDAPMessage *result, *e;
	gchar *attribs[2];
	BerElement *ber;
	gchar *attribute;
	gchar **vals;
	struct timeval timeout;

	/* Set timeout */
	timeout.tv_usec = 0L;
	if( tov > 0 ) {
		timeout.tv_sec = tov;
	}
	else {
		timeout.tv_sec = 30L;
	}

	/* Test for LDAP version 3 */
	attribs[0] = SYLDAP_V3_TEST_ATTR;
	attribs[1] = NULL;
	rc = ldap_search_ext_s(
		ld, SYLDAP_SEARCHBASE_V3, LDAP_SCOPE_BASE, SYLDAP_TEST_FILTER,
		attribs, 0, NULL, NULL, &timeout, 0, &result );

	if( rc == LDAP_SUCCESS ) {
		/* Process entries */
		for( e = ldap_first_entry( ld, result );
		     e != NULL;
		     e = ldap_next_entry( ld, e ) ) 
		{
			/* Process attributes */
			for( attribute = ldap_first_attribute( ld, e, &ber );
			     attribute != NULL;
			     attribute = ldap_next_attribute( ld, e, ber ) )
			{
				if( strcasecmp(
					attribute, SYLDAP_V3_TEST_ATTR ) == 0 )
				{
					vals = ldap_get_values( ld, e, attribute );
					if( vals != NULL ) {
						for( i = 0; vals[i] != NULL; i++ ) {
							baseDN = g_list_append(
								baseDN, g_strdup( vals[i] ) );
						}
					}
					ldap_value_free( vals );
				}
				ldap_memfree( attribute );
			}
			if( ber != NULL ) {
				ber_free( ber, 0 );
			}
			ber = NULL;
		}
	}
	ldap_msgfree( result );
	return baseDN;
}
Exemplo n.º 9
0
static void
do_read( LDAP *ld, char *entry,
	char **attrs, int noattrs, int nobind, int maxloop,
	int maxretries, int delay, int force, int chaserefs, int idx )
{
	int  	i = 0, do_retry = maxretries;
	int     rc = LDAP_SUCCESS;
	char	thrstr[BUFSIZ];

retry:;
	if ( do_retry == maxretries ) {
		snprintf( thrstr, BUFSIZ, "Read(%d): entry=\"%s\".\n",
			maxloop, entry );
		thread_verbose( idx, thrstr );
	}

	snprintf(thrstr, BUFSIZ, "LD %p cnt: %d (retried %d) (%s)", \
		 (void *) ld, maxloop, (do_retry - maxretries), entry);
	thread_verbose( idx, thrstr );

	for ( ; i < maxloop; i++ ) {
		LDAPMessage *res = NULL;

		rc = ldap_search_ext_s( ld, entry, LDAP_SCOPE_BASE,
				NULL, attrs, noattrs, NULL, NULL, NULL,
				LDAP_NO_LIMIT, &res );
		if ( res != NULL ) {
			ldap_msgfree( res );
		}

		if ( rc == 0 ) {
			rt_pass[idx]++;
		} else {
			int		first = tester_ignore_err( rc );
			char		buf[ BUFSIZ ];

			rt_fail[idx]++;
			snprintf( buf, sizeof( buf ), "ldap_search_ext_s(%s)", entry );

			/* if ignore.. */
			if ( first ) {
				/* only log if first occurrence */
				if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
					tester_ldap_error( ld, buf, NULL );
				}
				continue;
			}

			/* busy needs special handling */
			tester_ldap_error( ld, buf, NULL );
			if ( rc == LDAP_BUSY && do_retry > 0 ) {
				do_retry--;
				goto retry;
			}
			break;
		}
	}
}
Exemplo n.º 10
0
static int st_search(SearchThread *st)
{
    char *filterBuffer = NULL;
    char *pFilter;
    struct timeval timeout;
    struct timeval *timeoutp;
    int scope, attrsOnly = 0;
    LDAPMessage *result;
    int ret;

    scope = myScope;
    if (ntable || numeric) {
        char *s = NULL;
        char num[22]; /* string length of unsigned 64 bit integer + 1 */

        if (! numeric) {
            do {
                s = nt_getrand(ntable);
            } while ((s) && (strlen(s) < 1));
        } else {
            sprintf(num, "%d", get_large_random_number() % numeric);
            s = num;
        }
        filterBuffer = PR_smprintf("%s%s",filter, s ? s : "");
        pFilter = filterBuffer;
    } else {
        pFilter = filter;
    }

    /* Try to get attributes from the attrNameTable */
    if (!attrToReturn)
        attrToReturn = nt_get_all(attrTable);

    if (searchTimelimit <= 0) {
        timeoutp = NULL;
    } else {
        timeout.tv_sec = searchTimelimit;
        timeout.tv_usec = 0;
        timeoutp = &timeout;
    }
    ret = ldap_search_ext_s(st->ld, suffix, scope, pFilter, attrToReturn,
                            attrsOnly, NULL, NULL, timeoutp, -1, &result);
    if (ret != LDAP_SUCCESS) {
        fprintf(stderr, "T%d: failed to search 2, error=0x%02X\n",
                st->id, ret);
    }
    ldap_msgfree(result);
    if(filterBuffer){
        PR_smprintf_free(filterBuffer);
    }

    return ret;
}
Exemplo n.º 11
0
/* ARGSUSED */
int _ns_ldap_search_ext_s(char *service, int flags,
	char *base, int scope, char *filter,
	char **attrs, int attrsonly, LDAPControl **serverctrls,
	LDAPControl **clientctrls, struct timeval *timeoutp, int sizelimit,
	LDAPMessage **res)
{
	LDAP *ld = __s_api_getLDAPconn(flags);

	return (ldap_search_ext_s(ld, base, scope, filter,
		attrs, attrsonly, serverctrls,
		clientctrls, timeoutp, sizelimit, res));
}
Exemplo n.º 12
0
/***********************************************************************
 *      ldap_search_ext_sW     (WLDAP32.@)
 *
 * Search a directory tree (synchronous 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.
 *  timeout     [I] Timeout in seconds.
 *  sizelimit   [I] Maximum number of entries to return. Zero means unlimited.
 *  res         [O] Results of the search operation.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  Call ldap_msgfree to free the results.
 */
ULONG CDECL ldap_search_ext_sW( WLDAP32_LDAP *ld, PWCHAR base, ULONG scope,
    PWCHAR filter, PWCHAR attrs[], ULONG attrsonly, PLDAPControlW *serverctrls,
    PLDAPControlW *clientctrls, struct l_timeval* timeout, ULONG sizelimit, WLDAP32_LDAPMessage **res )
{
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
#ifdef HAVE_LDAP
    char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
    LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;

    ret = WLDAP32_LDAP_NO_MEMORY;

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

    if (!ld || !res) return WLDAP32_LDAP_PARAM_ERROR;

    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;
    }

    ret = map_error( ldap_search_ext_s( ld, baseU, scope, filterU, attrsU, attrsonly,
                                        serverctrlsU, clientctrlsU, (struct timeval *)timeout,
                                        sizelimit, res ));

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

#endif
    return ret;
}
static int
ldap_get_fulldn(LD_session *session, char *username, char *userstr, int username_length)
{
	struct berval cred;
	struct berval *msgidp=NULL;
	char filter[MAXFILTERSTR], *dn;
	int rc = 0;
	char logbuf[MAXLOGBUF];
	LDAPMessage *res, *entry;

	memset(userstr, 0, username_length);

        cred.bv_val = ldap_authorization_bindpasswd;
        cred.bv_len = strlen(ldap_authorization_bindpasswd);

#if LDAP_API_VERSION > 3000
	if((rc = ldap_sasl_bind_s(session->sess, ldap_authorization_binddn, ldap_authorization_type, &cred, NULL, NULL, &msgidp))!=LDAP_SUCCESS) {
		snprintf(logbuf, MAXLOGBUF, "!!!Ldap server %s authentificate with method %s failed: %s", ldap_authorization_host, ldap_authorization_type, ldap_err2string(rc));	
		ldap_log(LOG_DEBUG, logbuf);
		return RETURN_FALSE;
	};

#else
	if((rc = ldap_bind_s(session->sess, ldap_authorization_binddn, ldap_authorization_bindpasswd, LDAP_AUTH_SIMPLE))!=LDAP_SUCCESS) {
		snprintf(logbuf, MAXLOGBUF, "Ldap server %s authentificate failed: %s", ldap_authorization_host, ldap_err2string(rc));	
		ldap_log(LOG_DEBUG, logbuf);
		return RETURN_FALSE;
	}
#endif

	/* create filter for search */
	memset(filter, 0, MAXFILTERSTR);
	snprintf(filter, MAXLOGBUF, "(uid=%s)", username);

	if ((rc = ldap_search_ext_s(session->sess, ldap_authorization_basedn, LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res)) != LDAP_SUCCESS) {
#if LDAP_API_VERSION > 3000
		ldap_unbind_ext(session->sess, NULL, NULL);
#else   
		ldap_unbind(session->sess);
#endif
		return RETURN_FALSE;
	}

	if ((entry = ldap_first_entry(session->sess,res)) == NULL) {
		return RETURN_FALSE;
	} else {
		dn = ldap_get_dn(session->sess, entry);
		strncpy(userstr, dn, strlen(dn));
	};
	ldap_msgfree(res);
	return RETURN_TRUE;
}
Exemplo n.º 14
0
/** 
 * Should be called on an event requiring an ldap search, 
 * will return an slack_ldap_event_t struct. The event 
 * struct will provide all the necessary information 
 * and pointers to relevant information. The function 
 * itself uses the ldap_query_t tree to make a series 
 * of ldap searches to find out information about the 
 * nick provided, or the lack of it. 
 */
void
slack_ldap_search(const char *qval) { 
    slack_ldap_query_t *shead = &head; //Local searches event head 
       
    while(shead->next != NULL) { 
        LDAPMessage *result; 
        syslog(LOG_INFO, "Performing ldap search for %s", qval); 

        char newfilter[strlen(shead->filterstr) + strlen(qval)]; 
        sprintf(newfilter, shead->filterstr, qval); 

        int search_status = ldap_search_ext_s(
                ldap, shead->basednstr, LDAP_SCOPE_SUBTREE, newfilter, NULL, 
                0, NULL, NULL, &timeout, 1, &result);
        syslog(LOG_INFO, "Search Status: %s", ldap_err2string(search_status));
        //if(search_status != LDAP_SUCCESS) { return; } // We should probably die 

        syslog(LOG_INFO, "Parsing ldap search result"); 
    
        LDAPMessage *entry = ldap_first_entry(ldap, result); 
        char *attribute; 
        BerElement *ber; 
        char **vals; 
        int i;
        if(entry != NULL) { 
            syslog(LOG_INFO, "Found LDAP Entry..."); 
            /* For each attribute of the entry that has been parsed */
            for(attribute = ldap_first_attribute(ldap, entry, &ber); 
                    attribute != NULL; // if NULL then we are at the end
                    attribute = ldap_next_attribute(ldap, entry, ber)) {
                /* For each attribute print the attribute name and values */ 
                if ((vals = ldap_get_values(ldap, entry, attribute)) != NULL) { 
                    for(i=0; vals[i] != NULL; i++) { 
                        syslog(LOG_INFO, "FOUND VALUE %s: %s", attribute, vals[i]); 
                        /* We now have to call the ldap event, which allows the 
                        * custom handling from the configuration. */ 
                    }
                    ldap_value_free(vals); // MY 
                }
                ldap_memfree(attribute); // GOD
            }
            if(ber != NULL) { 
                ber_free(ber, 0); // MEMLEAK
            }
        }
        ldap_msgfree(result); // AVERTED

        /* Iterate through to the next ldap search event */ 
        shead = shead->next; 
    } // End While 
}          
Exemplo n.º 15
0
static
DWORD
_GetSchemaEntryFromPartner(
        LDAP *pLd,
        LDAPMessage **ppResult,
        LDAPMessage **ppEntry
        )
{
    DWORD dwError = 0;
    PCSTR pcszFilter = "(objectclass=*)";
    LDAPMessage *pResult = NULL;
    LDAPMessage *pEntry = NULL;

    dwError = ldap_search_ext_s(
            pLd,
            SUB_SCHEMA_SUB_ENTRY_DN,
            LDAP_SCOPE_BASE,
            pcszFilter,
            ppszSchemaEntryAttrs,
            FALSE, /* get values      */
            NULL,  /* server controls */
            NULL,  /* client controls */
            NULL,  /* timeout         */
            0,     /* size limit      */
            &pResult);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Note: searching by name should yield just one
    if (ldap_count_entries(pLd, pResult) != 1)
    {
        dwError = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION;
        BAIL_ON_VMDIR_ERROR(dwError);
    }
    pEntry = ldap_first_entry(pLd, pResult);
    *ppEntry = pEntry;
    *ppResult = pResult;

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s,%d failed, error(%d)", __FUNCTION__, __LINE__, dwError );

    if (pResult)
    {
        ldap_msgfree(pResult);
    }
    goto cleanup;
}
Exemplo n.º 16
0
/*
 * If attribute or attrvalues is NULL, just check for the existence of dn.
 * Otherwise, read values for attribute from dn; then set the bit 1<<n in mask
 * for each attrvalues[n] which is present in the values read.
 */
krb5_error_code
checkattributevalue(LDAP *ld, char *dn, char *attribute, char **attrvalues,
                    int *mask)
{
    krb5_error_code ret;
    int one = 1, i, j;
    char **values = NULL, *attributes[2] = { NULL };
    LDAPMessage *result = NULL, *entry;

    if (strlen(dn) == 0)
        return set_ldap_error(0, LDAP_NO_SUCH_OBJECT, OP_SEARCH);

    attributes[0] = attribute;

    /* Read values for attribute from the dn, or check for its existence. */
    ret = ldap_search_ext_s(ld, dn, LDAP_SCOPE_BASE, 0, attributes, 0, NULL,
                            NULL, &timelimit, LDAP_NO_LIMIT, &result);
    if (ret != LDAP_SUCCESS) {
        ldap_msgfree(result);
        return set_ldap_error(0, ret, OP_SEARCH);
    }

    /* Don't touch *mask if we are only checking for existence. */
    if (attribute == NULL || attrvalues == NULL)
        goto done;

    *mask = 0;

    entry = ldap_first_entry(ld, result);
    if (entry == NULL)
        goto done;
    values = ldap_get_values(ld, entry, attribute);
    if (values == NULL)
        goto done;

    /* Set bits in mask for each matching value we read. */
    for (i = 0; attrvalues[i]; i++) {
        for (j = 0; values[j]; j++) {
            if (strcasecmp(attrvalues[i], values[j]) == 0) {
                *mask |= (one << i);
                break;
            }
        }
    }

done:
    ldap_msgfree(result);
    ldap_value_free(values);
    return 0;
}
Exemplo n.º 17
0
static int
ldap_search_ext_s_wrapper(LDAP *ld, char *base, int scope, char *filter,
    char *attrs[], int attrsonly, LDAPControl **serverctrls,
    LDAPControl **clientctrls, struct timeval *timeout, int sizelimit,
    LDAPMessage **res)
{

#ifdef AUTH_LDAP_TEST_API
	return (ldap_search_ext_s(ld, base, scope, filter, attrs,
	    attrsonly, serverctrls, clientctrls, timeout, sizelimit, res));
#else
	return ((*ldap_search_ext_s_p)(ld, base, scope, filter, attrs,
	    attrsonly, serverctrls, clientctrls, timeout, sizelimit, res));
#endif
}
Exemplo n.º 18
0
/*
 * Get the certificate subject base from the IPA configuration.
 *
 * Not considered a show-stopper if this fails for some reason.
 *
 * The caller is responsible for binding/unbinding to LDAP.
 */
static int
get_subject(LDAP *ld, char *ldap_base, const char **subject, int quiet)
{
    char *attrs[] = {"ipaCertificateSubjectBase", NULL};
    char *base = NULL;
    LDAPMessage *entry, *res = NULL;
    struct berval **ncvals;
    int ret, rval = 0;

    ret = asprintf(&base, "cn=ipaconfig,cn=etc,%s", ldap_base);
    if (ret == -1)
    {
        if (!quiet)
            fprintf(stderr, _("Out of memory!\n"));
        rval = 3;
        goto done;
    }

    ret = ldap_search_ext_s(ld, base, LDAP_SCOPE_BASE,
                            "objectclass=*", attrs, 0,
                            NULL, NULL, NULL, 0, &res);

    if (ret != LDAP_SUCCESS) {
        fprintf(stderr,
                _("Search for ipaCertificateSubjectBase failed with error %d"),
                ret);
        rval = 14;
        goto done;
    }

    entry = ldap_first_entry(ld, res);
    ncvals = ldap_get_values_len(ld, entry, attrs[0]);
    if (!ncvals) {
        fprintf(stderr, _("No values for %s"), attrs[0]);
        rval = 14;
        goto done;
    }

    *subject = strdup(ncvals[0]->bv_val);

    ldap_value_free_len(ncvals);

done:
    free(base);
    if (res) ldap_msgfree(res);

    return rval;
}
Exemplo n.º 19
0
static krb5_error_code
LDAP_dn2principal(krb5_context context, HDB * db, const char *dn,
		  krb5_principal * principal)
{
    krb5_error_code ret;
    int rc;
    const char *filter = "(objectClass=krb5Principal)";
    LDAPMessage *res = NULL, *e;
    char *p;

    ret = LDAP_no_size_limit(context, HDB2LDAP(db));
    if (ret)
	goto out;

    rc = ldap_search_ext_s(HDB2LDAP(db), dn, LDAP_SCOPE_SUBTREE,
			   filter, krb5principal_attrs, 0,
			   NULL, NULL, NULL,
			   0, &res);
    if (check_ldap(context, db, rc)) {
	ret = HDB_ERR_NOENTRY;
	krb5_set_error_message(context, ret, "ldap_search_ext_s: "
			       "filter: %s error: %s",
			       filter, ldap_err2string(rc));
	goto out;
    }

    e = ldap_first_entry(HDB2LDAP(db), res);
    if (e == NULL) {
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    ret = LDAP_get_string_value(db, e, "krb5PrincipalName", &p);
    if (ret) {
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    ret = krb5_parse_name(context, p, principal);
    free(p);

  out:
    if (res)
	ldap_msgfree(res);

    return ret;
}
Exemplo n.º 20
0
int cb_ping_farm(cb_backend_instance *cb, cb_outgoing_conn * cnx,time_t end_time) {

	char 			*attrs[]	={"1.1",NULL};
	int 			rc;
    struct timeval          timeout;
	LDAP 			*ld;
	LDAPMessage		*result;
	time_t 			now;
	int 			secure;
	if (cb->max_idle_time <=0)	/* Heart-beat disabled */
		return LDAP_SUCCESS;

	if (cnx && (cnx->status != CB_CONNSTATUS_OK ))	/* Known problem */
		return LDAP_SERVER_DOWN;

	now = current_time();
	if (end_time && ((now <= end_time) || (end_time <0))) return LDAP_SUCCESS;

	secure = cb->pool->secure;
	if (cb->pool->starttls) {
		secure = 2;
	}
	ld=slapi_ldap_init(cb->pool->hostname,cb->pool->port,secure,0); 
	if (NULL == ld) {
		cb_update_failed_conn_cpt( cb );
		return LDAP_SERVER_DOWN;
	}

	timeout.tv_sec=cb->max_test_time;
	timeout.tv_usec=0;
	
	/* NOTE: This will fail if we implement the ability to disable
	   anonymous bind */
 	rc=ldap_search_ext_s(ld ,NULL,LDAP_SCOPE_BASE,"objectclass=*",attrs,1,NULL, 
		NULL, &timeout, 1,&result);
	if ( LDAP_SUCCESS != rc ) {
		slapi_ldap_unbind( ld );
		cb_update_failed_conn_cpt( cb );
		return LDAP_SERVER_DOWN; 
	}
	
	ldap_msgfree(result);
	slapi_ldap_unbind( ld );
	cb_reset_conn_cpt( cb );
	return LDAP_SUCCESS;
}
Exemplo n.º 21
0
/***********************************************************************
 *      ldap_search_stW     (WLDAP32.@)
 *
 * Search a directory tree (synchronous 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.
 *  timeout   [I] Timeout in seconds.
 *  res       [O] Results of the search operation.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  Call ldap_msgfree to free the results.
 */
ULONG CDECL ldap_search_stW( WLDAP32_LDAP *ld, const PWCHAR base, ULONG scope,
    const PWCHAR filter, PWCHAR attrs[], ULONG attrsonly,
    struct l_timeval *timeout, WLDAP32_LDAPMessage **res )
{
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
#ifdef HAVE_LDAP
    char *baseU = NULL, *filterU = NULL, **attrsU = NULL;

    ret = WLDAP32_LDAP_NO_MEMORY;

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

    if (!ld || !res) return WLDAP32_LDAP_PARAM_ERROR;

    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 = map_error( ldap_search_ext_s( ld, baseU, scope, filterU, attrsU, attrsonly,
                                        NULL, NULL, (struct timeval *)timeout, 0, res ));

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

#endif
    return ret;
}
Exemplo n.º 22
0
char *ldap_search(char *searchstring, char returnattribute[]){
	char **value = 0;
	char *attribute = (char *) malloc(32 * sizeof(char));
	LDAPMessage *entry;
	LDAPMessage *res; 
	BerElement *berptr;
	
	ldap_init();
	
	
	if(ldap_search_ext_s(ld,LDAP_BASE,LDAP_SCOPE_ONELEVEL,searchstring,NULL,0,NULL,NULL,NULL,LDAP_NO_LIMIT,&res) != LDAP_SUCCESS) {
		printf("LDAP search faild: %s\n", searchstring);
		return "failed";
	}

	entry = ldap_first_entry(ld,res);
	if(entry == NULL) {	
		printf("Could not find first entry\n");
		return "failed";
	}
	
	for(attribute = ldap_first_attribute(ld,entry,&berptr);strcmp(returnattribute,attribute);attribute = ldap_next_attribute(ld,entry,berptr)) {
		if(!attribute){
			printf("Could not find first attribute for: %s\n",entry);
			return "failed";
		}
	}

	value = ldap_get_values(ld,entry,attribute);
	if(value == NULL) {
		printf("Value returnd NULL\n");
		return "failed";
	}
	
	printf("%s\r\n",value[0]);
	free(attribute);
	return value[0];
}
Exemplo n.º 23
0
/* return 0 IFF op_dn is a value in group_at (member) attribute
 * of entry with gr_dn AND that entry has an objectClass
 * value of group_oc (groupOfNames)
 */
int
ldap_back_group(
	Backend		*be,
	Connection 	*conn,
	Operation 	*op,
	Entry		*target,
	struct berval	*gr_ndn,
	struct berval	*op_ndn,
	ObjectClass	*group_oc,
	AttributeDescription* group_at
)
{
	struct ldapinfo *li = (struct ldapinfo *) be->be_private;    
	int rc = 1;
	Attribute   *attr;

	LDAPMessage	*result;
	char *gattr[2];
	char *filter = NULL, *ptr;
	LDAP *ld;
	struct berval mop_ndn = { 0, NULL }, mgr_ndn = { 0, NULL };

	AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
	struct berval group_oc_name = {0, NULL};
	struct berval group_at_name = group_at->ad_cname;

	if( group_oc->soc_names && group_oc->soc_names[0] ) {
		group_oc_name.bv_val = group_oc->soc_names[0];
	} else {
		group_oc_name.bv_val = group_oc->soc_oid;
	}
	if (group_oc_name.bv_val)
		group_oc_name.bv_len = strlen(group_oc_name.bv_val);

	if (target != NULL && dn_match( &target->e_nname, gr_ndn ) ) {
		/* we already have a copy of the entry */
		/* attribute and objectclass mapping has already been done */

		/*
		 * first we need to check if the objectClass attribute
		 * has been retieved; otherwise we need to repeat the search
		 */
		attr = attr_find( target->e_attrs, ad_objectClass );
		if ( attr != NULL ) {

			/*
			 * Now we can check for the group objectClass value
			 */
			if( !is_entry_objectclass( target, group_oc, 0 ) ) {
				return(1);
			}

			/*
			 * This part has been reworked: the group attr compare
			 * fails only if the attribute is PRESENT but the value
			 * is NOT PRESENT; if the attribute is NOT PRESENT, the
			 * search must be repeated as well.
			 * This may happen if a search for an entry has already
			 * been performed (target is not null) but the group
			 * attribute has not been required
			 */
			if ((attr = attr_find(target->e_attrs, group_at)) != NULL) {
				if( value_find_ex( group_at, SLAP_MR_VALUE_NORMALIZED_MATCH,
					attr->a_vals, op_ndn ) != LDAP_SUCCESS )
					return(1);
				return(0);
			} /* else: repeat the search */
		} /* else: repeat the search */
	} /* else: do the search */

	/*
	 * Rewrite the op ndn if needed
	 */
#ifdef ENABLE_REWRITE
	switch ( rewrite_session( li->rwinfo, "bindDn",
				op_ndn->bv_val, conn, &mop_ndn.bv_val ) ) {
	case REWRITE_REGEXEC_OK:
		if ( mop_ndn.bv_val == NULL ) {
			mop_ndn = *op_ndn;
		}
#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDAP, DETAIL1, 
			"[rw] bindDn (op ndn in group): \"%s\" -> \"%s\"\n", 
			op_ndn->bv_val, mop_ndn.bv_val, 0 );
#else /* !NEW_LOGGING */
		Debug( LDAP_DEBUG_ARGS,
			"rw> bindDn (op ndn in group): \"%s\" -> \"%s\"\n%s",
			op_ndn->bv_val, mop_ndn.bv_val, "" );
#endif /* !NEW_LOGGING */
		break;
	
	case REWRITE_REGEXEC_UNWILLING:
	
	case REWRITE_REGEXEC_ERR:
		goto cleanup;
	}

	/*
	 * Rewrite the gr ndn if needed
	 */
        switch ( rewrite_session( li->rwinfo, "searchBase",
				gr_ndn->bv_val, conn, &mgr_ndn.bv_val ) ) {
	case REWRITE_REGEXEC_OK:
		if ( mgr_ndn.bv_val == NULL ) {
			mgr_ndn = *gr_ndn;
		}
#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDAP, DETAIL1, 
			"[rw] searchBase (gr ndn in group): \"%s\" -> \"%s\"\n%s", 
			gr_ndn->bv_val, mgr_ndn.bv_val, "" );
#else /* !NEW_LOGGING */
		Debug( LDAP_DEBUG_ARGS,
			"rw> searchBase (gr ndn in group):"
			" \"%s\" -> \"%s\"\n%s",
			gr_ndn->bv_val, mgr_ndn.bv_val, "" );
#endif /* !NEW_LOGGING */
		break;
	
	case REWRITE_REGEXEC_UNWILLING:
	
	case REWRITE_REGEXEC_ERR:
		goto cleanup;
	}
#else /* !ENABLE_REWRITE */
	ldap_back_dn_massage( li, op_ndn, &mop_ndn, 1, 1 );
	if ( mop_ndn.bv_val == NULL ) {
		goto cleanup;
	}
	ldap_back_dn_massage( li, gr_ndn, &mgr_ndn, 1, 1 );
	if ( mgr_ndn.bv_val == NULL ) {
		goto cleanup;
	}
#endif /* !ENABLE_REWRITE */

	ldap_back_map(&li->oc_map, &group_oc_name, &group_oc_name,
			BACKLDAP_MAP);
	if (group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0')
		goto cleanup;
	ldap_back_map(&li->at_map, &group_at_name, &group_at_name,
			BACKLDAP_MAP);
	if (group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0')
		goto cleanup;

	filter = ch_malloc(sizeof("(&(objectclass=)(=))")
						+ group_oc_name.bv_len
						+ group_at_name.bv_len
						+ mop_ndn.bv_len + 1);
	if (filter == NULL)
		goto cleanup;

	if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) {
		goto cleanup;
	}

	if (ldap_bind_s(ld, li->binddn, li->bindpw, LDAP_AUTH_SIMPLE)
			!= LDAP_SUCCESS) {
		goto cleanup;
	}

	ptr = lutil_strcopy(filter, "(&(objectclass=");
	ptr = lutil_strcopy(ptr, group_oc_name.bv_val);
	ptr = lutil_strcopy(ptr, ")(");
	ptr = lutil_strcopy(ptr, group_at_name.bv_val);
	ptr = lutil_strcopy(ptr, "=");
	ptr = lutil_strcopy(ptr, mop_ndn.bv_val);
	strcpy(ptr, "))");

	gattr[0] = "objectclass";
	gattr[1] = NULL;
	if (ldap_search_ext_s(ld, mgr_ndn.bv_val, LDAP_SCOPE_BASE, filter,
		gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
		LDAP_NO_LIMIT, &result) == LDAP_SUCCESS) {
		if (ldap_first_entry(ld, result) != NULL)
			rc = 0;
		ldap_msgfree(result);
	}

cleanup:;
	if ( ld != NULL ) {
		ldap_unbind(ld);
	}
	ch_free(filter);
	if ( mop_ndn.bv_val != op_ndn->bv_val ) {
		free( mop_ndn.bv_val );
	}
	if ( mgr_ndn.bv_val != gr_ndn->bv_val ) {
		free( mgr_ndn.bv_val );
	}
	return(rc);
}
Exemplo n.º 24
0
/*
 * sets last_ldap_result and last_ldap_handle
 */
int lds_search(
	char* _lds_name,
	char* _dn,
	int _scope,
	char* _filter,
	char** _attrs,
	struct timeval* _search_timeout,
	int* _ld_result_count,
	int* _ld_error)
{
	struct ld_session* lds;
#ifdef LDAP_PERF
	struct timeval before_search = { 0, 0 }, after_search = { 0, 0 };
#endif

	/*
	 * get ld_handle
	 */
	if (get_connected_ldap_session(_lds_name, &lds) != 0)
	{
		LM_ERR("[%s]: couldn't get ldap session\n", _lds_name);
		return -1;
	}

	/*
	 * free last_ldap_result
	 */
        if (last_ldap_result != NULL) {
                ldap_msgfree(last_ldap_result);
                last_ldap_result = NULL;
        }

	
	LM_DBG(	"[%s]: performing LDAP search: dn [%s],"
		" scope [%d], filter [%s], client_timeout [%d] usecs\n",
		_lds_name,
		_dn,
		_scope,
		_filter,
		(int)(lds->client_search_timeout.tv_sec * 1000000 
			+ lds->client_search_timeout.tv_usec));
	
#ifdef LDAP_PERF
	gettimeofday(&before_search, NULL);
#endif

	/*
	 * perform ldap search
	 */
	*_ld_error = ldap_search_ext_s(
		lds->handle,
		_dn,
		_scope,
		_filter,
		_attrs,
		0,
		NULL,
		NULL,
		&lds->client_search_timeout,
		0,
		&last_ldap_result);

#ifdef LDAP_PERF
	gettimeofday(&after_search, NULL);

	LM_INFO("[%s]: LDAP search took [%d] usecs\n",
		_lds_name,
		(int)((after_search.tv_sec * 1000000 + after_search.tv_usec)
		- (before_search.tv_sec * 1000000 + before_search.tv_usec)));
#endif

	if (*_ld_error != LDAP_SUCCESS)
	{
		if (last_ldap_result != NULL)
		{
			ldap_msgfree(last_ldap_result);
			last_ldap_result = NULL;
		}

		if (LDAP_API_ERROR(*_ld_error))
		{
			ldap_disconnect(_lds_name);
		}
		
		LM_DBG( "[%s]: ldap_search_ext_st failed: %s\n",
			_lds_name,
			ldap_err2string(*_ld_error));
		return -1;
	}

	last_ldap_handle = lds->handle;
	*_ld_result_count = ldap_count_entries(lds->handle, last_ldap_result);
	if (*_ld_result_count < 0)
	{
		LM_DBG("[%s]: ldap_count_entries failed\n", _lds_name);
		return -1;
	}

	return 0;
}
Exemplo n.º 25
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 );
}
Exemplo n.º 26
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;
}
Exemplo n.º 27
0
static GdaLdapClass *
worker_gdaprov_ldap_get_class_info (WorkerLdapClassInfoData *data, GError **error)
{
	GdaLdapClass *retval = NULL;

	/* initialize known classes */
	data->cdata->classes_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
							   NULL,
							   (GDestroyNotify) ldap_class_free);

	LDAPMessage *msg, *entry;
	int res;
	gchar *subschema = NULL;

	char *subschemasubentry[] = {"subschemaSubentry", NULL};
	char *schema_attrs[] = {"objectClasses", NULL};
	
	/* look for subschema */
	if (! gda_ldap_ensure_bound (data->cnc, NULL))
		return NULL;

	gda_ldap_execution_slowdown (data->cnc);
	res = ldap_search_ext_s (data->cdata->handle, "", LDAP_SCOPE_BASE,
				 "(objectclass=*)",
				 subschemasubentry, 0,
				 NULL, NULL, NULL, 0,
				 &msg);
	if (res != LDAP_SUCCESS) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	if ((entry = ldap_first_entry (data->cdata->handle, msg))) {
		char *attr;
		BerElement *ber;
		if ((attr = ldap_first_attribute (data->cdata->handle, entry, &ber))) {
			BerValue **bvals;
			if ((bvals = ldap_get_values_len (data->cdata->handle, entry, attr))) {
				subschema = g_strdup (bvals[0]->bv_val);
				ldap_value_free_len (bvals);
			}
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
	}
	ldap_msgfree (msg);

	if (! subschema) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	/* look for attributeTypes */
	gda_ldap_execution_slowdown (data->cnc);
	res = ldap_search_ext_s (data->cdata->handle, subschema, LDAP_SCOPE_BASE,
				 "(objectclass=*)",
				 schema_attrs, 0,
				 NULL, NULL, NULL, 0,
				 &msg);
	g_free (subschema);
	if (res != LDAP_SUCCESS) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	GHashTable *h_refs;
	h_refs = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_strfreev);
	for (entry = ldap_first_entry (data->cdata->handle, msg);
	     entry;
	     entry = ldap_next_entry (data->cdata->handle, msg)) {
		char *attr;
		BerElement *ber;
		for (attr = ldap_first_attribute (data->cdata->handle, msg, &ber);
		     attr;
		     attr = ldap_next_attribute (data->cdata->handle, msg, ber)) {
			if (strcasecmp(attr, "objectClasses")) {
				ldap_memfree (attr);
				continue;
			}

			BerValue **bvals;
			bvals = ldap_get_values_len (data->cdata->handle, entry, attr);
			if (bvals) {
				gint i;
				for (i = 0; bvals[i]; i++) {
					LDAPObjectClass *oc;
					const char *errp;
					int retcode;
					oc = ldap_str2objectclass (bvals[i]->bv_val, &retcode,
								   &errp,
								   LDAP_SCHEMA_ALLOW_ALL);
					if (oc && oc->oc_oid && oc->oc_names && oc->oc_names[0]) {
						GdaLdapClass *lcl;
						guint k;
						lcl = g_new0 (GdaLdapClass, 1);
						lcl->oid = g_strdup (oc->oc_oid);
//#define CLASS_DEBUG
#ifdef CLASS_DEBUG
						g_print ("FOUND CLASS\n");
#endif
						lcl->names = make_array_from_strv (oc->oc_names,
										   &(lcl->nb_names));
						for (k = 0; lcl->names[k]; k++) {
#ifdef CLASS_DEBUG
							g_print ("  oc_names[%d] = %s\n",
								 k, lcl->names[k]);
#endif
							g_hash_table_insert (data->cdata->classes_hash,
									     lcl->names[k],
									     lcl);
						}
						if (oc->oc_desc) {
#ifdef CLASS_DEBUG
							g_print ("  oc_desc = %s\n", oc->oc_desc);
#endif
							lcl->description = g_strdup (oc->oc_desc);
						}
#ifdef CLASS_DEBUG
						g_print ("  oc_kind = %d\n", oc->oc_kind);
#endif
						switch (oc->oc_kind) {
						case 0:
							lcl->kind = GDA_LDAP_CLASS_KIND_ABSTRACT;
							break;
						case 1:
							lcl->kind = GDA_LDAP_CLASS_KIND_STRUTURAL;
							break;
						case 2:
							lcl->kind = GDA_LDAP_CLASS_KIND_AUXILIARY;
							break;
						default:
							lcl->kind = GDA_LDAP_CLASS_KIND_UNKNOWN;
							break;
						}
						lcl->obsolete = oc->oc_obsolete;
#ifdef CLASS_DEBUG
						g_print ("  oc_obsolete = %d\n", oc->oc_obsolete);

#endif
						gchar **refs;
						refs = make_array_from_strv (oc->oc_sup_oids, NULL);
						if (refs)
							g_hash_table_insert (h_refs, lcl, refs);
						else
							data->cdata->top_classes = g_slist_insert_sorted (data->cdata->top_classes,
									     lcl, (GCompareFunc) classes_sort);
#ifdef CLASS_DEBUG
						for (k = 0; oc->oc_sup_oids && oc->oc_sup_oids[k]; k++)
							g_print ("  oc_sup_oids[0] = %s\n",
								 oc->oc_sup_oids[k]);
#endif

						lcl->req_attributes =
							make_array_from_strv (oc->oc_at_oids_must,
									      &(lcl->nb_req_attributes));
#ifdef CLASS_DEBUG
						for (k = 0; oc->oc_at_oids_must && oc->oc_at_oids_must[k]; k++)
							g_print ("  oc_at_oids_must[0] = %s\n",
								 oc->oc_at_oids_must[k]);
#endif
						lcl->opt_attributes =
							make_array_from_strv (oc->oc_at_oids_may,
									      &(lcl->nb_opt_attributes));
#ifdef CLASS_DEBUG
						for (k = 0; oc->oc_at_oids_may && oc->oc_at_oids_may[k]; k++)
							g_print ("  oc_at_oids_may[0] = %s\n",
								 oc->oc_at_oids_may[k]);
#endif
						  
					}
					if (oc)
						ldap_memfree (oc);
				}
				ldap_value_free_len (bvals);
			}
			  
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
	}
	ldap_msgfree (msg);

	/* create hierarchy */
	g_hash_table_foreach (h_refs, (GHFunc) classes_h_func, data->cdata);
	g_hash_table_destroy (h_refs);

	retval = g_hash_table_lookup (data->cdata->classes_hash, data->classname);
	gda_ldap_may_unbind (data->cnc);
	return retval;
}
Exemplo n.º 28
0
static LdapAttribute *
worker_gda_ldap_get_attr_info (WorkerLdapAttrInfoData *data, GError **error)
{
	LdapAttribute *retval = NULL;

	if (data->cdata->attributes_hash)
		return g_hash_table_lookup (data->cdata->attributes_hash, data->attribute);

	/* initialize known types */
	data->cdata->attributes_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
							NULL,
							(GDestroyNotify) ldap_attribute_free);
	

	if (data->cdata->attributes_cache_file) {
		/* try to load from cache file, which must contain one line per attribute:
		 * <syntax oid>,0|1,<attribute name>
		 */
		gchar *fdata;
		if (g_file_get_contents (data->cdata->attributes_cache_file, &fdata, NULL, NULL)) {
			gchar *start, *ptr;
			gchar **array;
			start = fdata;
			while (1) {
				gboolean done = FALSE;
				for (ptr = start; *ptr && (*ptr != '\n'); ptr++);
				if (*ptr == '\n')
					*ptr = 0;
				else
					done = TRUE;
				
				if (*start && (*start != '#')) {
					array = g_strsplit (start, ",", 3);
					if (array[0] && array[1] && array[2]) {
						LdapAttribute *lat;
						lat = g_new (LdapAttribute, 1);
						lat->name = g_strdup (array[2]);
						lat->type = gda_ldap_get_type_info (array[0]);
						lat->single_value = (*array[1] == '0' ? FALSE : TRUE);
						g_hash_table_insert (data->cdata->attributes_hash,
								     lat->name, lat);
						/*g_print ("CACHE ADDED [%s][%p][%d] for OID %s\n",
						  lat->name, lat->type, lat->single_value,
						  array[0]);*/
					}
					g_strfreev (array);
				}
				if (done)
					break;
				else
					start = ptr+1;
			}
			g_free (fdata);
			return g_hash_table_lookup (data->cdata->attributes_hash, data->attribute);
		}
	}

	GString *string = NULL;
	LDAPMessage *msg, *entry;
	int res;
	gchar *subschema = NULL;

	char *subschemasubentry[] = {"subschemaSubentry", NULL};
	char *schema_attrs[] = {"attributeTypes", NULL};
	
	/* look for subschema */
	if (! gda_ldap_ensure_bound (data->cnc, NULL))
		return NULL;

	gda_ldap_execution_slowdown (data->cnc);
	res = ldap_search_ext_s (data->cdata->handle, "", LDAP_SCOPE_BASE,
				 "(objectclass=*)",
				 subschemasubentry, 0,
				 NULL, NULL, NULL, 0,
				 &msg);
	if (res != LDAP_SUCCESS) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	if ((entry = ldap_first_entry (data->cdata->handle, msg))) {
		char *attr;
		BerElement *ber;
		if ((attr = ldap_first_attribute (data->cdata->handle, entry, &ber))) {
			BerValue **bvals;
			if ((bvals = ldap_get_values_len (data->cdata->handle, entry, attr))) {
				subschema = g_strdup (bvals[0]->bv_val);
				ldap_value_free_len (bvals);
			}
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
	}
	ldap_msgfree (msg);

	if (! subschema) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	/* look for attributeTypes */
	gda_ldap_execution_slowdown (data->cnc);
	res = ldap_search_ext_s (data->cdata->handle, subschema, LDAP_SCOPE_BASE,
				 "(objectclass=*)",
				 schema_attrs, 0,
				 NULL, NULL, NULL, 0,
				 &msg);
	g_free (subschema);
	if (res != LDAP_SUCCESS) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	if (data->cdata->attributes_cache_file)
		string = g_string_new ("# Cache file. This file can safely be removed, in this case\n"
				       "# it will be automatically recreated.\n"
				       "# DO NOT MODIFY\n");
	for (entry = ldap_first_entry (data->cdata->handle, msg);
	     entry;
	     entry = ldap_next_entry (data->cdata->handle, msg)) {
		char *attr;
		BerElement *ber;
		for (attr = ldap_first_attribute (data->cdata->handle, msg, &ber);
		     attr;
		     attr = ldap_next_attribute (data->cdata->handle, msg, ber)) {
			if (strcasecmp(attr, "attributeTypes")) {
				ldap_memfree (attr);
				continue;
			}

			BerValue **bvals;
			bvals = ldap_get_values_len (data->cdata->handle, entry, attr);
			if (bvals) {
				gint i;
				for (i = 0; bvals[i]; i++) {
					LDAPAttributeType *at;
					const char *errp;
					int retcode;
					at = ldap_str2attributetype (bvals[i]->bv_val, &retcode,
								     &errp,
								     LDAP_SCHEMA_ALLOW_ALL);
					if (at && at->at_names && at->at_syntax_oid &&
					    at->at_names[0] && *(at->at_names[0])) {
						LdapAttribute *lat;
						lat = g_new (LdapAttribute, 1);
						lat->name = g_strdup (at->at_names [0]);
						lat->type = gda_ldap_get_type_info (at->at_syntax_oid);
						lat->single_value = (at->at_single_value == 0 ? FALSE : TRUE);
						g_hash_table_insert (data->cdata->attributes_hash,
								     lat->name, lat);
						/*g_print ("ADDED [%s][%p][%d] for OID %s\n",
						  lat->name, lat->type, lat->single_value,
						  at->at_syntax_oid);*/
						if (string)
							g_string_append_printf (string, "%s,%d,%s\n",
										at->at_syntax_oid,
										lat->single_value,
										lat->name);
									  
					}
					if (at)
						ldap_memfree (at);
				}
				ldap_value_free_len (bvals);
			}
			  
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
	}
	ldap_msgfree (msg);

	if (string) {
		if (! g_file_set_contents (data->cdata->attributes_cache_file, string->str, -1, NULL)) {
			gchar *dirname;
			dirname = g_path_get_dirname (data->cdata->attributes_cache_file);
			g_mkdir_with_parents (dirname, 0700);
			g_free (dirname);
			g_file_set_contents (data->cdata->attributes_cache_file, string->str, -1, NULL);
		}
		g_string_free (string, TRUE);
	}

	gda_ldap_may_unbind (data->cnc);
	retval = g_hash_table_lookup (data->cdata->attributes_hash, data->attribute);
	return retval;
}
Exemplo n.º 29
0
static int
do_bind( char *uri, char *dn, struct berval *pass, int maxloop,
	int force, int chaserefs, int noinit, LDAP **ldp,
	int action_type, void *action )
{
	LDAP	*ld = ldp ? *ldp : NULL;
	int  	i, rc = -1;

	/* for internal search */
	int	timelimit = 0;
	int	sizelimit = 0;

	switch ( action_type ) {
	case -1:
		break;

	case TESTER_SEARCH:
		{
		LDAPURLDesc	*ludp = (LDAPURLDesc *)action;

		assert( action != NULL );

		if ( ludp->lud_exts != NULL ) {
			for ( i = 0; ludp->lud_exts[ i ] != NULL; i++ ) {
				char	*ext = ludp->lud_exts[ i ];
				int	crit = 0;

				if (ext[0] == '!') {
					crit++;
					ext++;
				}

				if ( strncasecmp( ext, "x-timelimit=", STRLENOF( "x-timelimit=" ) ) == 0 ) {
					if ( lutil_atoi( &timelimit, &ext[ STRLENOF( "x-timelimit=" ) ] ) && crit ) {
						tester_error( "unable to parse critical extension x-timelimit" );
					}

				} else if ( strncasecmp( ext, "x-sizelimit=", STRLENOF( "x-sizelimit=" ) ) == 0 ) {
					if ( lutil_atoi( &sizelimit, &ext[ STRLENOF( "x-sizelimit=" ) ] ) && crit ) {
						tester_error( "unable to parse critical extension x-sizelimit" );
					}

				} else if ( crit ) {
					tester_error( "unknown critical extension" );
				}
			}
		}
		} break;

	default:
		/* nothing to do yet */
		break;
	}
			
	if ( maxloop > 1 ) {
		fprintf( stderr, "PID=%ld - Bind(%d): dn=\"%s\".\n",
			 (long) pid, maxloop, dn );
	}

	for ( i = 0; i < maxloop; i++ ) {
		if ( !noinit || ld == NULL ) {
			int version = LDAP_VERSION3;
			ldap_initialize( &ld, uri );
			if ( ld == NULL ) {
				tester_perror( "ldap_initialize", NULL );
				rc = -1;
				break;
			}

			(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 ) {
			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_sasl_bind_s", NULL );
				}
				rc = LDAP_SUCCESS;

			} else {
				tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
			}
		}

		switch ( action_type ) {
		case -1:
			break;

		case TESTER_SEARCH:
			{
			LDAPURLDesc	*ludp = (LDAPURLDesc *)action;
			LDAPMessage	*res = NULL;
			struct timeval	tv = { 0 }, *tvp = NULL;

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

			assert( action != NULL );

			rc = ldap_search_ext_s( ld,
				ludp->lud_dn, ludp->lud_scope,
				ludp->lud_filter, ludp->lud_attrs, 0,
				NULL, NULL, tvp, sizelimit, &res );
			ldap_msgfree( res );
			} break;

		default:
			/* nothing to do yet */
			break;
		}
			
		if ( !noinit ) {
			ldap_unbind_ext( ld, NULL, NULL );
			ld = NULL;
		}

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

	if ( maxloop > 1 ) {
		fprintf( stderr, "  PID=%ld - Bind done (%d).\n", (long) pid, rc );
	}

	if ( ldp && noinit ) {
		*ldp = ld;

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

	return rc;
}
Exemplo n.º 30
0
static GdaLdapEntry *
worker_gdaprov_ldap_describe_entry (WorkerLdapDescrEntryData *data, GError **error)
{
	if (! gda_ldap_ensure_bound (data->cnc, error))
		return NULL;

	gda_ldap_execution_slowdown (data->cnc);

	int res;
	LDAPMessage *msg = NULL;
	const gchar *real_dn;
	real_dn = data->dn ? data->dn : data->cdata->base_dn;
 retry:
	res = ldap_search_ext_s (data->cdata->handle, real_dn, LDAP_SCOPE_BASE,
				 "(objectClass=*)", NULL, 0,
				 NULL, NULL, NULL, -1,
				 &msg);
	switch (res) {
	case LDAP_SUCCESS:
	case LDAP_NO_SUCH_OBJECT: {
		gint nb_entries;
		LDAPMessage *ldap_row;
		char *attr;
		BerElement* ber;
		GdaLdapEntry *lentry;
		GArray *array = NULL;

		nb_entries = ldap_count_entries (data->cdata->handle, msg);
		if (nb_entries == 0) {
			ldap_msgfree (msg);
			gda_ldap_may_unbind (data->cnc);
			return NULL;
		}
		else if (nb_entries > 1) {
			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
				     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
				     _("LDAP server returned more than one entry with DN '%s'"),
				     real_dn);
			gda_ldap_may_unbind (data->cnc);
			return NULL;
		}

		lentry = g_new0 (GdaLdapEntry, 1);
		lentry->dn = g_strdup (real_dn);
		lentry->attributes_hash = g_hash_table_new (g_str_hash, g_str_equal);
		array = g_array_new (TRUE, FALSE, sizeof (GdaLdapAttribute*));
		ldap_row = ldap_first_entry (data->cdata->handle, msg);
		for (attr = ldap_first_attribute (data->cdata->handle, ldap_row, &ber);
		     attr;
		     attr = ldap_next_attribute (data->cdata->handle, ldap_row, ber)) {
			BerValue **bvals;
			GArray *varray = NULL;
			bvals = ldap_get_values_len (data->cdata->handle, ldap_row, attr);
			if (bvals) {
				gint i;
				for (i = 0; bvals [i]; i++) {
					if (!varray)
						varray = g_array_new (TRUE, FALSE, sizeof (GValue *));
					GValue *value;
					GType type;
					type = gda_ldap_get_g_type (data->cnc, data->cdata, attr, NULL);
					/*g_print ("Type for attr %s is %s\n", attr, gda_g_type_to_string (type)); */
					value = gda_ldap_attr_value_to_g_value (data->cdata, type, bvals[i]);
					g_array_append_val (varray, value);
				}
				ldap_value_free_len (bvals);
			}
			if (varray) {
				GdaLdapAttribute *lattr = NULL;
				lattr = g_new0 (GdaLdapAttribute, 1);
				lattr->attr_name = g_strdup (attr);
				lattr->values = (GValue**) varray->data;
				lattr->nb_values = varray->len;
				g_array_free (varray, FALSE);

				g_array_append_val (array, lattr);
				g_hash_table_insert (lentry->attributes_hash, lattr->attr_name, lattr);
			}
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
		ldap_msgfree (msg);
		if (array) {
			g_array_sort (array, (GCompareFunc) attr_array_sort_func);
			lentry->attributes = (GdaLdapAttribute**) array->data;
			lentry->nb_attributes = array->len;
			g_array_free (array, FALSE);
		}
		gda_ldap_may_unbind (data->cnc);
		return lentry;
	}
	case LDAP_SERVER_DOWN:
	default: {
		if (res == LDAP_SERVER_DOWN) {
			gint i;
			for (i = 0; i < 5; i++) {
				if (gda_ldap_rebind (data->cnc, NULL))
					goto retry;
				g_usleep (G_USEC_PER_SEC * 2);
			}
		}
		/* error */
		int ldap_errno;
		ldap_get_option (data->cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
		g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
			     "%s", ldap_err2string(ldap_errno));
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}
	}
}