Beispiel #1
0
/*
 * ldap_search - initiate an ldap search operation.
 *
 * Parameters:
 *
 *	ld		LDAP descriptor
 *	base		DN of the base object
 *	scope		the search scope - one of LDAP_SCOPE_BASE,
 *			    LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE
 *	filter		a string containing the search filter
 *			(e.g., "(|(cn=bob)(sn=bob))")
 *	attrs		list of attribute types to return for matches
 *	attrsonly	1 => attributes only 0 => attributes and values
 *
 * Example:
 *	char	*attrs[] = { "mail", "title", 0 };
 *	msgid = ldap_search( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE, "cn~=bob",
 *	    attrs, attrsonly );
 */
int
ldap_search(
	LDAP *ld, LDAP_CONST char *base, int scope, LDAP_CONST char *filter,
	char **attrs, int attrsonly )
{
	BerElement	*ber;

#ifdef NEW_LOGGING
	LDAP_LOG ( OPERATION, ENTRY, "ldap_search\n", 0, 0, 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "ldap_search\n", 0, 0, 0 );
#endif

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );

	ber = ldap_build_search_req( ld, base, scope, filter, attrs,
	    attrsonly, NULL, NULL, -1, -1 ); 

	if ( ber == NULL ) {
		return( -1 );
	}


	/* send the message */
	return ( ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber ));
}
Beispiel #2
0
/*
 * ldap_modify_ext - initiate an ldap extended modify operation.
 *
 * Parameters:
 *
 *	ld		LDAP descriptor
 *	dn		DN of the object to modify
 *	mods		List of modifications to make.  This is null-terminated
 *			array of struct ldapmod's, specifying the modifications
 *			to perform.
 *	sctrls	Server Controls
 *	cctrls	Client Controls
 *	msgidp	Message ID pointer
 *
 * Example:
 *	LDAPMod	*mods[] = {
 *			{ LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
 *			{ LDAP_MOD_REPLACE, "sn", { "babs jensen", "babs", 0 } },
 *			{ LDAP_MOD_DELETE, "ou", 0 },
 *			{ LDAP_MOD_INCREMENT, "uidNumber, { "1", 0 } }
 *			0
 *		}
 *	rc=  ldap_modify_ext( ld, dn, mods, sctrls, cctrls, &msgid );
 */
int
ldap_modify_ext( LDAP *ld,
	LDAP_CONST char *dn,
	LDAPMod **mods,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int *msgidp )
{
	BerElement	*ber;
	int		i, rc;
	ber_int_t	id;

	Debug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	ber = ldap_build_modify_req( ld, dn, mods, sctrls, cctrls, &id );
	if( !ber )
		return ld->ld_errno;

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber, id );
	return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
Beispiel #3
0
/*
 * ldap_compare_ext - perform an ldap extended compare operation.  The dn
 * of the entry to compare to and the attribute and value to compare (in
 * attr and value) are supplied.  The msgid of the response is returned.
 *
 * Example:
 *	struct berval bvalue = { "secret", sizeof("secret")-1 };
 *	rc = ldap_compare( ld, "c=us@cn=bob",
 *		"userPassword", &bvalue,
 *		sctrl, cctrl, &msgid )
 */
int
ldap_compare_ext(
	LDAP *ld,
	LDAP_CONST char *dn,
	LDAP_CONST char *attr,
	struct berval *bvalue,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int	*msgidp )
{
	int rc;
	BerElement	*ber;
	ber_int_t	id;

	Debug( LDAP_DEBUG_TRACE, "ldap_compare\n", 0, 0, 0 );

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( dn != NULL );
	assert( attr != NULL );
	assert( msgidp != NULL );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	ber = ldap_build_compare_req(
		ld, dn, attr, bvalue, sctrls, cctrls, &id );
	if( !ber )
		return ld->ld_errno;

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_COMPARE, dn, ber, id );
	return ( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
Beispiel #4
0
int
ldap_rename(
	LDAP *ld,
	LDAP_CONST char *dn,
	LDAP_CONST char *newrdn,
	LDAP_CONST char *newSuperior,
	int deleteoldrdn,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int *msgidp )
{
	BerElement	*ber;
	int rc;
	ber_int_t id;

	Debug( LDAP_DEBUG_TRACE, "ldap_rename\n" );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	ber = ldap_build_moddn_req( ld, dn, newrdn, newSuperior,
		deleteoldrdn, sctrls, cctrls, &id );
	if( !ber )
		return ld->ld_errno;

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODRDN, dn, ber, id );

	if( *msgidp < 0 ) {
		return( ld->ld_errno );
	}

	return LDAP_SUCCESS;
}
Beispiel #5
0
/*
 * ldap_delete_ext - initiate an ldap extended delete operation. Parameters:
 *
 *	ld		LDAP descriptor
 *	dn		DN of the object to delete
 *	sctrls	Server Controls
 *	cctrls	Client Controls
 *	msgidp	Message Id Pointer
 *
 * Example:
 *	rc = ldap_delete( ld, dn, sctrls, cctrls, msgidp );
 */
int
ldap_delete_ext(
	LDAP *ld,
	LDAP_CONST char* dn,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int *msgidp )
{
	int rc;
	BerElement	*ber;

#ifdef NEW_LOGGING
	LDAP_LOG ( OPERATION, ENTRY, "ldap_delete_ext\n", 0,0,0 );
#else
	Debug( LDAP_DEBUG_TRACE, "ldap_delete_ext\n", 0, 0, 0 );
#endif

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( dn != NULL );
	assert( msgidp != NULL );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return( ld->ld_errno );
	}

	if ( ber_printf( ber, "{its", /* '}' */
		++ld->ld_msgid, LDAP_REQ_DELETE, dn ) == -1 )
	{
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_DELETE, dn, ber );

	if(*msgidp < 0)
		return ld->ld_errno;

	return LDAP_SUCCESS;
}
Beispiel #6
0
/*
 * ldap_compare_ext - perform an ldap extended compare operation.  The dn
 * of the entry to compare to and the attribute and value to compare (in
 * attr and value) are supplied.  The msgid of the response is returned.
 *
 * Example:
 *	struct berval bvalue = { "secret", sizeof("secret")-1 };
 *	rc = ldap_compare( ld, "c=us@cn=bob",
 *		"userPassword", &bvalue,
 *		sctrl, cctrl, &msgid )
 */
int
ldap_compare_ext(
	LDAP *ld,
	LDAP_CONST char *dn,
	LDAP_CONST char *attr,
	struct berval *bvalue,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int	*msgidp )
{
	int rc;
	BerElement	*ber;
	ber_int_t	id;

