Example #1
0
File: ldap.c Project: 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;
}
Example #2
0
/* Iterate to the next search result in the linked list
 * of messages returned by the LDAP server and convert
 * the field values.
 */
static int search_entry(db_res_t* res, int init)
{
	db_con_t* con;
	struct ld_res* lres;
	struct ld_con* lcon;
	int r;
	lres = DB_GET_PAYLOAD(res);
	/* FIXME */
	con = res->cmd->ctx->con[db_payload_idx];
	lcon = DB_GET_PAYLOAD(con);

	if (init
	    || !lres->current
	    || ldap_msgtype(lres->current) != LDAP_RES_SEARCH_ENTRY
	    /* there is no more value combination result left */
	    || ld_incindex(res->cmd->result)) {

		do {
			if (init) {
				lres->current = ldap_first_message(lcon->con, lres->msg);
				init = 0;
			}
			else
				lres->current = ldap_next_message(lcon->con, lres->current);
			
			while(lres->current) {
				if (ldap_msgtype(lres->current) == LDAP_RES_SEARCH_ENTRY) {
					break;
				}
				lres->current = ldap_next_message(lcon->con, lres->current);
			}
			if (lres->current == NULL) return 1;
			r = ld_ldap2fldinit(res->cmd->result, lcon->con, lres->current);
		} while (r > 0);
		if (r < 0) return -1;
	} else {
		if (ld_ldap2fld(res->cmd->result, lcon->con, lres->current) < 0) return -1;
	}

	res->cur_rec->fld = res->cmd->result;
	return 0;
}
Example #3
0
	void BuildReply(int res, LDAPRequest *req)
	{
		LDAPResult *ldap_result = req->result = new LDAPResult();
		req->result->type = req->type;

		if (res != LDAP_SUCCESS)
		{
			ldap_result->error = ldap_err2string(res);
			return;
		}

		if (req->message == NULL)
		{
			return;
		}

		/* a search result */

		for (LDAPMessage *cur = ldap_first_message(this->con, req->message); cur; cur = ldap_next_message(this->con, cur))
		{
			LDAPAttributes attributes;

			char *dn = ldap_get_dn(this->con, cur);
			if (dn != NULL)
			{
				attributes["dn"].push_back(dn);
				ldap_memfree(dn);
				dn = NULL;
			}

			BerElement *ber = NULL;

			for (char *attr = ldap_first_attribute(this->con, cur, &ber); attr; attr = ldap_next_attribute(this->con, cur, ber))
			{
				berval **vals = ldap_get_values_len(this->con, cur, attr);
				int count = ldap_count_values_len(vals);

				std::vector<Anope::string> attrs;
				for (int j = 0; j < count; ++j)
					attrs.push_back(vals[j]->bv_val);
				attributes[attr] = attrs;

				ldap_value_free_len(vals);
				ldap_memfree(attr);
			}

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

			ldap_result->messages.push_back(attributes);
		}
	}
Example #4
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;
}
Example #5
0
/*
 * poll for new responses
 */
int
ldap_sync_poll( ldap_sync_t *ls )
{
	struct	timeval		tv,
				*tvp = NULL;
	LDAPMessage		*res = NULL,
				*msg;
	int			rc = 0;

#ifdef LDAP_SYNC_TRACE
	fprintf( stderr, "ldap_sync_poll...\n" );
#endif /* LDAP_SYNC_TRACE */

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

	if ( ls->ls_timeout != -1 ) {
		tv.tv_sec = ls->ls_timeout;
		tv.tv_usec = 0;
		tvp = &tv;
	}

	rc = ldap_result( ls->ls_ld, ls->ls_msgid,
		LDAP_MSG_RECEIVED, tvp, &res );
	if ( rc <= 0 ) {
		return rc;
	}

	for ( msg = ldap_first_message( ls->ls_ld, res );
		msg;
		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;
		}
	}

done_search:;
	ldap_msgfree( res );

