Example #1
0
static int 
nsldapi_search_s(
    LDAP		*ld, 
    const char 		*base, 
    int 		scope, 
    const char 		*filter, 
    char 		**attrs,
    int			attrsonly, 
    LDAPControl		**serverctrls,
    LDAPControl		**clientctrls,
    struct timeval	*localtimeoutp,
    int			timelimit,	/* -1 means use ld->ld_timelimit */
    int			sizelimit,	/* -1 means use ld->ld_sizelimit */
    LDAPMessage		**res
)
{
	int	err, msgid;

	/*
	 * It is an error to pass in a zero'd timeval.
	 */
	if ( localtimeoutp != NULL && localtimeoutp->tv_sec == 0 &&
	    localtimeoutp->tv_usec == 0 ) {
		if ( ld != NULL ) {
			LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
		}
		if ( res != NULL ) {
			*res = NULL;
		}
                return( LDAP_PARAM_ERROR );
        }

	if (( err = nsldapi_search( ld, base, scope, filter, attrs, attrsonly,
	    serverctrls, clientctrls, timelimit, sizelimit, &msgid ))
	    != LDAP_SUCCESS ) {
		if ( res != NULL ) {
			*res = NULL;
		}
		return( err );
	}

	if ( ldap_result( ld, msgid, 1, localtimeoutp, res ) == -1 ) {
		/*
		 * Error.  ldap_result() sets *res to NULL for us.
		 */
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}

	if ( LDAP_GET_LDERRNO( ld, NULL, NULL ) == LDAP_TIMEOUT ) {
		(void) ldap_abandon( ld, msgid );
		err = LDAP_TIMEOUT;
		LDAP_SET_LDERRNO( ld, err, NULL, NULL );
		if ( res != NULL ) {
			*res = NULL;
		}
		return( err );
	}

	return( ldap_result2error( ld, *res, 0 ) );
}
Example #2
0
int
LDAP_CALL
ldap_url_search_s( LDAP *ld, const char *url, int attrsonly, LDAPMessage **res )
{
	int	msgid;

	if (( msgid = ldap_url_search( ld, url, attrsonly )) == -1 ) {
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}

	if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, res ) == -1 ) {
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}

	return( ldap_result2error( ld, *res, 0 ));
}
Example #3
0
/*
 * ldap_extended_operation_s - perform an arbitrary ldapv3 extended operation.
 * the oid and data of the extended operation are supplied. LDAP_SUCCESS
 * is returned upon success, the ldap error code otherwise.
 *
 * Example:
 *	struct berval	exdata, exretval;
 *	char		*exoid;
 *	int		rc;
 *	... fill in oid and data ...
 *	rc = ldap_extended_operation_s( ld, exoid, &exdata, &exretval );
 */
int
LDAP_CALL
ldap_extended_operation_s(
    LDAP		*ld,
    const char		*requestoid,
    const struct berval	*requestdata,
    LDAPControl		**serverctrls,
    LDAPControl		**clientctrls,
    char		**retoidp,
    struct berval	**retdatap
)
{
	int		err, msgid;
	LDAPMessage	*result;

	if (( err = ldap_extended_operation( ld, requestoid, requestdata,
	    serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) {
		return( err );
	}

	if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result )
	    == -1 ) {
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}

	if (( err = ldap_parse_extended_result( ld, result, retoidp, retdatap,
		0 )) != LDAP_SUCCESS ) {
	    ldap_msgfree( result );
	    return( err );
	}

	return( ldap_result2error( ld, result, 1 ) );
}
Example #4
0
/*
 * ldap_sasl_bind_s - bind to the ldap server using sasl authentication
 * The dn, mechanism, and credentials of the entry to which to bind are
 * supplied.  LDAP_SUCCESS is returned upon success, the ldap error code
 * otherwise.
 *
 * Example:
 *	struct berval	creds;
 *	... fill in creds with credentials ...
 *	ldap_sasl_bind_s( ld, "cn=manager, o=university of michigan, c=us",
 *	    "mechanismname", &creds )
 */
int
LDAP_CALL
ldap_sasl_bind_s(
    LDAP		*ld,
    const char		*dn,
    const char		*mechanism,
    const struct berval	*cred,
    LDAPControl		**serverctrls,
    LDAPControl		**clientctrls,
    struct berval	**servercredp
)
{
	int		err, msgid;
	LDAPMessage	*result;

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

	if ( ( err = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls,
	    clientctrls, &msgid )) != LDAP_SUCCESS )
		return( err );

	if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 )
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );

	if (( err = ldap_parse_sasl_bind_result( ld, result, servercredp, 0 ))
	    != LDAP_SUCCESS ) {
		ldap_msgfree( result );
		return( err );
	}

	return( ldap_result2error( ld, result, 1 ) );
}
Example #5
0
/*
 * ldap_simple_bind - bind to the ldap server using simple
 * authentication.  The dn and password of the entry to which to bind are
 * supplied.  LDAP_SUCCESS is returned upon success, the ldap error code
 * otherwise.
 *
 * Example:
 *	ldap_simple_bind_s( ld, "cn=manager, o=university of michigan, c=us",
 *	    "secret" )
 */