	Debug( LDAP_DEBUG_TRACE, "ldap_compare\n", 0, 0, 0 );

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( dn != NULL );
	assert( attr != NULL );
	assert( msgidp != NULL );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		return( LDAP_NO_MEMORY );
	}

	LDAP_NEXT_MSGID(ld, id);
	rc = ber_printf( ber, "{it{s{sON}N}", /* '}' */
		id,
		LDAP_REQ_COMPARE, dn, attr, bvalue );
	if ( rc == -1 )
	{
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}


	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_COMPARE, dn, ber, id );
	return ( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
Beispiel #7
0
/*
 * ldap_kerberos_bind1 - initiate a bind to the ldap server using
 * kerberos authentication.  The dn is supplied.  It is assumed the user
 * already has a valid ticket granting ticket.  The msgid of the
 * request is returned on success (suitable for passing to ldap_result()),
 * -1 is returned if there's trouble.
 *
 * Example:
 *	ldap_kerberos_bind1( ld, "cn=manager, o=university of michigan, c=us" )
 */
int
ldap_kerberos_bind1( LDAP *ld, LDAP_CONST char *dn )
{
	BerElement	*ber;
	char		*cred;
	int		rc;
	ber_len_t credlen;
	ber_int_t	id;

	Debug( LDAP_DEBUG_TRACE, "ldap_kerberos_bind1\n", 0, 0, 0 );

	if( ld->ld_version > LDAP_VERSION2 ) {
		ld->ld_errno = LDAP_NOT_SUPPORTED;
		return -1;
	}

	if ( dn == NULL )
		dn = "";

	if ( (cred = ldap_get_kerberosv4_credentials( ld, dn, "ldapserver",
	    &credlen )) == NULL ) {
		return( -1 );	/* ld_errno should already be set */
	}

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		LDAP_FREE( cred );
		return( -1 );
	}

	LDAP_NEXT_MSGID( ld, id );
	/* fill it in */
	rc = ber_printf( ber, "{it{istoN}N}", id, LDAP_REQ_BIND,
	    ld->ld_version, dn, LDAP_AUTH_KRBV41, cred, credlen );

	if ( rc == -1 ) {
		LDAP_FREE( cred );
		ber_free( ber, 1 );
		ld->ld_errno = LDAP_ENCODING_ERROR;
		return( -1 );
	}

	LDAP_FREE( cred );


	/* send the message */
	return ( ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id ));
}
Beispiel #8
0
/*
 * ldap_search - initiate an ldap search operation.
 *
 * Parameters:
 *
 *	ld		LDAP descriptor
 *	base		DN of the base object
 *	scope		the search scope - one of
 *				LDAP_SCOPE_BASE (baseObject),
 *			    LDAP_SCOPE_ONELEVEL (oneLevel),
 *				LDAP_SCOPE_SUBTREE (subtree), or
 *				LDAP_SCOPE_SUBORDINATE (children) -- OpenLDAP extension
 *	filter		a string containing the search filter
 *			(e.g., "(|(cn=bob)(sn=bob))")
 *	attrs		list of attribute types to return for matches
 *	attrsonly	1 => attributes only 0 => attributes and values
 *
 * Example:
 *	char	*attrs[] = { "mail", "title", 0 };
 *	msgid = ldap_search( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE, "cn~=bob",
 *	    attrs, attrsonly );
 */
int
ldap_search(
    LDAP *ld, LDAP_CONST char *base, int scope, LDAP_CONST char *filter,
    char **attrs, int attrsonly )
{
    BerElement	*ber;
    ber_int_t	id;

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

    assert( ld != NULL );
    assert( LDAP_VALID( ld ) );

    ber = ldap_build_search_req( ld, base, scope, filter, attrs,
                                 attrsonly, NULL, NULL, -1, -1, -1, &id );

    if ( ber == NULL ) {
        return( -1 );
    }


    /* send the message */
    return ( ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber, id ));
}
Beispiel #9
0
int
ldap_sasl_bind(
	LDAP			*ld,
	LDAP_CONST char	*dn,
	LDAP_CONST char	*mechanism,
	struct berval	*cred,
	LDAPControl		**sctrls,
	LDAPControl		**cctrls,
	int				*msgidp )
{
	BerElement	*ber;
	int rc;
	ber_int_t id;

	Debug( LDAP_DEBUG_TRACE, "ldap_sasl_bind\n", 0, 0, 0 );

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( msgidp != NULL );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	ber = ldap_build_bind_req( ld, dn, mechanism, cred, sctrls, cctrls, &id );
	if( !ber )
		return ld->ld_errno;

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id );

	if(*msgidp < 0)
		return ld->ld_errno;

	return LDAP_SUCCESS;
}
Beispiel #10
0
/*
 * ldap_modify_ext - initiate an ldap extended modify operation.
 *
 * Parameters:
 *
 *	ld		LDAP descriptor
 *	dn		DN of the object to modify
 *	mods		List of modifications to make.  This is null-terminated
 *			array of struct ldapmod's, specifying the modifications
 *			to perform.
 *	sctrls	Server Controls
 *	cctrls	Client Controls
 *	msgidp	Message ID pointer
 *
 * Example:
 *	LDAPMod	*mods[] = { 
 *			{ LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
 *			{ LDAP_MOD_REPLACE, "sn", { "babs jensen", "babs", 0 } },
 *			{ LDAP_MOD_DELETE, "ou", 0 },
 *			{ LDAP_MOD_INCREMENT, "uidNumber, { "1", 0 } }
 *			0
 *		}
 *	rc=  ldap_modify_ext( ld, dn, mods, sctrls, cctrls, &msgid );
 */
int
ldap_modify_ext( LDAP *ld,
	LDAP_CONST char *dn,
	LDAPMod **mods,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int *msgidp )
{
	BerElement	*ber;
	int		i, rc;
	ber_int_t	id;

	Debug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		return( LDAP_NO_MEMORY );
	}

	LDAP_NEXT_MSGID( ld, id );
	rc = ber_printf( ber, "{it{s{" /*}}}*/, id, LDAP_REQ_MODIFY, dn );
	if ( rc == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* allow mods to be NULL ("touch") */
	if ( mods ) {
		/* for each modification to be performed... */
		for ( i = 0; mods[i] != NULL; i++ ) {
			if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
				rc = ber_printf( ber, "{e{s[V]N}N}",
				    (ber_int_t) ( mods[i]->mod_op & ~LDAP_MOD_BVALUES ),
				    mods[i]->mod_type, mods[i]->mod_bvalues );
			} else {
				rc = ber_printf( ber, "{e{s[v]N}N}",
					(ber_int_t) mods[i]->mod_op,
				    mods[i]->mod_type, mods[i]->mod_values );
			}

			if ( rc == -1 ) {
				ld->ld_errno = LDAP_ENCODING_ERROR;
				ber_free( ber, 1 );
				return( ld->ld_errno );
			}
		}
	}

	if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber, id );
	return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