done:;
	return rc;
}
Example #6
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;
}
Example #7
0
int
asyncmeta_handle_search_msg(LDAPMessage *res, a_metaconn_t *mc, bm_context_t *bc, int candidate)
{
	a_metainfo_t	*mi;
	a_metatarget_t	*mt;
	a_metasingleconn_t *msc;
	Operation *op = bc->op;
	SlapReply *rs;
	int	   i, rc = LDAP_SUCCESS, sres;
	SlapReply *candidates;
	char		**references = NULL;
	LDAPControl	**ctrls = NULL;
	a_dncookie dc;
	LDAPMessage *msg;
	ber_int_t id;

	rs = &bc->rs;
	mi = mc->mc_info;
	mt = mi->mi_targets[ candidate ];
	msc = &mc->mc_conns[ candidate ];
	dc.op = op;
	dc.target = mt;
	dc.to_from = MASSAGE_REP;
	id = ldap_msgid(res);


	candidates = bc->candidates;
	i = candidate;

	while (res && !META_BACK_CONN_INVALID(msc)) {
	for (msg = ldap_first_message(msc->msc_ldr, res); msg; msg = ldap_next_message(msc->msc_ldr, msg)) {
		switch(ldap_msgtype(msg)) {
		case LDAP_RES_SEARCH_ENTRY:
			Debug( LDAP_DEBUG_TRACE,
				"%s asyncmeta_handle_search_msg: msc %p entry\n",
				op->o_log_prefix, msc );
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			/* count entries returned by target */
			candidates[ i ].sr_nentries++;
			if (bc->c_peer_name.bv_val == op->o_conn->c_peer_name.bv_val && !op->o_abandon) {
				rs->sr_err = asyncmeta_send_entry( &bc->copy_op, rs, mc, i, msg );
			} else {
				goto err_cleanup;
			}
			switch ( rs->sr_err ) {
			case LDAP_SIZELIMIT_EXCEEDED:
				asyncmeta_send_ldap_result(bc, op, rs);
				rs->sr_err = LDAP_SUCCESS;
				goto err_cleanup;
			case LDAP_UNAVAILABLE:
				rs->sr_err = LDAP_OTHER;
				break;
			default:
				break;
			}
			bc->is_ok++;
			break;

		case LDAP_RES_SEARCH_REFERENCE:
			if ( META_BACK_TGT_NOREFS( mt ) ) {
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			bc->is_ok++;
			rc = ldap_parse_reference( msc->msc_ldr, msg,
				   &references, &rs->sr_ctrls, 0 );

			if ( rc != LDAP_SUCCESS || references == NULL ) {
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}

			/* FIXME: merge all and return at the end */

			{
				int cnt;
				for ( cnt = 0; references[ cnt ]; cnt++ )
					;

				rs->sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
								 op->o_tmpmemctx );

				for ( cnt = 0; references[ cnt ]; cnt++ ) {
					ber_str2bv_x( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ],
							  op->o_tmpmemctx );
				}
				BER_BVZERO( &rs->sr_ref[ cnt ] );
			}

			{
				dc.memctx = op->o_tmpmemctx;
				( void )asyncmeta_referral_result_rewrite( &dc, rs->sr_ref );
			}

			if ( rs->sr_ref != NULL ) {
				if (!BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) {
					/* ignore return value by now */
					( void )send_search_reference( op, rs );
				}

				ber_bvarray_free_x( rs->sr_ref, op->o_tmpmemctx );
				rs->sr_ref = NULL;
			}

			/* cleanup */
			if ( references ) {
				ber_memvfree( (void **)references );
			}

			if ( rs->sr_ctrls ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}
			break;

		case LDAP_RES_INTERMEDIATE:
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			bc->is_ok++;

			/* FIXME: response controls
			 * are passed without checks */
			rs->sr_err = ldap_parse_intermediate( msc->msc_ldr,
								  msg,
								  (char **)&rs->sr_rspoid,
								  &rs->sr_rspdata,
								  &rs->sr_ctrls,
								  0 );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				candidates[ i ].sr_type = REP_RESULT;
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}

			slap_send_ldap_intermediate( op, rs );

			if ( rs->sr_rspoid != NULL ) {
				ber_memfree( (char *)rs->sr_rspoid );
				rs->sr_rspoid = NULL;
			}

			if ( rs->sr_rspdata != NULL ) {
				ber_bvfree( rs->sr_rspdata );
				rs->sr_rspdata = NULL;
			}

			if ( rs->sr_ctrls != NULL ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}
			break;

		case LDAP_RES_SEARCH_RESULT:
			if ( mi->mi_idle_timeout != 0 ) {
				asyncmeta_set_msc_time(msc);
			}
			Debug( LDAP_DEBUG_TRACE,
			       "%s asyncmeta_handle_search_msg: msc %p result\n",
			       op->o_log_prefix, msc );
			candidates[ i ].sr_type = REP_RESULT;
			candidates[ i ].sr_msgid = META_MSGID_IGNORE;
			/* NOTE: ignores response controls
			 * (and intermediate response controls
			 * as well, except for those with search
			 * references); this may not be correct,
			 * but if they're not ignored then
			 * back-meta would need to merge them
			 * consistently (think of pagedResults...)
			 */
			/* FIXME: response controls? */
			rs->sr_err = ldap_parse_result( msc->msc_ldr,
							msg,
							&candidates[ i ].sr_err,
								(char **)&candidates[ i ].sr_matched,
							(char **)&candidates[ i ].sr_text,
							&references,
							&ctrls /* &candidates[ i ].sr_ctrls (unused) */ ,
							0 );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				candidates[ i ].sr_err = rs->sr_err;
				sres = slap_map_api2result( &candidates[ i ] );
				candidates[ i ].sr_type = REP_RESULT;
				goto finish;
			}

			rs->sr_err = candidates[ i ].sr_err;

			/* massage matchedDN if need be */
			if ( candidates[ i ].sr_matched != NULL ) {
				struct berval	match, mmatch;

				ber_str2bv( candidates[ i ].sr_matched,
						0, 0, &match );
				candidates[ i ].sr_matched = NULL;

				dc.memctx = NULL;
				asyncmeta_dn_massage( &dc, &match, &mmatch );
				if ( mmatch.bv_val == match.bv_val ) {
					candidates[ i ].sr_matched
						= ch_strdup( mmatch.bv_val );

				} else {
					candidates[ i ].sr_matched = mmatch.bv_val;
				}

				bc->candidate_match++;
				ldap_memfree( match.bv_val );
			}

			/* add references to array */
			/* RFC 4511: referrals can only appear
			 * if result code is LDAP_REFERRAL */
			if ( references != NULL
				 && references[ 0 ] != NULL
				 && references[ 0 ][ 0 ] != '\0' )
			{
				if ( rs->sr_err != LDAP_REFERRAL ) {
					Debug( LDAP_DEBUG_ANY,
						   "%s asncmeta_search_result[%d]: "
						   "got referrals with err=%d\n",
						   op->o_log_prefix,
						   i, rs->sr_err );

				} else {
					BerVarray	sr_ref;
					int		cnt;

					for ( cnt = 0; references[ cnt ]; cnt++ )
						;

					sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
								 op->o_tmpmemctx );

					for ( cnt = 0; references[ cnt ]; cnt++ ) {
						ber_str2bv_x( references[ cnt ], 0, 1, &sr_ref[ cnt ],
								  op->o_tmpmemctx );
					}
					BER_BVZERO( &sr_ref[ cnt ] );

					dc.memctx = op->o_tmpmemctx;
					( void )asyncmeta_referral_result_rewrite( &dc, sr_ref );

					if ( rs->sr_v2ref == NULL ) {
						rs->sr_v2ref = sr_ref;

					} else {
						for ( cnt = 0; !BER_BVISNULL( &sr_ref[ cnt ] ); cnt++ ) {
							ber_bvarray_add_x( &rs->sr_v2ref, &sr_ref[ cnt ],
									   op->o_tmpmemctx );
						}
						ber_memfree_x( sr_ref, op->o_tmpmemctx );
					}
				}

			} else if ( rs->sr_err == LDAP_REFERRAL ) {
				Debug( LDAP_DEBUG_TRACE,
					   "%s asyncmeta_search_result[%d]: "
					   "got err=%d with null "
					   "or empty referrals\n",
					   op->o_log_prefix,
					   i, rs->sr_err );

				rs->sr_err = LDAP_NO_SUCH_OBJECT;
			}

			/* cleanup */
			ber_memvfree( (void **)references );

			sres = slap_map_api2result( rs );

			if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
				Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_search_result[%d] "
				       "match=\"%s\" err=%ld",
				       op->o_log_prefix, i,
				       candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
				       (long) candidates[ i ].sr_err );
			} else {
					Debug( LDAP_DEBUG_ANY,  "%s asyncmeta_search_result[%d] "
				       "match=\"%s\" err=%ld (%s)",
				       op->o_log_prefix, i,
				       candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
					       (long) candidates[ i ].sr_err, ldap_err2string( candidates[ i ].sr_err ) );
			}

			switch ( sres ) {
			case LDAP_NO_SUCH_OBJECT:
				/* is_ok is touched any time a valid
				 * (even intermediate) result is
				 * returned; as a consequence, if
				 * a candidate returns noSuchObject
				 * it is ignored and the candidate
				 * is simply demoted. */
				if ( bc->is_ok ) {
					sres = LDAP_SUCCESS;
				}
				break;

			case LDAP_SUCCESS:
				if ( ctrls != NULL && ctrls[0] != NULL ) {
#ifdef SLAPD_META_CLIENT_PR
					LDAPControl *pr_c;

					pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
					if ( pr_c != NULL ) {
						BerElementBuffer berbuf;
						BerElement *ber = (BerElement *)&berbuf;
						ber_tag_t tag;
						ber_int_t prsize;
						struct berval prcookie;

						/* unsolicited, do not accept */
						if ( mt->mt_ps == 0 ) {
							rs->sr_err = LDAP_OTHER;
							goto err_pr;
						}

						ber_init2( ber, &pr_c->ldctl_value, LBER_USE_DER );

						tag = ber_scanf( ber, "{im}", &prsize, &prcookie );
						if ( tag == LBER_ERROR ) {
							rs->sr_err = LDAP_OTHER;
							goto err_pr;
						}

						/* more pages? new search request */
						if ( !BER_BVISNULL( &prcookie ) && !BER_BVISEMPTY( &prcookie ) ) {
							if ( mt->mt_ps > 0 ) {
								/* ignore size if specified */
								prsize = 0;

							} else if ( prsize == 0 ) {
								/* guess the page size from the entries returned so far */
								prsize = candidates[ i ].sr_nentries;
							}

							candidates[ i ].sr_nentries = 0;
							candidates[ i ].sr_msgid = META_MSGID_IGNORE;
							candidates[ i ].sr_type = REP_INTERMEDIATE;

							assert( candidates[ i ].sr_matched == NULL );
							assert( candidates[ i ].sr_text == NULL );
							assert( candidates[ i ].sr_ref == NULL );

							switch ( asyncmeta_back_search_start( &bc->copy_op, rs, mc, bc, i, &prcookie, prsize, 1 ) )
							{
							case META_SEARCH_CANDIDATE:
								assert( candidates[ i ].sr_msgid >= 0 );
								ldap_controls_free( ctrls );
								//	goto free_message;

							case META_SEARCH_ERR:
							case META_SEARCH_NEED_BIND:
err_pr:;
								candidates[ i ].sr_err = rs->sr_err;
								candidates[ i ].sr_type = REP_RESULT;
								if ( META_BACK_ONERR_STOP( mi ) ) {
									asyncmeta_send_ldap_result(bc, op, rs);
									ldap_controls_free( ctrls );
									goto err_cleanup;
								}
								/* fallthru */

							case META_SEARCH_NOT_CANDIDATE:
								/* means that asyncmeta_back_search_start()
								 * failed but onerr == continue */
								candidates[ i ].sr_msgid = META_MSGID_IGNORE;
								candidates[ i ].sr_type = REP_RESULT;
								break;

							default:
								/* impossible */
								assert( 0 );
								break;
							}
							break;
						}
					}
#endif /* SLAPD_META_CLIENT_PR */

					ldap_controls_free( ctrls );
				}
				/* fallthru */

			case LDAP_REFERRAL:
				bc->is_ok++;
				break;

			case LDAP_SIZELIMIT_EXCEEDED:
				/* if a target returned sizelimitExceeded
				 * and the entry count is equal to the
				 * proxy's limit, the target would have
				 * returned more, and the error must be
				 * propagated to the client; otherwise,
				 * the target enforced a limit lower
				 * than what requested by the proxy;
				 * ignore it */
				candidates[ i ].sr_err = rs->sr_err;
				if ( rs->sr_nentries == op->ors_slimit
					 || META_BACK_ONERR_STOP( mi ) )
				{
					const char *save_text;
got_err:
					save_text = rs->sr_text;
					rs->sr_text = candidates[ i ].sr_text;
					asyncmeta_send_ldap_result(bc, op, rs);
					if (candidates[ i ].sr_text != NULL) {
						ch_free( (char *)candidates[ i ].sr_text );
						candidates[ i ].sr_text = NULL;
					}
					rs->sr_text = save_text;
					ldap_controls_free( ctrls );
					goto err_cleanup;
				}
				break;

			default:
				candidates[ i ].sr_err = rs->sr_err;
				if ( META_BACK_ONERR_STOP( mi ) ) {
					goto got_err;
				}
				break;
			}
			/* if this is the last result we will ever receive, send it back  */
			rc = rs->sr_err;
			if (asyncmeta_is_last_result(mc, bc, i) == 0) {
				Debug( LDAP_DEBUG_TRACE,
					"%s asyncmeta_handle_search_msg: msc %p last result\n",
					op->o_log_prefix, msc );
				asyncmeta_search_last_result(mc, bc, i, sres);
err_cleanup:
				rc = rs->sr_err;
				ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
				asyncmeta_drop_bc( mc, bc);
				asyncmeta_clear_bm_context(bc);
				ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );
				ldap_msgfree(res);
				return rc;
			}