int
LDAP_CALL
ldap_simple_bind_s( LDAP *ld, const char *dn, const char *passwd )
{
	int		msgid;
	LDAPMessage	*result;

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

	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
		return( LDAP_PARAM_ERROR );
	}

	if ( (msgid = ldap_simple_bind( ld, dn, passwd )) == -1 )
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );

	if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 )
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );

	return( ldap_result2error( ld, result, 1 ) );
}
Example #6
0
/*
 * ldap_simple_bind - bind to the ldap server using simple
 * authentication.  The dn and password of the entry to which to bind are
 * supplied.  LDAP_SUCCESS is returned upon success, the ldap error code
 * otherwise.
 *
 * Example:
 *	ldap_simple_bind_s( ld, "cn=manager, o=university of michigan, c=us",
 *	    "secret" )
 */
int
LDAP_CALL
ldap_simple_bind_s( LDAP *ld, const char *dn, const char *passwd )
{
	int		msgid;
	LDAPMessage	*result;

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

	if ( NSLDAPI_VALID_LDAP_POINTER( ld ) &&
	    ( ld->ld_options & LDAP_BITOPT_RECONNECT ) != 0 ) {
		return( simple_bindifnot_s( ld, dn, passwd ));
	}

	if ( (msgid = ldap_simple_bind( ld, dn, passwd )) == -1 )
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );

	if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 )
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );

	return( ldap_result2error( ld, result, 1 ) );
}
Example #7
0
int
LDAP_CALL
ldap_url_search_st( LDAP *ld, const char *url, int attrsonly,
	struct timeval *timeout, LDAPMessage **res )
{
	int	msgid;

	/*
	 * It is an error to pass in a zero'd timeval.
	 */
	if ( timeout != NULL && timeout->tv_sec == 0 &&
	    timeout->tv_usec == 0 ) {
		if ( ld != NULL ) {
			LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
		}
		if ( res != NULL ) {
			*res = NULL;
		}
                return( LDAP_PARAM_ERROR );
        }

	if (( msgid = ldap_url_search( ld, url, attrsonly )) == -1 ) {
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}

	if ( ldap_result( ld, msgid, 1, timeout, res ) == -1 ) {
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}

	if ( LDAP_GET_LDERRNO( ld, NULL, NULL ) == LDAP_TIMEOUT ) {
		(void) ldap_abandon( ld, msgid );
		LDAP_SET_LDERRNO( ld, LDAP_TIMEOUT, NULL, NULL );
		return( LDAP_TIMEOUT );
	}

	return( ldap_result2error( ld, *res, 0 ));
}
Example #8
0
static int
nsldapi_sasl_bind_s(
    LDAP                *ld,
    const char          *dn,
    const char          *mechanism,
    const struct berval *cred,
    LDAPControl         **serverctrls,
    LDAPControl         **clientctrls,
    struct berval       **servercredp,
    LDAPControl         ***responsectrls
)
{
        int             err, msgid;
        LDAPMessage     *result;

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

        if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
                return( LDAP_PARAM_ERROR );
        }

        if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
                LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
                return( LDAP_NOT_SUPPORTED );
        }

        if ( ( err = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls,
            clientctrls, &msgid )) != LDAP_SUCCESS )
                return( err );

        if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 )
                return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );

        /* Get the controls sent by the server if requested */
        if ( responsectrls ) {
                if ( ( err = ldap_parse_result( ld, result, &err, NULL, NULL,
                       NULL, responsectrls, 0 )) != LDAP_SUCCESS )
                    return( err );
        }

        err = ldap_parse_sasl_bind_result( ld, result, servercredp, 0 );
        if (err != LDAP_SUCCESS  && err != LDAP_SASL_BIND_IN_PROGRESS) {
                ldap_msgfree( result );
                return( err );
        }

        return( ldap_result2error( ld, result, 1 ) );
}
Example #9
0
int
LDAP_CALL
ldap_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods,
    LDAPControl **serverctrls, LDAPControl **clientctrls )
{
	int		msgid, err;
	LDAPMessage	*res;

	if (( err = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls,
	    &msgid )) != LDAP_SUCCESS ) {
		return( err );
	}

	if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) {
		return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}

	return( ldap_result2error( ld, res, 1 ) );
}
Example #10
0
/*
 * ldap_sasl_bind - authenticate to the ldap server.  The dn, mechanism,
 * and credentials of the entry to which to bind are supplied. An LDAP
 * error code is returned and if LDAP_SUCCESS is returned *msgidp is set
 * to the id of the request initiated.
 *
 * Example:
 *	struct berval	creds;
 *	LDAPControl	**ctrls;
 *	int		err, msgid;
 *	... fill in creds with credentials ...
 *	... fill in ctrls with server controls ...
 *	err = ldap_sasl_bind( ld, "cn=manager, o=university of michigan, c=us",
 *	    "mechanismname", &creds, ctrls, NULL, &msgid );
 */