int
ldap_extended_operation(
	LDAP			*ld,
	LDAP_CONST char	*reqoid,
	struct berval	*reqdata,
	LDAPControl		**sctrls,
	LDAPControl		**cctrls,
	int				*msgidp )
{
	BerElement *ber;
	int rc;
	ber_int_t id;

	Debug( LDAP_DEBUG_TRACE, "ldap_extended_operation\n", 0, 0, 0 );

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( reqoid != NULL && *reqoid != '\0' );
	assert( msgidp != NULL );

	/* must be version 3 (or greater) */
	if ( ld->ld_version < LDAP_VERSION3 ) {
		ld->ld_errno = LDAP_NOT_SUPPORTED;
		return( ld->ld_errno );
	}

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return( ld->ld_errno );
	}

	LDAP_NEXT_MSGID( ld, id );
	if ( reqdata != NULL ) {
		rc = ber_printf( ber, "{it{tstON}", /* '}' */
			id, LDAP_REQ_EXTENDED,
			LDAP_TAG_EXOP_REQ_OID, reqoid,
			LDAP_TAG_EXOP_REQ_VALUE, reqdata );

	} else {
		rc = ber_printf( ber, "{it{tsN}", /* '}' */
			id, LDAP_REQ_EXTENDED,
			LDAP_TAG_EXOP_REQ_OID, reqoid );
	}

	if( rc == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_EXTENDED, NULL, ber, id );

	return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
Beispiel #12
0
/*
 * ldap_modify_ext - initiate an ldap extended modify operation.
 *
 * Parameters:
 *
 *	ld		LDAP descriptor
 *	dn		DN of the object to modify
 *	mods		List of modifications to make.  This is null-terminated
 *			array of struct ldapmod's, specifying the modifications
 *			to perform.
 *	sctrls	Server Controls
 *	cctrls	Client Controls
 *	msgidp	Message ID pointer
 *
 * Example:
 *	LDAPMod	*mods[] = { 
 *			{ LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
 *			{ LDAP_MOD_REPLACE, "sn", { "jensen", 0 } },
 *			0
 *		}
 *	rc=  ldap_modify_ext( ld, dn, mods, sctrls, cctrls, &msgid );
 */
int
ldap_modify_ext( LDAP *ld,
	LDAP_CONST char *dn,
	LDAPMod **mods,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int *msgidp )
{
	BerElement	*ber;
	int		i, rc;

	/*
	 * A modify request looks like this:
	 *	ModifyRequet ::= SEQUENCE {
	 *		object		DistinguishedName,
	 *		modifications	SEQUENCE OF SEQUENCE {
	 *			operation	ENUMERATED {
	 *				add	(0),
	 *				delete	(1),
	 *				replace	(2)
	 *			},
	 *			modification	SEQUENCE {
	 *				type	AttributeType,
	 *				values	SET OF AttributeValue
	 *			}
	 *		}
	 *	}
	 */

#ifdef NEW_LOGGING
	LDAP_LOG ( OPERATION, ENTRY, "ldap_modify_ext\n", 0, 0, 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
#endif

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		return( LDAP_NO_MEMORY );
	}

	if ( ber_printf( ber, "{it{s{" /*}}}*/, ++ld->ld_msgid, LDAP_REQ_MODIFY, dn )
	    == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* for each modification to be performed... */
	for ( i = 0; mods[i] != NULL; i++ ) {
		if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
			rc = ber_printf( ber, "{e{s[V]N}N}",
			    (ber_int_t) ( mods[i]->mod_op & ~LDAP_MOD_BVALUES ),
			    mods[i]->mod_type, mods[i]->mod_bvalues );
		} else {
			rc = ber_printf( ber, "{e{s[v]N}N}",
				(ber_int_t) mods[i]->mod_op,
			    mods[i]->mod_type, mods[i]->mod_values );
		}

		if ( rc == -1 ) {
			ld->ld_errno = LDAP_ENCODING_ERROR;
			ber_free( ber, 1 );
			return( ld->ld_errno );
		}
	}

	if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber );
	return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
Beispiel #13
0
meta_search_candidate_t
asyncmeta_back_modrdn_start(Operation *op,
			    SlapReply *rs,
			    a_metaconn_t *mc,
			    bm_context_t *bc,
			    int candidate)
{
	a_dncookie	dc;
	a_metainfo_t	*mi = mc->mc_info;
	a_metatarget_t	*mt = mi->mi_targets[ candidate ];
	struct berval	mdn = BER_BVNULL,
		mnewSuperior = BER_BVNULL,
		newrdn = BER_BVNULL;
	int rc = 0, nretries = 1;
	LDAPControl	**ctrls = NULL;
	meta_search_candidate_t retcode = META_SEARCH_CANDIDATE;
	BerElement *ber = NULL;
	a_metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
	SlapReply		*candidates = bc->candidates;
	ber_int_t	msgid;

	dc.target = mt;
	dc.conn = op->o_conn;
	dc.rs = rs;

	if ( op->orr_newSup ) {

		/*
		 * NOTE: the newParent, if defined, must be on the
		 * same target as the entry to be renamed.  This check
		 * has been anticipated in meta_back_getconn()
		 */
		/*
		 * FIXME: one possibility is to delete the entry
		 * from one target and add it to the other;
		 * unfortunately we'd need write access to both,
		 * which is nearly impossible; for administration
		 * needs, the rootdn of the metadirectory could
		 * be mapped to an administrative account on each
		 * target (the binddn?); we'll see.
		 */
		/*
		 * NOTE: we need to port the identity assertion
		 * feature from back-ldap
		 */

		/* needs LDAPv3 */
		switch ( mt->mt_version ) {
		case LDAP_VERSION3:
			break;

		case 0:
			if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
				break;
			}
			/* fall thru */

		default:
			/* op->o_protocol cannot be anything but LDAPv3,
			 * otherwise wouldn't be here */
			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			retcode = META_SEARCH_ERR;
			goto done;
		}

		/*
		 * Rewrite the new superior, if defined and required
		 */
		dc.ctx = "newSuperiorDN";
		if ( asyncmeta_dn_massage( &dc, op->orr_newSup, &mnewSuperior ) ) {
			rs->sr_err = LDAP_OTHER;
			retcode = META_SEARCH_ERR;
			goto done;
		}
	}

	/*
	 * Rewrite the modrdn dn, if required
	 */
	dc.ctx = "modrDN";
	if ( asyncmeta_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
		rs->sr_err = LDAP_OTHER;
		retcode = META_SEARCH_ERR;
		goto done;
	}

	/* NOTE: we need to copy the newRDN in case it was formed
	 * from a DN by simply changing the length (ITS#5397) */
	newrdn = op->orr_newrdn;
	if ( newrdn.bv_val[ newrdn.bv_len ] != '\0' ) {
		ber_dupbv_x( &newrdn, &op->orr_newrdn, op->o_tmpmemctx );
	}