finish:
			break;

		default:
			continue;
		}
	}
		ldap_msgfree(res);
		res = NULL;
		if (candidates[ i ].sr_type != REP_RESULT) {
			struct timeval	tv = {0};
			rc = ldap_result( msc->msc_ldr, id, LDAP_MSG_RECEIVED, &tv, &res );
			if (res != NULL) {
				msc->msc_result_time = slap_get_time();
			}
		}
	}
	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
	bc->bc_active--;
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );

	return rc;
}
Example #8
0
static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
                         size_t len, CURLcode *err)
{
  ldapconninfo *li = conn->proto.generic;
  struct SessionHandle *data = conn->data;
  ldapreqinfo *lr = data->req.protop;
  int rc, ret;
  LDAPMessage *msg = NULL;
  LDAPMessage *ent;
  BerElement *ber = NULL;
  struct timeval tv = {0, 1};

  (void)len;
  (void)buf;
  (void)sockindex;

  rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
  if(rc < 0) {
    failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
    *err = CURLE_RECV_ERROR;
    return -1;
  }

  *err = CURLE_AGAIN;
  ret = -1;

  /* timed out */
  if(!msg)
    return ret;

  for(ent = ldap_first_message(li->ld, msg); ent;
    ent = ldap_next_message(li->ld, ent)) {
    struct berval bv, *bvals, **bvp = &bvals;
    int binary = 0, msgtype;

    msgtype = ldap_msgtype(ent);
    if(msgtype == LDAP_RES_SEARCH_RESULT) {
      int code;
      char *info = NULL;
      rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
      if(rc) {
        failf(data, "LDAP local: search ldap_parse_result %s",
              ldap_err2string(rc));
        *err = CURLE_LDAP_SEARCH_FAILED;
      }
      else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
        failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
              info ? info : "");
        *err = CURLE_LDAP_SEARCH_FAILED;
      }
      else {
        /* successful */
        if(code == LDAP_SIZELIMIT_EXCEEDED)
          infof(data, "There are more than %d entries\n", lr->nument);
        data->req.size = data->req.bytecount;
        *err = CURLE_OK;
        ret = 0;
      }
      lr->msgid = 0;
      ldap_memfree(info);
      break;
    }
    else if(msgtype != LDAP_RES_SEARCH_ENTRY)
      continue;

    lr->nument++;
    rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
    if(rc < 0) {
      /* TODO: verify that this is really how this return code should be
         handled */
      *err = CURLE_RECV_ERROR;
      return -1;
    }
    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
    if(*err)
      return -1;

    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
                             bv.bv_len);
    if(*err)
      return -1;

    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
    if(*err)
      return -1;
    data->req.bytecount += bv.bv_len + 5;

    for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
      rc == LDAP_SUCCESS;
      rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
      int i;

      if(bv.bv_val == NULL) break;

      if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
        binary = 1;
      else
        binary = 0;

      for(i=0; bvals[i].bv_val != NULL; i++) {
        int binval = 0;
        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
        if(*err)
          return -1;

        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
                                 bv.bv_len);
        if(*err)
          return -1;

        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
        if(*err)
          return -1;
        data->req.bytecount += bv.bv_len + 2;

        if(!binary) {
          /* check for leading or trailing whitespace */
          if(ISSPACE(bvals[i].bv_val[0]) ||
              ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
            binval = 1;
          else {
            /* check for unprintable characters */
            unsigned int j;
            for(j=0; j<bvals[i].bv_len; j++)
              if(!ISPRINT(bvals[i].bv_val[j])) {
                binval = 1;
                break;
              }
          }
        }
        if(binary || binval) {
          char *val_b64 = NULL;
          size_t val_b64_sz = 0;
          /* Binary value, encode to base64. */
          CURLcode error = Curl_base64_encode(data,
                                              bvals[i].bv_val,
                                              bvals[i].bv_len,
                                              &val_b64,
                                              &val_b64_sz);
          if(error) {
            ber_memfree(bvals);
            ber_free(ber, 0);
            ldap_msgfree(msg);
            *err = error;
            return -1;
          }
          *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
          if(*err)
            return -1;

          data->req.bytecount += 2;
          if(val_b64_sz > 0) {
            *err = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
                                     val_b64_sz);
            if(*err)
              return -1;
            free(val_b64);
            data->req.bytecount += val_b64_sz;
          }
        }
        else {
          *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
          if(*err)
            return -1;

          *err = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
                                   bvals[i].bv_len);
          if(*err)
            return -1;

          data->req.bytecount += bvals[i].bv_len + 1;
        }
        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
        if(*err)
          return -1;

        data->req.bytecount++;
      }
      ber_memfree(bvals);
      *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
      if(*err)
        return -1;
      data->req.bytecount++;
    }
    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
    if(*err)
      return -1;
    data->req.bytecount++;
    ber_free(ber, 0);
  }
  ldap_msgfree(msg);
  return ret;
}
Example #9
0
/** Parse response from LDAP server dealing with any errors
 *
 * Should be called after an LDAP operation. Will check result of operation and if
 * it was successful, then attempt to retrieve and parse the result.  Will also produce
 * extended error output including any messages the server sent, and information about
 * partial DN matches.
 *
 * @note Error messages should be retrieved with fr_strerror() and fr_strerror_pop()
 *
 * @param[out] result	Where to write result, if NULL result will be freed.  If not NULL caller
 *			must free with ldap_msgfree().
 * @param[out] ctrls	Server ctrls returned to the client.  May be NULL if not required.
 *			Must be freed with ldap_free_ctrls.
 * @param[in] conn	Current connection.
 * @param[in] msgid	returned from last operation.
 *			Special values are:
 *			- LDAP_RES_ANY - Retrieve any received messages useful for multiplexing.
 * 			- LDAP_RES_UNSOLICITED - Any unsolicited message.
 * @param[in] all	How many messages to retrieve:
 *			- LDAP_MSG_ONE - Retrieve the first message matching msgid (waiting if one is not available).
 *			- LDAP_MSG_ALL - Retrieve all received messages matching msgid (waiting if none are available).
 *			- LDAP_MSG_RECEIVED - Retrieve all received messages.
 * @param[in] dn	Last search or bind DN.  May be NULL.
 * @param[in] timeout	Override the default result timeout.
 *
 * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values.
 */