int
LDAP_CALL
ldap_sasl_bind(
    LDAP		*ld,
    const char		*dn,
    const char		*mechanism,
    const struct berval	*cred,
    LDAPControl		**serverctrls,
    LDAPControl		**clientctrls,
    int			*msgidp
)
{
	BerElement	*ber;
	int		rc, simple, msgid, ldapversion;

	/*
	 * The ldapv3 bind request looks like this:
	 *	BindRequest ::= SEQUENCE {
	 *		version		INTEGER,
	 *		name		DistinguishedName,	 -- who
	 *		authentication	CHOICE {
	 *			simple		[0] OCTET STRING, -- passwd
	 *			sasl		[3] SaslCredentials -- v3 only
	 *		}
	 *	}
	 *	SaslCredentials ::= SEQUENCE {
	 *		mechanism	LDAPString,
	 * 		credentials	OCTET STRING
	 *	}
	 * all wrapped up in an LDAPMessage sequence.
	 */

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

	if ( msgidp == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
                return( LDAP_PARAM_ERROR );
	}

	simple = ( mechanism == LDAP_SASL_SIMPLE );
	ldapversion = NSLDAPI_LDAP_VERSION( ld );

	/* only ldapv3 or higher can do sasl binds */
	if ( !simple && ldapversion < LDAP_VERSION3 ) {
		LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
		return( LDAP_NOT_SUPPORTED );
	}

	LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
	msgid = ++ld->ld_msgid;
	LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );

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

	if ( ld->ld_cache_on && ld->ld_cache_bind != NULL ) {
		LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
		if ( (rc = (ld->ld_cache_bind)( ld, msgid, LDAP_REQ_BIND, dn,
		    cred, LDAP_AUTH_SASL )) != 0 ) {
			*msgidp = rc;
			LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
			return( LDAP_SUCCESS );
		}
		LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
	}

	/* create a message to send */
	if (( rc = nsldapi_alloc_ber_with_options( ld, &ber ))
	    != LDAP_SUCCESS ) {
		return( rc );
	}

	/* fill it in */
	if ( simple ) {		/* simple bind; works in LDAPv2 or v3 */
		struct berval	tmpcred;

		if ( cred == NULL ) {
			tmpcred.bv_val = "";
			tmpcred.bv_len = 0;
			cred = &tmpcred;
		}
		rc = ber_printf( ber, "{it{isto}", msgid, LDAP_REQ_BIND,
		    ldapversion, dn, LDAP_AUTH_SIMPLE, cred->bv_val,
		    (int)cred->bv_len /* XXX lossy cast */ );

	} else {		/* SASL bind; requires LDAPv3 or better */
		if ( cred == NULL ) {
			rc = ber_printf( ber, "{it{ist{s}}", msgid,
			    LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
			    mechanism );
		} else {
			rc = ber_printf( ber, "{it{ist{so}}", msgid,
			    LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
			    mechanism, cred->bv_val,
			    (int)cred->bv_len /* XXX lossy cast */ );
		}
	}

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

	if ( (rc = nsldapi_put_controls( ld, serverctrls, 1, ber ))
	    != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return( rc );
	}

	/* send the message */
	rc = nsldapi_send_initial_request( ld, msgid, LDAP_REQ_BIND,
		(char *)dn, ber );
	*msgidp = rc;
	return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
Example #11
0
/*
 * returns an LDAP error code
 *
 * XXXmcs: this function used to have #ifdef LDAP_DNS code in it but I
 *	removed it when I improved the parsing (we don't define LDAP_DNS
 *	here at Netscape).
 */
static int
chase_one_referral( LDAP *ld, LDAPRequest *lr, LDAPRequest *origreq,
    char *refurl, char *desc, int *unknownp )
{
	int		rc, tmprc, secure, msgid;
	LDAPServer	*srv;
	BerElement	*ber;
	LDAPURLDesc	*ludp;

	*unknownp = 0;
	ludp = NULLLDAPURLDESC;

	if ( nsldapi_url_parse( refurl, &ludp, 0 ) != 0 ) {
		LDAPDebug( LDAP_DEBUG_TRACE,
		    "ignoring unknown %s <%s>\n", desc, refurl, 0 );
		*unknownp = 1;
		rc = LDAP_SUCCESS;
		goto cleanup_and_return;
	}

	secure = (( ludp->lud_options & LDAP_URL_OPT_SECURE ) != 0 );

/* XXXmcs: can't tell if secure is supported by connect callback */
	if ( secure && ld->ld_extconnect_fn == NULL ) {
		LDAPDebug( LDAP_DEBUG_TRACE,
		    "ignoring LDAPS %s <%s>\n", desc, refurl, 0 );
		*unknownp = 1;
		rc = LDAP_SUCCESS;
		goto cleanup_and_return;
	}

	LDAPDebug( LDAP_DEBUG_TRACE, "chasing LDAP%s %s: <%s>\n",
	    secure ? "S" : "", desc, refurl );

	LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
	msgid = ++ld->ld_msgid;
	LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );

	if (( tmprc = re_encode_request( ld, origreq->lr_ber, msgid,
	    ludp, &ber )) != LDAP_SUCCESS ) {
		rc = tmprc;
		goto cleanup_and_return;
	}

	if (( srv = (LDAPServer *)NSLDAPI_CALLOC( 1, sizeof( LDAPServer )))
	    == NULL ) {
		ber_free( ber, 1 );
		rc = LDAP_NO_MEMORY;
		goto cleanup_and_return;
	}

	if (ludp->lud_host == NULL && ld->ld_defhost == NULL) {
		srv->lsrv_host = NULL;
	} else {
		if (ludp->lud_host == NULL) {
			srv->lsrv_host =
			    nsldapi_strdup( origreq->lr_conn->lconn_server->lsrv_host );
			LDAPDebug(LDAP_DEBUG_TRACE,
			    "chase_one_referral: using hostname '%s' from original "
			    "request on new request\n",
			    srv->lsrv_host, 0, 0);
		} else {
			srv->lsrv_host = nsldapi_strdup(ludp->lud_host);
			LDAPDebug(LDAP_DEBUG_TRACE,
			    "chase_one_referral: using hostname '%s' as specified "
			    "on new request\n",
			    srv->lsrv_host, 0, 0);
		}

		if (srv->lsrv_host == NULL) {
			NSLDAPI_FREE((char *)srv);
			ber_free(ber, 1);
			rc = LDAP_NO_MEMORY;
			goto cleanup_and_return;
		}
	}

	/*
	 * According to our reading of RFCs 2255 and 1738, the
	 * following algorithm applies:
	 * - no hostport (no host, no port) provided in LDAP URL, use those
	 *   of previous request
	 * - no port but a host, use default LDAP port
	 * - else use given hostport
	 */
	if (ludp->lud_port == 0 && ludp->lud_host == NULL) {
		srv->lsrv_port = origreq->lr_conn->lconn_server->lsrv_port;
		LDAPDebug(LDAP_DEBUG_TRACE,
		    "chase_one_referral: using port (%d) from original "
		    "request on new request\n",
		    srv->lsrv_port, 0, 0);
	} else if (ludp->lud_port == 0 && ludp->lud_host != NULL) {
		srv->lsrv_port = (secure) ? LDAPS_PORT : LDAP_PORT;
		LDAPDebug(LDAP_DEBUG_TRACE,
		    "chase_one_referral: using default port (%d) \n",
		    srv->lsrv_port, 0, 0);
	} else {
		srv->lsrv_port = ludp->lud_port;
		LDAPDebug(LDAP_DEBUG_TRACE,
		    "chase_one_referral: using port (%d) as specified on "
		    "new request\n",
		    srv->lsrv_port, 0, 0);
	}

	if ( secure ) {
		srv->lsrv_options |= LDAP_SRV_OPT_SECURE;
	}

	if ( nsldapi_send_server_request( ld, ber, msgid,
	    lr, srv, NULL, NULL, 1 ) < 0 ) {
		rc = LDAP_GET_LDERRNO( ld, NULL, NULL );
		LDAPDebug( LDAP_DEBUG_ANY, "Unable to chase %s %s (%s)\n",
		    desc, refurl, ldap_err2string( rc ));
	} else {
		rc = LDAP_SUCCESS;
	}