retry:;
	ctrls = op->o_ctrls;
	if ( asyncmeta_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS )
	{
		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
		retcode = META_SEARCH_ERR;
		goto done;
	}

	ber = ldap_build_moddn_req( msc->msc_ld, mdn.bv_val, newrdn.bv_val,
			mnewSuperior.bv_val, op->orr_deleteoldrdn, ctrls, NULL, &msgid);
	if (ber) {
		candidates[ candidate ].sr_msgid = msgid;
		rc = ldap_send_initial_request( msc->msc_ld, LDAP_REQ_MODRDN,
						mdn.bv_val, ber, msgid );
		if (rc == msgid)
			rc = LDAP_SUCCESS;
		else
			rc = LDAP_SERVER_DOWN;

		switch ( rc ) {
		case LDAP_SUCCESS:
			retcode = META_SEARCH_CANDIDATE;
			asyncmeta_set_msc_time(msc);
			break;

		case LDAP_SERVER_DOWN:
			ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
			asyncmeta_clear_one_msc(NULL, mc, candidate);
			ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);
			if ( nretries && asyncmeta_retry( op, rs, &mc, candidate, LDAP_BACK_DONTSEND ) ) {
				nretries = 0;
				/* if the identity changed, there might be need to re-authz */
				(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
				goto retry;
			}

		default:
			candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
			retcode = META_SEARCH_ERR;
		}
	}

done:
	(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );

	if ( mdn.bv_val != op->o_req_dn.bv_val ) {
		free( mdn.bv_val );
		BER_BVZERO( &mdn );
	}

	if ( !BER_BVISNULL( &mnewSuperior )
			&& mnewSuperior.bv_val != op->orr_newSup->bv_val )
	{
		free( mnewSuperior.bv_val );
		BER_BVZERO( &mnewSuperior );
	}

	if ( newrdn.bv_val != op->orr_newrdn.bv_val ) {
		op->o_tmpfree( newrdn.bv_val, op->o_tmpmemctx );
	}

doreturn:;
	Debug( LDAP_DEBUG_TRACE, "%s <<< asyncmeta_back_modrdn_start[%p]=%d\n", op->o_log_prefix, msc, candidates[candidate].sr_msgid );
	return retcode;
}
Beispiel #14
0
meta_search_candidate_t
asyncmeta_back_add_start(Operation *op,
			 SlapReply *rs,
			 a_metaconn_t *mc,
			 bm_context_t *bc,
			 int candidate)
{
	int		isupdate;
	Attribute	*a;
	int i;
	LDAPMod		**attrs;
	struct berval	mapped;
	a_dncookie	dc;
	a_metainfo_t	*mi = mc->mc_info;
	a_metatarget_t	*mt = mi->mi_targets[ candidate ];
	struct berval   mdn;
	meta_search_candidate_t retcode = META_SEARCH_CANDIDATE;
	BerElement *ber = NULL;
	a_metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
	SlapReply		*candidates = bc->candidates;
	ber_int_t	msgid;
	LDAPControl		**ctrls = NULL;
	int rc, nretries = 1;


	dc.target = mt;
	dc.conn = op->o_conn;
	dc.rs = rs;
	dc.ctx = "addDN";

	mdn.bv_len = 0;

	switch (asyncmeta_dn_massage( &dc, &bc->op->o_req_dn, &mdn ) )
	{
	case LDAP_SUCCESS:
		break;
	case LDAP_UNWILLING_TO_PERFORM:
		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
		rs->sr_text = "Operation not allowed";
		retcode = META_SEARCH_ERR;
		goto doreturn;
	default:
		rs->sr_err = LDAP_NO_SUCH_OBJECT;
		retcode = META_SEARCH_NOT_CANDIDATE;
		goto doreturn;
	}

	/* Count number of attributes in entry ( +1 ) */
	for ( i = 1, a = op->ora_e->e_attrs; a; i++, a = a->a_next );

	/* Create array of LDAPMods for ldap_add() */
	attrs = ch_malloc( sizeof( LDAPMod * )*i );

	dc.ctx = "addAttrDN";
	isupdate = be_shadow_update( op );
	for ( i = 0, a = op->ora_e->e_attrs; a; a = a->a_next ) {
		int j, is_oc = 0;

		if ( !isupdate && !get_relax( op ) && a->a_desc->ad_type->sat_no_user_mod  )
		{
			continue;
		}

		if ( a->a_desc == slap_schema.si_ad_objectClass
				|| a->a_desc == slap_schema.si_ad_structuralObjectClass )
		{
			is_oc = 1;
			mapped = a->a_desc->ad_cname;

		} else {
			asyncmeta_map( &mt->mt_rwmap.rwm_at,
					&a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
			if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
				continue;
			}
		}

		attrs[ i ] = ch_malloc( sizeof( LDAPMod ) );
		if ( attrs[ i ] == NULL ) {
			continue;
		}
		attrs[ i ]->mod_op = LDAP_MOD_BVALUES;
		attrs[ i ]->mod_type = mapped.bv_val;

		if ( is_oc ) {
			for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ );

			attrs[ i ]->mod_bvalues =
				(struct berval **)ch_malloc( ( j + 1 ) *
				sizeof( struct berval * ) );
			for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); ) {
				struct ldapmapping	*mapping;

				asyncmeta_mapping( &mt->mt_rwmap.rwm_oc,
						&a->a_vals[ j ], &mapping, BACKLDAP_MAP );

				if ( mapping == NULL ) {
					if ( mt->mt_rwmap.rwm_oc.drop_missing ) {
						continue;
					}
					attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];

				} else {
					attrs[ i ]->mod_bvalues[ j ] = &mapping->dst;
				}
				j++;
			}
			attrs[ i ]->mod_bvalues[ j ] = NULL;

		} else {
			/*
			 * FIXME: dn-valued attrs should be rewritten
			 * to allow their use in ACLs at the back-ldap
			 * level.
			 */
			if ( a->a_desc->ad_type->sat_syntax ==
				slap_schema.si_syn_distinguishedName )
			{
				(void)asyncmeta_dnattr_rewrite( &dc, a->a_vals );
				if ( a->a_vals == NULL ) {
					continue;
				}
			}

			for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ )
				;

			attrs[ i ]->mod_bvalues = ch_malloc( ( j + 1 ) * sizeof( struct berval * ) );
			for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) {
				attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];
			}
			attrs[ i ]->mod_bvalues[ j ] = NULL;
		}
		i++;
	}
	attrs[ i ] = NULL;