fr_ldap_rcode_t fr_ldap_result(LDAPMessage **result, LDAPControl ***ctrls,
			       fr_ldap_connection_t const *conn, int msgid, int all,
			       char const *dn,
			       struct timeval const *timeout)
{
	fr_ldap_rcode_t	status = LDAP_PROC_SUCCESS;
	int		lib_errno;

	struct timeval	tv;			/* Holds timeout values */

	LDAPMessage	*tmp_msg = NULL, *msg;	/* Temporary message pointer storage if we weren't provided with one */
	LDAPMessage	**result_p = result;

	if (result) *result = NULL;
	if (ctrls) *ctrls = NULL;

	/*
	 *	We always need the result, but our caller may not
	 */
	if (!result) result_p = &tmp_msg;

	/*
	 *	Check if there was an error sending the request
	 */
	ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &lib_errno);
	if (lib_errno != LDAP_SUCCESS) return fr_ldap_error_check(NULL, conn, NULL, dn);

	if (!timeout) {
		tv = conn->config->res_timeout;
	} else {
		tv = *timeout;
	}

	/*
	 *	Now retrieve the result and check for errors
	 *	ldap_result returns -1 on failure, and 0 on timeout
	 */
	lib_errno = ldap_result(conn->handle, msgid, all, &tv, result_p);
	switch (lib_errno) {
	case 0:
		lib_errno = LDAP_TIMEOUT;
		fr_strerror_printf("timeout waiting for result");
		return LDAP_PROC_TIMEOUT;

	case -1:
		return fr_ldap_error_check(NULL, conn, NULL, dn);

	default:
		break;
	}

	for (msg = ldap_first_message(conn->handle, *result_p);
	     msg;
	     msg = ldap_next_message(conn->handle, msg)) {
		status = fr_ldap_error_check(ctrls, conn, msg, dn);
		if (status != LDAP_PROC_SUCCESS) break;
	}

	if (*result_p && ((status < 0) || !result)) {
		ldap_msgfree(*result_p);
		*result_p = NULL;
	}

	return status;
}
Example #10
0
void
OPENLDAP::Book::refresh_result ()
{
  int result = LDAP_SUCCESS;
  int nbr = 0;
  struct timeval timeout = { 1, 0}; /* block 1s */
  LDAPMessage *msg_entry = NULL;
  LDAPMessage *msg_result = NULL;
  gchar* c_status = NULL;

  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_result, this),
				   12);
    } else if (patience == 2) {

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

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

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

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

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

    return;
  }

  msg_result = ldap_first_message (ldap_context, msg_entry);
  do {

    if (ldap_msgtype (msg_result) == LDAP_RES_SEARCH_ENTRY) {

      ContactPtr contact = parse_result (msg_result);
      if (contact) {
	add_contact (contact);
        nbr++;
      }
    }
    msg_result = ldap_next_message (ldap_context, msg_result);
  } while (msg_result != NULL);

  // Do not count ekiga.net's first entry "Search Results ... 100 entries"
  if (bookinfo.uri_host == EKIGA_NET_URI)
    nbr--;
  c_status = g_strdup_printf (ngettext ("%d user found",
					"%d users found", nbr), nbr);
  status = c_status;
  g_free (c_status);

  updated (this->shared_from_this ());

  (void)ldap_msgfree (msg_entry);

  ldap_unbind_ext (ldap_context, NULL, NULL);
  ldap_context = NULL;
}
Example #11
0
static bool_t linphone_ldap_contact_provider_iterate(void *data)
{
	LinphoneLDAPContactProvider* obj = LINPHONE_LDAP_CONTACT_PROVIDER(data);
	if( obj->ld && obj->connected && (obj->req_count > 0) ){

		// never block
		struct timeval timeout = {0,0};
		LDAPMessage* results = NULL;

		int ret = ldap_result(obj->ld, LDAP_RES_ANY, LDAP_MSG_ONE, &timeout, &results);

		switch( ret ){
		case -1:
		{
			ms_warning("Error in ldap_result : returned -1 (req_count %d): %s", obj->req_count, ldap_err2string(errno));
			break;
		}
		case 0: break; // nothing to do

		case LDAP_RES_BIND:
		{
			ms_error("iterate: unexpected LDAP_RES_BIND");
			break;
		}
		case LDAP_RES_EXTENDED:
		case LDAP_RES_SEARCH_ENTRY:
		case LDAP_RES_SEARCH_REFERENCE:
		case LDAP_RES_INTERMEDIATE:
		case LDAP_RES_SEARCH_RESULT:
		{
			LDAPMessage* message = ldap_first_message(obj->ld, results);
			LinphoneLDAPContactSearch* req = linphone_ldap_contact_provider_request_search(obj, ldap_msgid(message));
			while( message != NULL ){
				linphone_ldap_contact_provider_handle_search_result(obj, req, message );
				message = ldap_next_message(obj->ld, message);
			}
			if( req && ret == LDAP_RES_SEARCH_RESULT)
				linphone_ldap_contact_provider_cancel_search(
							LINPHONE_CONTACT_PROVIDER(obj),
							LINPHONE_CONTACT_SEARCH(req));
			break;
		}
		case LDAP_RES_MODIFY:
		case LDAP_RES_ADD:
		case LDAP_RES_DELETE:
		case LDAP_RES_MODDN:
		case LDAP_RES_COMPARE:
		default:
			ms_message("Unhandled LDAP result %x", ret);
			break;
		}

		if( results )
			ldap_msgfree(results);
	}

	if( obj->ld && obj->connected ){
		// check for pending searches
		unsigned int i;

		for( i=0; i<obj->req_count; i++){
			LinphoneLDAPContactSearch* search = (LinphoneLDAPContactSearch*)ms_list_nth_data( obj->requests, i );
			if( search && search->msgid == 0){
				int ret;
				ms_message("Found pending search %p (for %s), launching...", search, search->filter);
				ret = linphone_ldap_contact_provider_perform_search(obj, search);
				if( ret != LDAP_SUCCESS ){
					linphone_ldap_contact_provider_cancel_search(
								LINPHONE_CONTACT_PROVIDER(obj),
								LINPHONE_CONTACT_SEARCH(search));
				}
			}
		}
	}

	return TRUE;
}
Example #12
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;
}
static int
check_auth(LD_session *session, char *login, char *password, char *fullname) {
	int rc = 0, count = 0;
	char username[MAXFILTERSTR];
	char logbuf[MAXLOGBUF];
	LDAPMessage *res, *entry;
	char *attr;
	BerElement * ber;
        struct berval **list_of_values;
        struct berval value;
	char *userdn, *validgroups, *fn;
	char filter[MAXFILTERSTR];

	/* Check authorization */
	memset(filter, 0, 100);
	snprintf(filter, MAXLOGBUF, "(&(objectClass=posixGroup)(memberUid=%s))", login);

	struct berval cred;
	struct berval *msgidp=NULL;
	cred.bv_val = password;
	cred.bv_len = strlen(password);

#if LDAP_API_VERSION > 3000
	if((rc = ldap_sasl_bind_s(session->sess, fullname, ldap_authorization_type, &cred, NULL, NULL, NULL))!=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, fullname, password, 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

	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_TRUE;
	}
	
	for (entry = ldap_first_entry(session->sess,res); entry!=NULL && count<ldap_count_messages(session->sess, res); entry=ldap_next_entry(session->sess, res)) {
		count++;
		for(attr = ldap_first_attribute(session->sess,entry,&ber); attr != NULL ; attr=ldap_next_attribute(session->sess,entry,ber)) {
			snprintf(logbuf, MAXLOGBUF, "Found attribute %s", attr); 	
			ldap_log(LOG_DEBUG, logbuf); 
			if (strcmp(attr, "cn"))
				continue;
			if ((list_of_values = ldap_get_values_len(session->sess, entry, attr)) != NULL ) {
				value = *list_of_values[0];
				char temp[MAXGROUPLIST];
				memset(temp, 0, MAXGROUPLIST);
				if (ldap_authorization_validgroups) {
				    strcpy(temp, ldap_authorization_validgroups);
				    validgroups = strtok(temp, ",");
				    while (validgroups != NULL)
				    {
					snprintf(logbuf, MAXLOGBUF, "Attribute value validgroups ? value.bv_val >> %s ? %s", validgroups, value.bv_val); 	
					ldap_log(LOG_DEBUG, logbuf); 
					if (!strcmp(validgroups, value.bv_val))
					{
					    ldap_msgfree(res);
#if LDAP_API_VERSION > 3000
					    ldap_unbind_ext(session->sess, NULL, NULL);
#else	
					    ldap_unbind(session->sess);
#endif
					    fn = (char *)malloc(strlen(value.bv_val));
					    strcpy(fn, value.bv_val);
					    return RETURN_TRUE;
					}
					validgroups = strtok (NULL, ",");
				    }
				    printf("VAL: %s\n", value.bv_val);
				    ldap_value_free_len( list_of_values );
				}
			}
		}
		res = ldap_next_message(session->sess, res);
	};
	ldap_msgfree(res);
#if LDAP_API_VERSION > 3000
	ldap_unbind_ext(session->sess, NULL, NULL);
#else	
	ldap_unbind(session->sess);
#endif
	return RETURN_FALSE;
}
Example #14
0
static int l_search_do_filter(struct ldapsearch *s,
			      int (*callback_func)(const char *utf8_name,
						   const char *address,
						   void *callback_arg),
			      void *callback_arg,
			      const char *filter,
			      const char *lookup_key,
			      int *found)
{
	char *kk;
	struct timeval tv;
	LDAPMessage *result;
	char *attrs[3];
	int rc_code=0;
	int msgidp;

	*found=0;

	kk=make_search_key(filter, lookup_key);

	if (!kk)
		return -1;

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


	attrs[0]="cn";
	attrs[1]="mail";
	attrs[2]=NULL;

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

	if (ldap_search_ext(s->handle, s->base, LDAP_SCOPE_SUBTREE,
			    kk, attrs, 0, NULL, NULL, &tv, 1000000, &msgidp)
	    != LDAP_SUCCESS)
		return -1;

	do
	{
		int rc;
		LDAPMessage *msg;

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

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

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

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

			ldap_unbind_ext(s->handle, NULL, NULL);
			s->handle=NULL;
			rc_code= -1;
			break;
		}

		if (rc == LDAP_RES_SEARCH_RESULT)
		{
			ldap_msgfree(result);
			break; /* End of search */
		}

		if (rc != LDAP_RES_SEARCH_ENTRY)
		{
			ldap_msgfree(result);
			continue;
		}

		for (msg=ldap_first_message(s->handle, result); msg;
		     msg=ldap_next_message(s->handle, msg))
		{
			struct berval **n_val=
				ldap_get_values_len(s->handle, msg, "cn");
			struct berval **a_val=
				ldap_get_values_len(s->handle, msg, "mail");

			if (n_val && a_val)
			{
				size_t i, j;

				for (i=0; n_val[i]; i++)
					for (j=0; a_val[j]; j++)
					{
						char *p=malloc(n_val[i]->bv_len
							       +1);
						char *q=malloc(a_val[j]->bv_len
							       +1);

						if (!p || !q)
						{
							if (p) free(p);
							if (q) free(q);
							rc_code= -1;
							break;
						}

						memcpy(p, n_val[i]->bv_val,
						       n_val[i]->bv_len);
						p[n_val[i]->bv_len]=0;

						memcpy(q, a_val[j]->bv_val,
						       a_val[j]->bv_len);
						q[a_val[j]->bv_len]=0;

						rc_code=(*callback_func)
							(p, q, callback_arg);
						free(p);
						free(q);
						if (rc_code)
							break;
						*found=1;
					}
			}
			if (n_val)
				ldap_value_free_len(n_val);
			if (a_val)
				ldap_value_free_len(a_val);
		}

		ldap_msgfree(result);
	} while (rc_code == 0);
	return rc_code;
}
Example #15
0
static void *
my_task( void *my_num )
{
	LDAP	*ld = NULL, *sld = NULL;
	ber_int_t msgid;
	LDAPMessage *res, *msg;
	char *attrs[] = { "1.1", NULL };
	int     rc = LDAP_SUCCESS;
	int		tid = *(int *)my_num;

	ldap_initialize( &ld, uri );
	if ( ld == NULL ) {
		perror( "ldap_initialize" );
		return NULL;
	}

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

	ldap_initialize( &sld, uri );
	if ( sld == NULL ) {
		perror( "ldap_initialize" );
		return NULL;
	}

	{
		int version = LDAP_VERSION3;
		(void) ldap_set_option( sld, LDAP_OPT_PROTOCOL_VERSION,
			&version ); 
	}
	(void) ldap_set_option( sld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
	if ( binder ) {
		rc = ldap_bind_s( sld, binder, pass, LDAP_AUTH_SIMPLE );
		if ( rc != LDAP_SUCCESS ) {
			ldap_perror( sld, "ldap_bind" );
		}
	}

	r1binds[tid] = 0;

	for (;;) {
		char dn[BUFSIZ], *ptr, fstr[256];
		int j, isr1;
		
		if ( finish )
			break;

		j = rand() % 100;
		if ( j < r1per ) {
			j = rand() % r1hi;
			isr1 = 1;
		} else {
			j = rand() % (r2hi - r2lo + 1 );
			j += r2lo;
			isr1 = 0;
		}
		sprintf(fstr, filter, j);

		rc = ldap_search_ext( sld, base, LDAP_SCOPE_SUB,
			fstr, attrs, 0, NULL, NULL, 0, 0, &msgid );
		if ( rc != LDAP_SUCCESS ) {
			ldap_perror( sld, "ldap_search_ex" );
			return NULL;
		}

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

			for (msg = ldap_first_message( sld, res ); msg;
				msg = ldap_next_message( sld, msg )) {
				switch ( ldap_msgtype( msg )) {
				case LDAP_RES_SEARCH_ENTRY:
					rc = ldap_get_dn_ber( sld, msg, &ber, &bv );
					strcpy(dn, bv.bv_val );
					ber_free( ber, 0 );
					break;
				case LDAP_RES_SEARCH_RESULT:
					done = 1;
					break;
				}
				if ( done )
					break;
			}
			ldap_msgfree( res );
			if ( done ) break;
		}

		rc = ldap_bind_s( ld, dn, pass, LDAP_AUTH_SIMPLE );
		if ( rc != LDAP_SUCCESS ) {
			ldap_perror( ld, "ldap_bind" );
		}
		if ( isr1 )
			r1binds[tid]++;
		else
			r2binds[tid]++;
	}

	ldap_unbind( sld );
	ldap_unbind( ld );

	return NULL;
}