cleanup_and_return:
	if ( ludp != NULLLDAPURLDESC ) {
		ldap_free_urldesc( ludp );
	}

	return( rc );
}
Example #12
0
int
LDAP_CALL
ldap_extended_operation(
    LDAP		*ld,
    const char		*exoid,
    const struct berval	*exdata,
    LDAPControl		**serverctrls,
    LDAPControl		**clientctrls,
    int			*msgidp
)
{
	BerElement	*ber;
	int		rc, msgid;

	/*
	 * the ldapv3 extended operation request looks like this:
	 *
	 *	ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
	 *		requestName	LDAPOID,
	 *		requestValue	OCTET STRING
	 *	}
	 *
	 * all wrapped up in an LDAPMessage sequence.
	 */

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

	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
		return( LDAP_PARAM_ERROR );
	}


	/* only ldapv3 or higher can do extended operations */
	if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
		rc = LDAP_NOT_SUPPORTED;
		LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
		return( rc );
	}

	if ( msgidp == NULL || exoid == NULL || *exoid == '\0' ) {
		rc = LDAP_PARAM_ERROR;
		LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
		return( rc );
	}

	LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
	msgid = ++ld->ld_msgid;
	LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );

#if 0
	if ( ld->ld_cache_on && ld->ld_cache_extendedop != NULL ) {
		LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
		if ( (rc = (ld->ld_cache_extendedop)( ld, msgid,
		    LDAP_REQ_EXTENDED, exoid, cred )) != 0 ) {
			LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
			return( rc );
		}
		LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
	}
#endif

	/* create a message to send */
	if (( rc = nsldapi_alloc_ber_with_options( ld, &ber ))
	    != LDAP_SUCCESS ) {
		return( rc );
	}

	/* fill it in */
	if ( ber_printf( ber, "{it{tsto}", msgid, LDAP_REQ_EXTENDED,
	    LDAP_TAG_EXOP_REQ_OID, exoid, LDAP_TAG_EXOP_REQ_VALUE,
	    exdata->bv_val, (int)exdata->bv_len /* XXX lossy cast */ ) == -1 ) {
		rc = LDAP_ENCODING_ERROR;
		LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
		ber_free( ber, 1 );
		return( rc );
	}

	if (( rc = nsldapi_put_controls( ld, serverctrls, 1, ber ))
	    != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return( rc );
	}

	/* send the message */
	rc = nsldapi_send_initial_request( ld, msgid, LDAP_REQ_EXTENDED, NULL,
		ber );
	*msgidp = rc;
	return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