retry:;
	ctrls = op->o_ctrls;
	if ( asyncmeta_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS )
	{
		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
		retcode = META_SEARCH_ERR;
		goto done;
	}

	ber = ldap_build_add_req( msc->msc_ld, mdn.bv_val, attrs, ctrls, NULL, &msgid);
	if (ber) {
		candidates[ candidate ].sr_msgid = msgid;
		rc = ldap_send_initial_request( msc->msc_ld, LDAP_REQ_ADD,
						mdn.bv_val, ber, msgid );
		if (rc == msgid)
			rc = LDAP_SUCCESS;
		else
			rc = LDAP_SERVER_DOWN;

		switch ( rc ) {
		case LDAP_SUCCESS:
			retcode = META_SEARCH_CANDIDATE;
			asyncmeta_set_msc_time(msc);
			break;

		case LDAP_SERVER_DOWN:
			ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
			asyncmeta_clear_one_msc(NULL, mc, candidate);
			ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);
			if ( nretries && asyncmeta_retry( op, rs, &mc, candidate, LDAP_BACK_DONTSEND ) ) {
				nretries = 0;
				/* if the identity changed, there might be need to re-authz */
				(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
				goto retry;
			}

		default:
			candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
			retcode = META_SEARCH_ERR;
		}
	}

done:

	(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );

	for ( --i; i >= 0; --i ) {
		free( attrs[ i ]->mod_bvalues );
		free( attrs[ i ] );
	}
	free( attrs );
	if ( mdn.bv_val != op->ora_e->e_dn ) {
		free( mdn.bv_val );
		BER_BVZERO( &mdn );
	}

doreturn:;
	Debug( LDAP_DEBUG_TRACE, "%s <<< asyncmeta_back_add_start[%p]=%d\n", op->o_log_prefix, msc, candidates[candidate].sr_msgid );
	return retcode;
}
Beispiel #15
0
/*
 * ldap_search_ext - initiate an ldap search operation.
 *
 * Parameters:
 *
 *	ld		LDAP descriptor
 *	base		DN of the base object
 *	scope		the search scope - one of LDAP_SCOPE_BASE,
 *			    LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE
 *	filter		a string containing the search filter
 *			(e.g., "(|(cn=bob)(sn=bob))")
 *	attrs		list of attribute types to return for matches
 *	attrsonly	1 => attributes only 0 => attributes and values
 *
 * Example:
 *	char	*attrs[] = { "mail", "title", 0 };
 *	ldap_search_ext( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE, "cn~=bob",
 *	    attrs, attrsonly, sctrls, ctrls, timeout, sizelimit,
 *		&msgid );
 */
int
ldap_search_ext(
	LDAP *ld,
	LDAP_CONST char *base,
	int scope,
	LDAP_CONST char *filter,
	char **attrs,
	int attrsonly,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	struct timeval *timeout,
	int sizelimit,
	int *msgidp )
{
	int rc;
	BerElement	*ber;
	int timelimit;

#ifdef NEW_LOGGING
	LDAP_LOG ( OPERATION, ENTRY, "ldap_search_ext\n", 0, 0, 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "ldap_search_ext\n", 0, 0, 0 );
#endif

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	/*
	 * if timeout is provided, both tv_sec and tv_usec must
	 * be non-zero
	 */
	if( timeout != NULL ) {
		if( timeout->tv_sec == 0 && timeout->tv_usec == 0 ) {
			return LDAP_PARAM_ERROR;
		}

		/* timelimit must be non-zero if timeout is provided */
		timelimit = timeout->tv_sec != 0 ? timeout->tv_sec : 1;

	} else {
		/* no timeout, no timelimit */
		timelimit = -1;
	}

	ber = ldap_build_search_req( ld, base, scope, filter, attrs,
	    attrsonly, sctrls, cctrls, timelimit, sizelimit ); 

	if ( ber == NULL ) {
		return ld->ld_errno;
	}


	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber );

	if( *msgidp < 0 )
		return ld->ld_errno;

	return LDAP_SUCCESS;
}
Beispiel #16
0
/*
 * ldap_add_ext - initiate an ldap extended add operation.  Parameters:
 *
 *	ld		LDAP descriptor
 *	dn		DN of the entry to add
 *	mods		List of attributes for the entry.  This is a null-
 *			terminated array of pointers to LDAPMod structures.
 *			only the type and values in the structures need be
 *			filled in.
 *	sctrl	Server Controls
 *	cctrl	Client Controls
 *	msgidp	Message ID pointer
 *
 * Example:
 *	LDAPMod	*attrs[] = { 
 *			{ 0, "cn", { "babs jensen", "babs", 0 } },
 *			{ 0, "sn", { "jensen", 0 } },
 *			{ 0, "objectClass", { "person", 0 } },
 *			0
 *		}
 *	rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid );
 */