Example #13
0
static int
do_entry2text(
	LDAP			*ld,
	char			*buf,		/* NULL for use-internal */
	char			*base,		/* used for search actions */
	LDAPMessage		*entry,
	struct ldap_disptmpl	*tmpl,
	char			**defattrs,
	char			***defvals,
	writeptype		writeproc,
	void			*writeparm,
	char			*eol,
	int			rdncount,
	unsigned long		opts,
	char			*urlprefix	/* if non-NULL, do HTML */
)
{
    int				i, err, html, show, labelwidth;
    int				freebuf,  freevals;
    char			*dn, **vals;
    struct ldap_tmplitem	*rowp, *colp;

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
	return( LDAP_PARAM_ERROR );
    }

    if ( writeproc == NULL ||
	    !NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )) {
	err = LDAP_PARAM_ERROR;
	LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	return( err );
    }

    if (( dn = ldap_get_dn( ld, entry )) == NULL ) {
	return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
    }

    if ( buf == NULL ) {
	if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) {
	    err = LDAP_NO_MEMORY;
	    LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	    NSLDAPI_FREE( dn );
	    return( err );
	}
	freebuf = 1;
    } else {
	freebuf = 0;
    }

    html = ( urlprefix != NULL );

    if ( html ) {
	/*
	 * add HTML intro. and title
	 */
	if (!(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) {
	    sprintf( buf, "<HTML>%s<HEAD>%s<TITLE>%s%s - ", eol, eol, eol,
		    ( tmpl == NULL ) ? "Entry" : tmpl->dt_name );
	    (*writeproc)( writeparm, buf, strlen( buf ));
	    output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL );
	    sprintf( buf, "%s</TITLE>%s</HEAD>%s<BODY>%s<H3>%s - ", eol, eol,
		    eol, eol, ( tmpl == NULL ) ? "Entry" : tmpl->dt_name );
	    (*writeproc)( writeparm, buf, strlen( buf ));
	    output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL );
	    sprintf( buf, "</H3>%s", eol );
	    (*writeproc)( writeparm, buf, strlen( buf ));
	}

	if (( opts & LDAP_DISP_OPT_NONLEAF ) != 0 &&
		( vals = ldap_explode_dn( dn, 0 )) != NULL ) {
	    char	*untagged;

	    /*
	     * add "Move Up" link
	     */
	    sprintf( buf, "<A HREF=\"%s", urlprefix );
	    for ( i = 1; vals[ i ] != NULL; ++i ) {
		if ( i > 1 ) {
		     strcat_escaped( buf, ", " );
		}
		strcat_escaped( buf, vals[ i ] );
	    }
	    if ( vals[ 1 ] != NULL ) {
		untagged = strchr( vals[ 1 ], '=' );
	    } else {
		untagged = "=The World";
	    }
	    sprintf( buf + strlen( buf ),
		    "%s\">Move Up To <EM>%s</EM></A>%s<BR>",
		    ( vals[ 1 ] == NULL ) ? "??one" : "",
		    ( untagged != NULL ) ? untagged + 1 : vals[ 1 ], eol );
	    (*writeproc)( writeparm, buf, strlen( buf ));

	    /*
	     * add "Browse" link
	     */
	    untagged = strchr( vals[ 0 ], '=' );
	    sprintf( buf, "<A HREF=\"%s", urlprefix );
	    strcat_escaped( buf, dn );
	    sprintf( buf + strlen( buf ), "??one?(!(objectClass=dsa))\">Browse Below <EM>%s</EM></A>%s%s",
		    ( untagged != NULL ) ? untagged + 1 : vals[ 0 ], eol, eol );
	    (*writeproc)( writeparm, buf, strlen( buf ));

	    ldap_value_free( vals );
	}

	(*writeproc)( writeparm, "<HR>", 4 );	/* horizontal rule */
    } else {
	(*writeproc)( writeparm, "\"", 1 );
	output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL );
	sprintf( buf, "\"%s", eol );
	(*writeproc)( writeparm, buf, strlen( buf ));
    }

    if ( tmpl != NULL && ( opts & LDAP_DISP_OPT_AUTOLABELWIDTH ) != 0 ) {
	labelwidth = max_label_len( tmpl ) + 3;
    } else {
	labelwidth = DEF_LABEL_WIDTH;;
    }

    err = LDAP_SUCCESS;

    if ( tmpl == NULL ) {
	BerElement	*ber;
	char		*attr;

	ber = NULL;
	for ( attr = ldap_first_attribute( ld, entry, &ber );
		NONFATAL_LDAP_ERR( err ) && attr != NULL;
		attr = ldap_next_attribute( ld, entry, ber )) {
	    if (( vals = ldap_get_values( ld, entry, attr )) == NULL ) {
		freevals = 0;
		if ( defattrs != NULL ) {
		    for ( i = 0; defattrs[ i ] != NULL; ++i ) {
			if ( strcasecmp( attr, defattrs[ i ] ) == 0 ) {
			    break;
			}
		    }
		    if ( defattrs[ i ] != NULL ) {
			vals = defvals[ i ];
		    }
		}
	    } else {
		freevals = 1;
	    }

	    if ( islower( *attr )) {	/* cosmetic -- upcase attr. name */
		*attr = toupper( *attr );
	    }

	    err = do_vals2text( ld, buf, vals, attr, labelwidth,
		    LDAP_SYN_CASEIGNORESTR, writeproc, writeparm, eol, 
		    rdncount, urlprefix );
	    if ( freevals ) {
		ldap_value_free( vals );
	    }
	}
	if ( ber == NULL ) {
	    ber_free( ber, 0 );
	}
	/*
	 * XXX check for errors in ldap_first_attribute/ldap_next_attribute
	 * here (but what should we do if there was one?)
	 */

    } else {
	for ( rowp = ldap_first_tmplrow( tmpl );
		NONFATAL_LDAP_ERR( err ) && rowp != NULLTMPLITEM;
		rowp = ldap_next_tmplrow( tmpl, rowp )) {
	    for ( colp = ldap_first_tmplcol( tmpl, rowp ); colp != NULLTMPLITEM;
		    colp = ldap_next_tmplcol( tmpl, rowp, colp )) {
		vals = NULL;
		if ( colp->ti_attrname == NULL || ( vals = ldap_get_values( ld,
			entry, colp->ti_attrname )) == NULL ) {
		    freevals = 0;
		    if ( !LDAP_IS_TMPLITEM_OPTION_SET( colp,
			    LDAP_DITEM_OPT_HIDEIFEMPTY ) && defattrs != NULL
			    && colp->ti_attrname != NULL ) {
			for ( i = 0; defattrs[ i ] != NULL; ++i ) {
			    if ( strcasecmp( colp->ti_attrname, defattrs[ i ] )
				    == 0 ) {
				break;
			    }
			}
			if ( defattrs[ i ] != NULL ) {
			    vals = defvals[ i ];
			}
		    }
		} else {
		    freevals = 1;
		    if ( LDAP_IS_TMPLITEM_OPTION_SET( colp,
			    LDAP_DITEM_OPT_SORTVALUES ) && vals[ 0 ] != NULL
			    && vals[ 1 ] != NULL ) {
			ldap_sort_values(ld, vals, ldap_sort_strcasecmp);
		    }
		}

		/*
		 * don't bother even calling do_vals2text() if no values
		 * or boolean with value false and "hide if false" option set
		 */
		show = ( vals != NULL && vals[ 0 ] != NULL );
		if ( show && LDAP_GET_SYN_TYPE( colp->ti_syntaxid )
			== LDAP_SYN_TYPE_BOOLEAN && LDAP_IS_TMPLITEM_OPTION_SET(
			colp, LDAP_DITEM_OPT_HIDEIFFALSE ) &&
			toupper( vals[ 0 ][ 0 ] ) != 'T' ) {
		    show = 0;
		}

		if ( colp->ti_syntaxid == LDAP_SYN_SEARCHACTION ) {
		    if (( opts & LDAP_DISP_OPT_DOSEARCHACTIONS ) != 0 ) {
			if ( colp->ti_attrname == NULL || ( show &&
				toupper( vals[ 0 ][ 0 ] ) == 'T' )) {
			    err = searchaction( ld, buf, base, entry, dn, colp,
				    labelwidth, rdncount, writeproc,
				    writeparm, eol, urlprefix );
			}
		    }
		    show = 0;
		}

		if ( show ) {
		    err = do_vals2text( ld, buf, vals, colp->ti_label,
			labelwidth, colp->ti_syntaxid, writeproc, writeparm,
			eol, rdncount, urlprefix );
		}

		if ( freevals ) {
		    ldap_value_free( vals );
		}
	    }
	}
    }

    if ( html  && !(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) {
	sprintf( buf, "</BODY>%s</HTML>%s", eol, eol );
	(*writeproc)( writeparm, buf, strlen( buf ));
    }

    NSLDAPI_FREE( dn );
    if ( freebuf ) {
	NSLDAPI_FREE( buf );
    }

    return( err );
}
Example #14
0
static int
do_entry2text_search(
	LDAP			*ld,
	char			*dn,		/* if NULL, use entry */
	char			*base,		/* if NULL, no search actions */
	LDAPMessage		*entry,		/* if NULL, use dn */
	struct ldap_disptmpl*	tmpllist,	/* if NULL, no template used */
	char			**defattrs,
	char			***defvals,
	writeptype		writeproc,
	void			*writeparm,
	char			*eol,
	int			rdncount,	/* if 0, display full DN */
	unsigned long		opts,
	char			*urlprefix
)
{
    int				err, freedn, html;
    char			*buf, **fetchattrs, **vals;
    LDAPMessage			*ldmp;
    struct ldap_disptmpl	*tmpl;
    struct timeval		timeout;

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
	return( LDAP_PARAM_ERROR );
    }

    if ( dn == NULL && entry == NULLMSG ) {
	err = LDAP_PARAM_ERROR;
	LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	return( err );
    }

    html = ( urlprefix != NULL );

    timeout.tv_sec = SEARCH_TIMEOUT_SECS;
    timeout.tv_usec = 0;

    if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) {
	err = LDAP_NO_MEMORY;
	LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	return( err );
    }

    freedn = 0;
    tmpl = NULL;

    if ( dn == NULL ) {
	if (( dn = ldap_get_dn( ld, entry )) == NULL ) {
	    NSLDAPI_FREE( buf );
	    return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}
	freedn = 1;
    }


    if ( tmpllist != NULL ) {
	ldmp = NULLMSG;

	if ( entry == NULL ) {
	    char	*ocattrs[2];

	    ocattrs[0] = OCATTRNAME;
	    ocattrs[1] = NULL;
#ifdef CLDAP
	    if ( LDAP_IS_CLDAP( ld ))
		    err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE,
			"objectClass=*", ocattrs, 0, &ldmp, NULL );
	    else
#endif /* CLDAP */
		    err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE,
			    "objectClass=*", ocattrs, 0, &timeout, &ldmp );

	    if ( err == LDAP_SUCCESS ) {
		entry = ldap_first_entry( ld, ldmp );
	    }
	}

	if ( entry != NULL ) {
	    vals = ldap_get_values( ld, entry, OCATTRNAME );
	    tmpl = ldap_oc2template( vals, tmpllist );
	    if ( vals != NULL ) {
		ldap_value_free( vals );
	    }
	}
	if ( ldmp != NULL ) {
	    ldap_msgfree( ldmp );
	}
    }

    entry = NULL;

    if ( tmpl == NULL ) {
	fetchattrs = NULL;
    } else {
	fetchattrs = ldap_tmplattrs( tmpl, NULL, 1, LDAP_SYN_OPT_DEFER );
    }

#ifdef CLDAP
    if ( LDAP_IS_CLDAP( ld ))
	err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
		fetchattrs, 0, &ldmp, NULL );
    else
#endif /* CLDAP */
	err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
		fetchattrs, 0, &timeout, &ldmp );

    if ( freedn ) {
	NSLDAPI_FREE( dn );
    }
    if ( fetchattrs != NULL ) {
	ldap_value_free( fetchattrs );
    }

    if ( err != LDAP_SUCCESS ||
	    ( entry = ldap_first_entry( ld, ldmp )) == NULL ) {
	NSLDAPI_FREE( buf );
	return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
    }

    err = do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals,
	    writeproc, writeparm, eol, rdncount, opts, urlprefix );

    NSLDAPI_FREE( buf );
    ldap_msgfree( ldmp );
    return( err );
}
Example #15
0
/*
 * Like ldap_search_ext() except an integer timelimit is passed instead of
 * using the overloaded struct timeval *timeoutp.
 */
static int
nsldapi_search(
    LDAP 		*ld,
    const char 		*base,
    int 		scope,
    const char 		*filter,
    char 		**attrs,
    int 		attrsonly,
    LDAPControl		**serverctrls,
    LDAPControl		**clientctrls,
    int			timelimit,	/* -1 means use ld->ld_timelimit */
    int			sizelimit,	/* -1 means use ld->ld_sizelimit */
    int			*msgidp
)
{
	BerElement	*ber;
	int		rc, rc_key;
	unsigned long	key;	/* XXXmcs: memcache */

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

	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
		return( LDAP_PARAM_ERROR );
	}

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

	if ( filter == NULL ) {
	    filter = "(objectclass=*)";
	}

	if ( msgidp == NULL || ( scope != LDAP_SCOPE_BASE
	    && scope != LDAP_SCOPE_ONELEVEL && scope != LDAP_SCOPE_SUBTREE )
		|| ( sizelimit < -1 )) {
		LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
                return( LDAP_PARAM_ERROR );
        }
	LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
	*msgidp = ++ld->ld_msgid;
	LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );

	/*
	 * XXXmcs: should use cache function pointers to hook in memcache
	 */
	if ( ld->ld_memcache == NULL ) {
		rc_key = LDAP_NOT_SUPPORTED;
	} else if (( rc_key = ldap_memcache_createkey( ld, base, scope, filter,
	    attrs, attrsonly, serverctrls, clientctrls, &key)) == LDAP_SUCCESS
	    && ldap_memcache_result( ld, *msgidp, key ) == LDAP_SUCCESS ) {
		return LDAP_SUCCESS;
	}

	/* check the cache */
	if ( ld->ld_cache_on && ld->ld_cache_search != NULL ) {
		LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
		if ( (rc = (ld->ld_cache_search)( ld, *msgidp, LDAP_REQ_SEARCH,
		    base, scope, filter, attrs, attrsonly )) != 0 ) {
			*msgidp = rc;
			LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
			return( LDAP_SUCCESS );
		}
		LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
	}

	/* caching off or did not find it in the cache - check the net */
	if (( rc = nsldapi_build_search_req( ld, base, scope, filter, attrs,
	    attrsonly, serverctrls, clientctrls, timelimit, sizelimit,
	    *msgidp, &ber )) != LDAP_SUCCESS ) {
		return( rc );
	}

	/* send the message */
	rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_SEARCH,
		(char *) base, ber );

	/*
	 * XXXmcs: should use cache function pointers to hook in memcache
	 */
	if ( (rc_key == LDAP_SUCCESS) && (rc >= 0) ) {
		ldap_memcache_new( ld, rc, key, base );
	}

	*msgidp = rc;
	return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