int
ldap_add_ext(
	LDAP *ld,
	LDAP_CONST char *dn,
	LDAPMod **attrs,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int	*msgidp )
{
	BerElement	*ber;
	int		i, rc;
	ber_int_t	id;

	Debug( LDAP_DEBUG_TRACE, "ldap_add_ext\n", 0, 0, 0 );
	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( dn != NULL );
	assert( msgidp != NULL );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return ld->ld_errno;
	}

	LDAP_NEXT_MSGID(ld, id);
	rc = ber_printf( ber, "{it{s{", /* '}}}' */
		id, LDAP_REQ_ADD, dn );

	if ( rc == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	/* allow attrs to be NULL ("touch"; should fail...) */
	if ( attrs ) {
		/* for each attribute in the entry... */
		for ( i = 0; attrs[i] != NULL; i++ ) {
			if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
				int j;

				if ( attrs[i]->mod_bvalues == NULL ) {
					ld->ld_errno = LDAP_PARAM_ERROR;
					ber_free( ber, 1 );
					return ld->ld_errno;
				}

				for ( j = 0; attrs[i]->mod_bvalues[ j ] != NULL; j++ ) {
					if ( attrs[i]->mod_bvalues[ j ]->bv_val == NULL ) {
						ld->ld_errno = LDAP_PARAM_ERROR;
						ber_free( ber, 1 );
						return ld->ld_errno;
					}
				}

				rc = ber_printf( ber, "{s[V]N}", attrs[i]->mod_type,
				    attrs[i]->mod_bvalues );

			} else {
				if ( attrs[i]->mod_values == NULL ) {
					ld->ld_errno = LDAP_PARAM_ERROR;
					ber_free( ber, 1 );
					return ld->ld_errno;
				}

				rc = ber_printf( ber, "{s[v]N}", attrs[i]->mod_type,
				    attrs[i]->mod_values );
			}
			if ( rc == -1 ) {
				ld->ld_errno = LDAP_ENCODING_ERROR;
				ber_free( ber, 1 );
				return ld->ld_errno;
			}
		}
	}

	if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber, id );

	if(*msgidp < 0)
		return ld->ld_errno;

	return LDAP_SUCCESS;
}
Beispiel #17
0
int
ldap_rename(
	LDAP *ld,
	LDAP_CONST char *dn,
	LDAP_CONST char *newrdn,
	LDAP_CONST char *newSuperior,
	int deleteoldrdn,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int *msgidp )
{
	BerElement	*ber;
	int rc;
	ber_int_t id;

	Debug( LDAP_DEBUG_TRACE, "ldap_rename\n", 0, 0, 0 );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		return( LDAP_NO_MEMORY );
	}

	LDAP_NEXT_MSGID( ld, id );
	if( newSuperior != NULL ) {
		/* must be version 3 (or greater) */
		if ( ld->ld_version < LDAP_VERSION3 ) {
			ld->ld_errno = LDAP_NOT_SUPPORTED;
			ber_free( ber, 1 );
			return( ld->ld_errno );
		}
		rc = ber_printf( ber, "{it{ssbtsN}", /* '}' */ 
			id, LDAP_REQ_MODDN,
			dn, newrdn, (ber_int_t) deleteoldrdn,
			LDAP_TAG_NEWSUPERIOR, newSuperior );

	} else {
		rc = ber_printf( ber, "{it{ssbN}", /* '}' */ 
			id, LDAP_REQ_MODDN,
			dn, newrdn, (ber_int_t) deleteoldrdn );
	}

	if ( rc < 0 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	rc = ber_printf( ber, /*{*/ "N}" );
	if ( rc < 0 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODRDN, dn, ber, id );
	
	if( *msgidp < 0 ) {
		return( ld->ld_errno );
	}

	return LDAP_SUCCESS;
}
Beispiel #18
0
int
ldap_sasl_bind(
	LDAP			*ld,
	LDAP_CONST char	*dn,
	LDAP_CONST char	*mechanism,
	struct berval	*cred,
	LDAPControl		**sctrls,
	LDAPControl		**cctrls,
	int				*msgidp )
{
	BerElement	*ber;
	int rc;

#ifdef NEW_LOGGING
	LDAP_LOG ( TRANSPORT, ENTRY, "ldap_sasl_bind\n", 0, 0, 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "ldap_sasl_bind\n", 0, 0, 0 );
#endif

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( msgidp != NULL );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	if( mechanism == LDAP_SASL_SIMPLE ) {
		if( dn == NULL && cred != NULL && cred->bv_len ) {
			/* use default binddn */
			dn = ld->ld_defbinddn;
		}

	} else if( ld->ld_version < LDAP_VERSION3 ) {
		ld->ld_errno = LDAP_NOT_SUPPORTED;
		return ld->ld_errno;
	}

	if ( dn == NULL ) {
		dn = "";
	}

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return ld->ld_errno;
	}

	assert( LBER_VALID( ber ) );

	if( mechanism == LDAP_SASL_SIMPLE ) {
		/* simple bind */
		rc = ber_printf( ber, "{it{istON}" /*}*/,
			++ld->ld_msgid, LDAP_REQ_BIND,
			ld->ld_version, dn, LDAP_AUTH_SIMPLE,
			cred );
		
	} else if ( cred == NULL || cred->bv_val == NULL ) {
		/* SASL bind w/o creditials */
		rc = ber_printf( ber, "{it{ist{sN}N}" /*}*/,
			++ld->ld_msgid, LDAP_REQ_BIND,
			ld->ld_version, dn, LDAP_AUTH_SASL,
			mechanism );

	} else {
		/* SASL bind w/ creditials */
		rc = ber_printf( ber, "{it{ist{sON}N}" /*}*/,
			++ld->ld_msgid, LDAP_REQ_BIND,
			ld->ld_version, dn, LDAP_AUTH_SASL,
			mechanism, cred );
	}

	if( rc == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( -1 );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return ld->ld_errno;
	}


	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber );

	if(*msgidp < 0)
		return ld->ld_errno;

	return LDAP_SUCCESS;
}
Beispiel #19
0
meta_search_candidate_t
asyncmeta_back_compare_start(Operation *op,
			    SlapReply *rs,
			    a_metaconn_t *mc,
			    bm_context_t *bc,
			    int candidate)
{
	a_dncookie	dc;
	a_metainfo_t	*mi = mc->mc_info;
	a_metatarget_t	*mt = mi->mi_targets[ candidate ];
	struct berval	mdn = BER_BVNULL;
	struct berval	mapped_attr = op->orc_ava->aa_desc->ad_cname;
	struct berval	mapped_value = op->orc_ava->aa_value;
	int rc = 0, nretries = 1;
	LDAPControl	**ctrls = NULL;
	meta_search_candidate_t retcode = META_SEARCH_CANDIDATE;
	BerElement *ber = NULL;
	a_metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
	SlapReply		*candidates = bc->candidates;
	ber_int_t	msgid;

	dc.target = mt;
	dc.conn = op->o_conn;
	dc.rs = rs;
	dc.ctx = "compareDN";

	switch ( asyncmeta_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
	case LDAP_UNWILLING_TO_PERFORM:
		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
		retcode = META_SEARCH_ERR;
		goto doreturn;
	default:
		break;
	}

	/*
	 * if attr is objectClass, try to remap the value
	 */
	if ( op->orc_ava->aa_desc == slap_schema.si_ad_objectClass ) {
		asyncmeta_map( &mt->mt_rwmap.rwm_oc,
				&op->orc_ava->aa_value,
				&mapped_value, BACKLDAP_MAP );

		if ( BER_BVISNULL( &mapped_value ) || BER_BVISEMPTY( &mapped_value ) ) {
			rs->sr_err = LDAP_OTHER;
			retcode = META_SEARCH_ERR;
			goto done;
		}

	/*
	 * else try to remap the attribute
	 */
	} else {
		asyncmeta_map( &mt->mt_rwmap.rwm_at,
			&op->orc_ava->aa_desc->ad_cname,
			&mapped_attr, BACKLDAP_MAP );
		if ( BER_BVISNULL( &mapped_attr ) || BER_BVISEMPTY( &mapped_attr ) ) {
			rs->sr_err = LDAP_OTHER;
			retcode = META_SEARCH_ERR;
			goto done;
		}

		if ( op->orc_ava->aa_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
		{
			dc.ctx = "compareAttrDN";

			switch ( asyncmeta_dn_massage( &dc, &op->orc_ava->aa_value, &mapped_value ) )
			{
			case LDAP_UNWILLING_TO_PERFORM:
				rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
				retcode = META_SEARCH_ERR;
				goto done;

			default:
				break;
			}
		}
	}
retry:;
	ctrls = op->o_ctrls;
	if ( asyncmeta_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS )
	{
		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
		retcode = META_SEARCH_ERR;
		goto done;
	}

	ber = ldap_build_compare_req( msc->msc_ld, mdn.bv_val, mapped_attr.bv_val, &mapped_value,
			ctrls, NULL, &msgid);
	if (ber) {
		candidates[ candidate ].sr_msgid = msgid;
		rc = ldap_send_initial_request( msc->msc_ld, LDAP_REQ_COMPARE,
						mdn.bv_val, ber, msgid );
		if (rc == msgid)
			rc = LDAP_SUCCESS;
		else
			rc = LDAP_SERVER_DOWN;

		switch ( rc ) {
		case LDAP_SUCCESS:
			retcode = META_SEARCH_CANDIDATE;
			asyncmeta_set_msc_time(msc);
			break;

		case LDAP_SERVER_DOWN:
			ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
			asyncmeta_clear_one_msc(NULL, mc, candidate);
			ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);
			if ( nretries && asyncmeta_retry( op, rs, &mc, candidate, LDAP_BACK_DONTSEND ) ) {
				nretries = 0;
				/* if the identity changed, there might be need to re-authz */
				(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
				goto retry;
			}

		default:
			candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
			retcode = META_SEARCH_ERR;
		}
	}
done:
	(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );

	if ( mdn.bv_val != op->o_req_dn.bv_val ) {
		free( mdn.bv_val );
	}

	if ( op->orc_ava->aa_value.bv_val != mapped_value.bv_val ) {
		free( mapped_value.bv_val );
	}

doreturn:;
	Debug( LDAP_DEBUG_TRACE, "%s <<< asyncmeta_back_compare_start[%p]=%d\n", op->o_log_prefix, msc, candidates[candidate].sr_msgid );
	return retcode;
}
Beispiel #20
0
meta_search_candidate_t
asyncmeta_back_search_start(
				Operation *op,
				SlapReply *rs,
			    a_metaconn_t *mc,
			    bm_context_t *bc,
			    int candidate,
			    struct berval		*prcookie,
			    ber_int_t		prsize )
{
	SlapReply		*candidates = bc->candidates;
	a_metainfo_t		*mi = ( a_metainfo_t * )mc->mc_info;
	a_metatarget_t		*mt = mi->mi_targets[ candidate ];
	a_metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
	a_dncookie		dc;
	struct berval		realbase = op->o_req_dn;
	int			realscope = op->ors_scope;
	struct berval		mbase = BER_BVNULL;
	struct berval		mfilter = BER_BVNULL;
	char			**mapped_attrs = NULL;
	int			rc;
	meta_search_candidate_t	retcode;
	int timelimit;
	int			nretries = 1;
	LDAPControl		**ctrls = NULL;
	BerElement *ber;
	ber_int_t	msgid;
#ifdef SLAPD_META_CLIENT_PR
	LDAPControl		**save_ctrls = NULL;
#endif /* SLAPD_META_CLIENT_PR */

	/* this should not happen; just in case... */
	if ( msc->msc_ld == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"%s: asyncmeta_back_search_start candidate=%d ld=NULL%s.\n",
			op->o_log_prefix, candidate,
			META_BACK_ONERR_STOP( mi ) ? "" : " (ignored)" );
		candidates[ candidate ].sr_err = LDAP_OTHER;
		if ( META_BACK_ONERR_STOP( mi ) ) {
			return META_SEARCH_ERR;
		}
		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
		return META_SEARCH_NOT_CANDIDATE;
	}

	Debug( LDAP_DEBUG_TRACE, "%s >>> asyncmeta_back_search_start[%d]\n", op->o_log_prefix, candidate, 0 );
	/*
	 * modifies the base according to the scope, if required
	 */
	if ( mt->mt_nsuffix.bv_len > op->o_req_ndn.bv_len ) {
		switch ( op->ors_scope ) {
		case LDAP_SCOPE_SUBTREE:
			/*
			 * make the target suffix the new base
			 * FIXME: this is very forgiving, because
			 * "illegal" searchBases may be turned
			 * into the suffix of the target; however,
			 * the requested searchBase already passed
			 * thru the candidate analyzer...
			 */
			if ( dnIsSuffix( &mt->mt_nsuffix, &op->o_req_ndn ) ) {
				realbase = mt->mt_nsuffix;
				if ( mt->mt_scope == LDAP_SCOPE_SUBORDINATE ) {
					realscope = LDAP_SCOPE_SUBORDINATE;
				}

			} else {
				/*
				 * this target is no longer candidate
				 */
				retcode = META_SEARCH_NOT_CANDIDATE;
				goto doreturn;
			}
			break;

		case LDAP_SCOPE_SUBORDINATE:
		case LDAP_SCOPE_ONELEVEL:
		{
			struct berval	rdn = mt->mt_nsuffix;
			rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," );
			if ( dnIsOneLevelRDN( &rdn )
					&& dnIsSuffix( &mt->mt_nsuffix, &op->o_req_ndn ) )
			{
				/*
				 * if there is exactly one level,
				 * make the target suffix the new
				 * base, and make scope "base"
				 */
				realbase = mt->mt_nsuffix;
				if ( op->ors_scope == LDAP_SCOPE_SUBORDINATE ) {
					if ( mt->mt_scope == LDAP_SCOPE_SUBORDINATE ) {
						realscope = LDAP_SCOPE_SUBORDINATE;
					} else {
						realscope = LDAP_SCOPE_SUBTREE;
					}
				} else {
					realscope = LDAP_SCOPE_BASE;
				}
				break;
			} /* else continue with the next case */
		}

		case LDAP_SCOPE_BASE:
			/*
			 * this target is no longer candidate
			 */
			retcode = META_SEARCH_NOT_CANDIDATE;
			goto doreturn;
		}
	}

	/* check filter expression */
	if ( mt->mt_filter ) {
		metafilter_t *mf;
		for ( mf = mt->mt_filter; mf; mf = mf->mf_next ) {
			if ( regexec( &mf->mf_regex, op->ors_filterstr.bv_val, 0, NULL, 0 ) == 0 )
				break;
		}
		/* nothing matched, this target is no longer a candidate */
		if ( !mf ) {
			retcode = META_SEARCH_NOT_CANDIDATE;
			goto doreturn;
		}
	}

	/*
	 * Rewrite the search base, if required
	 */
	dc.target = mt;
	dc.ctx = "searchBase";
	dc.conn = op->o_conn;
	dc.rs = rs;
	switch ( asyncmeta_dn_massage( &dc, &realbase, &mbase ) ) {
	case LDAP_SUCCESS:
		break;

	case LDAP_UNWILLING_TO_PERFORM:
		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
		rs->sr_text = "Operation not allowed";
		retcode = META_SEARCH_ERR;
		goto doreturn;

	default:

		/*
		 * this target is no longer candidate
		 */
		retcode = META_SEARCH_NOT_CANDIDATE;
		goto doreturn;
	}

	/*
	 * Maps filter
	 */
	rc = asyncmeta_filter_map_rewrite( &dc, op->ors_filter,
			&mfilter, BACKLDAP_MAP, NULL );
	switch ( rc ) {
	case LDAP_SUCCESS:
		break;

	case LDAP_COMPARE_FALSE:
	default:
		/*
		 * this target is no longer candidate
		 */
		retcode = META_SEARCH_NOT_CANDIDATE;
		goto done;
	}

	/*
	 * Maps required attributes
	 */
	rc = asyncmeta_map_attrs( op, &mt->mt_rwmap.rwm_at,
			op->ors_attrs, BACKLDAP_MAP, &mapped_attrs );
	if ( rc != LDAP_SUCCESS ) {
		/*
		 * this target is no longer candidate
		 */
		retcode = META_SEARCH_NOT_CANDIDATE;
		goto done;
	}

	if ( op->ors_tlimit != SLAP_NO_LIMIT ) {
		timelimit = op->ors_tlimit > 0 ? op->ors_tlimit : 1;
	} else {
		timelimit = -1;	/* no limit */
	}

#ifdef SLAPD_META_CLIENT_PR
	save_ctrls = op->o_ctrls;
	{
		LDAPControl *pr_c = NULL;
		int i = 0, nc = 0;

		if ( save_ctrls ) {
			for ( ; save_ctrls[i] != NULL; i++ );
			nc = i;
			pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, save_ctrls, NULL );
		}

		if ( pr_c != NULL ) nc--;
		if ( mt->mt_ps > 0 || prcookie != NULL ) nc++;

		if ( mt->mt_ps > 0 || prcookie != NULL || pr_c != NULL ) {
			int src = 0, dst = 0;
			BerElementBuffer berbuf;
			BerElement *ber = (BerElement *)&berbuf;
			struct berval val = BER_BVNULL;
			ber_len_t len;

			len = sizeof( LDAPControl * )*( nc + 1 ) + sizeof( LDAPControl );

			if ( mt->mt_ps > 0 || prcookie != NULL ) {
				struct berval nullcookie = BER_BVNULL;
				ber_tag_t tag;

				if ( prsize == 0 && mt->mt_ps > 0 ) prsize = mt->mt_ps;
				if ( prcookie == NULL ) prcookie = &nullcookie;

				ber_init2( ber, NULL, LBER_USE_DER );
				tag = ber_printf( ber, "{iO}", prsize, prcookie );
				if ( tag == LBER_ERROR ) {
					/* error */
					(void) ber_free_buf( ber );
					goto done_pr;
				}

				tag = ber_flatten2( ber, &val, 0 );
				if ( tag == LBER_ERROR ) {
					/* error */
					(void) ber_free_buf( ber );
					goto done_pr;
				}

				len += val.bv_len + 1;
			}

			op->o_ctrls = op->o_tmpalloc( len, op->o_tmpmemctx );
			if ( save_ctrls ) {
				for ( ; save_ctrls[ src ] != NULL; src++ ) {
					if ( save_ctrls[ src ] != pr_c ) {
						op->o_ctrls[ dst ] = save_ctrls[ src ];
						dst++;
					}
				}
			}

			if ( mt->mt_ps > 0 || prcookie != NULL ) {
				op->o_ctrls[ dst ] = (LDAPControl *)&op->o_ctrls[ nc + 1 ];

				op->o_ctrls[ dst ]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
				op->o_ctrls[ dst ]->ldctl_iscritical = 1;

				op->o_ctrls[ dst ]->ldctl_value.bv_val = (char *)&op->o_ctrls[ dst ][ 1 ];
				AC_MEMCPY( op->o_ctrls[ dst ]->ldctl_value.bv_val, val.bv_val, val.bv_len + 1 );
				op->o_ctrls[ dst ]->ldctl_value.bv_len = val.bv_len;
				dst++;

				(void)ber_free_buf( ber );
			}

			op->o_ctrls[ dst ] = NULL;
		}
done_pr:;
	}