Example #16
0
static int
nsldapi_get_sasl_mechs ( LDAP *ld, char **pmech )
{
        char *attr[] = { "supportedSASLMechanisms", NULL };
        char **values, **v, *mech, *m;
        LDAPMessage *res, *e;
        struct timeval  timeout;
        int slen, rc;

        if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
                return( LDAP_PARAM_ERROR );
        }

        timeout.tv_sec = SEARCH_TIMEOUT_SECS;
        timeout.tv_usec = 0;

        rc = ldap_search_st( ld, "", LDAP_SCOPE_BASE,
                "objectclass=*", attr, 0, &timeout, &res );

        if ( rc != LDAP_SUCCESS ) {
                return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
        }

        e = ldap_first_entry( ld, res );
        if ( e == NULL ) {
                ldap_msgfree( res );
                if ( ld->ld_errno == LDAP_SUCCESS ) {
                        LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_OBJECT, NULL, NULL );
                }
                return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
        }

        values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
        if ( values == NULL ) {
                ldap_msgfree( res );
                LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_ATTRIBUTE, NULL, NULL );
                return( LDAP_NO_SUCH_ATTRIBUTE );
        }

        slen = 0;
        for(v = values; *v != NULL; v++ ) {
                slen += strlen(*v) + 1;
        }
        if ( (mech = NSLDAPI_CALLOC(1, slen)) == NULL) {
                ldap_value_free( values );
                ldap_msgfree( res );
                LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
                return( LDAP_NO_MEMORY );
        }
        m = mech;
        for(v = values; *v; v++) {
                if (v != values) {
                        *m++ = ' ';
                }
                slen = strlen(*v);
                strncpy(m, *v, slen);
                m += slen;
        }
        *m = '\0';

        ldap_value_free( values );
        ldap_msgfree( res );

        *pmech = mech;

        return( LDAP_SUCCESS );
}
Example #17
0
int
LDAP_CALL
ldap_modify_ext( LDAP *ld, const char *dn, LDAPMod **mods,
    LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp )
{
	BerElement	*ber;
	int		i, rc, lderr;

	/*
	 * 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
	 *			}
	 *		}
	 *	}
	 */

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

	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
		return( LDAP_PARAM_ERROR );
	}
	if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp )) 
        {
		LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
		return( LDAP_PARAM_ERROR );
	}
        
	if ( !NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( mods )) {
		lderr = LDAP_PARAM_ERROR;
		LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
		return( lderr );
	}
	if ( dn == NULL ) {
		dn = "";
	}

	LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
	*msgidp = ++ld->ld_msgid;
	LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );

	/* see if we should add to the cache */
	if ( ld->ld_cache_on && ld->ld_cache_modify != NULL ) {
		LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
		if ( (rc = (ld->ld_cache_modify)( ld, *msgidp, LDAP_REQ_MODIFY,
		    dn, mods )) != 0 ) {
			*msgidp = rc;
			LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
			return( LDAP_SUCCESS );
		}
		LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
	}

	/* create a message to send */
	if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber ))
	    != LDAP_SUCCESS ) {
		return( lderr );
	}

	if ( ber_printf( ber, "{it{s{", *msgidp, LDAP_REQ_MODIFY, dn )
	    == -1 ) {
		lderr = LDAP_ENCODING_ERROR;
		LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
		ber_free( ber, 1 );
		return( lderr );
	}

	/* 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]}}",
			    mods[i]->mod_op & ~LDAP_MOD_BVALUES,
			    mods[i]->mod_type, mods[i]->mod_bvalues );
		} else {
			rc = ber_printf( ber, "{e{s[v]}}", mods[i]->mod_op,
			    mods[i]->mod_type, mods[i]->mod_values );
		}

		if ( rc == -1 ) {
			lderr = LDAP_ENCODING_ERROR;
			LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
			ber_free( ber, 1 );
			return( lderr );
		}
	}

	if ( ber_printf( ber, "}}" ) == -1 ) {
		lderr = LDAP_ENCODING_ERROR;
		LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
		ber_free( ber, 1 );
		return( lderr );
	}

	if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber ))
	    != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return( lderr );
	}

	/* send the message */
	rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_MODIFY,
		(char *)dn, ber );
	*msgidp = rc;
	return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
Example #18
0
/*
 * simple_bindifnot_s() is like ldap_simple_bind_s() except that it only does
 * a bind if the default connection is not currently bound.
 * If a successful bind using the same DN has already taken place we just
 * return LDAP_SUCCESS without conversing with the server at all.
 */
static int
simple_bindifnot_s( LDAP *ld, const char *dn, const char *passwd )
{
	int		msgid, rc;
	LDAPMessage	*result;
	char		*binddn;

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

	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
		return( LDAP_PARAM_ERROR );
	}

	if ( dn == NULL ) {
		dn = "";	/* to make comparisons simpler */
	}

	/*
	 * if we are already bound using the same DN, just return LDAP_SUCCESS.
	 */
	if ( NULL != ( binddn = nsldapi_get_binddn( ld ))
	    && 0 == strcmp( dn, binddn )) {
		rc = LDAP_SUCCESS;
		LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
		return rc;
	}

	/*
	 * if the default connection has been lost and is now marked dead,
	 * dispose of the default connection so it will get re-established.
	 *
	 * if not, clear the bind DN and status to ensure that we don't
	 * report the wrong bind DN to a different thread while waiting
	 * for our bind result to return from the server.
	 */
	LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
	if ( NULL != ld->ld_defconn ) {
	    if ( LDAP_CONNST_DEAD == ld->ld_defconn->lconn_status ) {
		nsldapi_free_connection( ld, ld->ld_defconn, NULL, NULL, 1, 0 );
		ld->ld_defconn = NULL;
	    } else if ( ld->ld_defconn->lconn_binddn != NULL ) {
		NSLDAPI_FREE( ld->ld_defconn->lconn_binddn );
		ld->ld_defconn->lconn_binddn = NULL;
		ld->ld_defconn->lconn_bound = 0;
	    }
	}
	LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );

	/*
	 * finally, bind (this will open a new connection if necessary)
	 *
	 * do everything under the protection of the result lock to
	 * ensure that only one thread will be in this code at a time.
	 * XXXmcs: we should use a condition variable instead?
	 */
	LDAP_MUTEX_LOCK( ld, LDAP_RESULT_LOCK );
	if ( (msgid = simple_bind_nolock( ld, dn, passwd, 0 )) == -1 ) {
		rc = LDAP_GET_LDERRNO( ld, NULL, NULL );
		goto unlock_and_return;
	}

	/*
	 * Note that at this point the bind request is on its way to the
	 * server and at any time now we will either be bound as the new
	 * DN (if the bind succeeded) or we will be bound as anonymous (if
	 * the bind failed).
	 */

	/*
	 * Wait for the bind result.  Code inside result.c:read1msg()
	 * takes care of setting the connection's bind DN and status.
	 */
	if ( nsldapi_result_nolock( ld, msgid, 1, 0, (struct timeval *) 0,
	    &result ) == -1 ) {
		rc = LDAP_GET_LDERRNO( ld, NULL, NULL );
		goto unlock_and_return;
	}

	rc = ldap_result2error( ld, result, 1 );

unlock_and_return:
	LDAP_MUTEX_UNLOCK( ld, LDAP_RESULT_LOCK );
	return( rc );
}