#endif /* SLAPD_META_CLIENT_PR */

retry:;
	asyncmeta_set_msc_time(msc);
	ctrls = op->o_ctrls;
	if (nretries == 0)
	{
		if (rc != LDAP_SUCCESS)
		{
			rs->sr_err = LDAP_BUSY;
			retcode = META_SEARCH_ERR;
			candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
		        goto done;
		}
	}

	if ( asyncmeta_controls_add( op, rs, mc, candidate, &ctrls )
		!= LDAP_SUCCESS )
	{
		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
		retcode = META_SEARCH_NOT_CANDIDATE;
		goto done;
	}

	/*
	 * Starts the search
	 */
	ber = ldap_build_search_req( msc->msc_ld,
			mbase.bv_val, realscope, mfilter.bv_val,
			mapped_attrs, op->ors_attrsonly,
			ctrls, NULL, timelimit, op->ors_slimit, op->ors_deref,
			&msgid );
	if (ber) {
		candidates[ candidate ].sr_msgid = msgid;
		rc = ldap_send_initial_request( msc->msc_ld, LDAP_REQ_SEARCH,
			mbase.bv_val, ber, msgid );
		if (rc == msgid)
			rc = LDAP_SUCCESS;
		else
			rc = LDAP_SERVER_DOWN;
		switch ( rc ) {
		case LDAP_SUCCESS:
			retcode = META_SEARCH_CANDIDATE;
			asyncmeta_set_msc_time(msc);
			break;

		case LDAP_SERVER_DOWN:
			ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
			if (mc->mc_active < 1) {
				asyncmeta_clear_one_msc(NULL, mc, candidate);
			}
			ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);
			if ( nretries && asyncmeta_retry( op, rs, &mc, candidate, LDAP_BACK_DONTSEND ) ) {
				nretries = 0;
				/* if the identity changed, there might be need to re-authz */
				(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
				goto retry;
			}
			rs->sr_err = LDAP_UNAVAILABLE;
			retcode = META_SEARCH_ERR;
			break;
		default:
			candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
			retcode = META_SEARCH_NOT_CANDIDATE;
		}
	}

done:;
	(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
#ifdef SLAPD_META_CLIENT_PR
	if ( save_ctrls != op->o_ctrls ) {
		op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx );
		op->o_ctrls = save_ctrls;
	}
#endif /* SLAPD_META_CLIENT_PR */

	if ( mapped_attrs ) {
		ber_memfree_x( mapped_attrs, op->o_tmpmemctx );
	}
	if ( mfilter.bv_val != op->ors_filterstr.bv_val ) {
		ber_memfree_x( mfilter.bv_val, NULL );
	}
	if ( mbase.bv_val != realbase.bv_val ) {
		free( mbase.bv_val );
	}

doreturn:;
	Debug( LDAP_DEBUG_TRACE, "%s <<< asyncmeta_back_search_start[%p]=%d\n", op->o_log_prefix, msc, candidates[candidate].sr_msgid );
	return retcode;
}