Exemplo n.º 1
0
int
LDAP_CALL
ldap_create_proxyauth_control (
     LDAP *ld, 
     const char *dn, 
     const char ctl_iscritical,
     LDAPControl **ctrlp   
)
{
	BerElement		*ber;
	int				rc;

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

	if (  ctrlp == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
		return ( LDAP_PARAM_ERROR );
	}
	if (NULL == dn)
	{
	    dn = "";
	}

	/* create a ber package to hold the controlValue */
	if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) ) != LDAP_SUCCESS ) {
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		return( LDAP_NO_MEMORY );
	}



        if ( LBER_ERROR == ber_printf( ber, 
                                       "{s}", 
                                       dn ) ) 
        {
            LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
            ber_free( ber, 1 );
            return( LDAP_ENCODING_ERROR );
        }

	rc = nsldapi_build_control( LDAP_CONTROL_PROXYAUTH, ber, 1,
	    ctl_iscritical, ctrlp );

	LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
	return( rc );

}
int
LDAP_CALL
ldap_create_geteffectiveRights_control (
     LDAP *ld, 
     const char *authzid,
	 const char **attrlist, 
     const char ctl_iscritical,
     LDAPControl **ctrlp   
)
{
	BerElement		*ber;
	int				rc;

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

	if (  ctrlp == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
		return ( LDAP_PARAM_ERROR );
	}
	if (NULL == authzid)
	{
	    authzid = "";
	}

	/* create a ber package to hold the controlValue */
	if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) ) != LDAP_SUCCESS ) {
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		return( LDAP_NO_MEMORY );
	}

	if ( LBER_ERROR == ber_printf( ber, "{s{v}}", authzid, attrlist ) ) {
        LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
        ber_free( ber, 1 );
        return( LDAP_ENCODING_ERROR );
    }

	rc = nsldapi_build_control( LDAP_CONTROL_GETEFFECTIVERIGHTS_REQUEST, ber, 1,
	    ctl_iscritical, ctrlp );

	LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
	return( rc );

}
Exemplo n.º 3
0
/* returns an LDAP error code */
static int
re_encode_request( LDAP *ld, BerElement *origber, int msgid, LDAPURLDesc *ludp,
    BerElement **berp )
{
/*
 * XXX this routine knows way too much about how the lber library works!
 */
	ber_uint_t		along;
	ber_tag_t		tag;
	ber_int_t		ver;
	int			rc;
	BerElement		*ber;
	struct berelement	tmpber;
	char			*dn, *orig_dn;

	LDAPDebug( LDAP_DEBUG_TRACE,
	    "re_encode_request: new msgid %d, new dn <%s>\n",
	    msgid, ( ludp->lud_dn == NULL ) ? "NONE" : ludp->lud_dn, 0 );

	tmpber = *origber;

	/*
	 * All LDAP requests are sequences that start with a message id.  For
	 * everything except delete requests, this is followed by a sequence
	 * that is tagged with the operation code.  For deletes, there is just
	 * a DN that is tagged with the operation code.
	 */

	/* skip past msgid and get operation tag */
	if ( ber_scanf( &tmpber, "{it", &along, &tag ) == LBER_ERROR ) {
		return( LDAP_DECODING_ERROR );
	}

	/*
	 * XXXmcs: we don't support scope or filters in search referrals yet,
	 * so if either were present we return an error which is probably
	 * better than just ignoring the extra info.
	 */
	if ( tag == LDAP_REQ_SEARCH &&
	    ( ludp->lud_scope != -1 || ludp->lud_filter != NULL )) {
		return( LDAP_LOCAL_ERROR );
	}

	if ( tag == LDAP_REQ_BIND ) {
		/* bind requests have a version number before the DN */
		rc = ber_scanf( &tmpber, "{ia", &ver, &orig_dn );
	} else if ( tag == LDAP_REQ_DELETE ) {
		/* delete requests DNs are not within a sequence */
		rc = ber_scanf( &tmpber, "a", &orig_dn );
	} else {
		rc = ber_scanf( &tmpber, "{a", &orig_dn );
	}

	if ( rc == LBER_ERROR ) {
		return( LDAP_DECODING_ERROR );
	}

	if ( ludp->lud_dn == NULL ) {
		dn = orig_dn;
	} else {
		dn = ludp->lud_dn;
		NSLDAPI_FREE( orig_dn );
		orig_dn = NULL;
	}

	/* allocate and build the new request */
        if (( rc = nsldapi_alloc_ber_with_options( ld, &ber ))
	    != LDAP_SUCCESS ) {
		if ( orig_dn != NULL ) {
			NSLDAPI_FREE( orig_dn );
		}
                return( rc );
        }

	if ( tag == LDAP_REQ_BIND ) {
		rc = ber_printf( ber, "{it{is", msgid, tag,
		    (int)ver /* XXX lossy cast */, dn );
	} else if ( tag == LDAP_REQ_DELETE ) {
		rc = ber_printf( ber, "{its}", msgid, tag, dn );
	} else {
		rc = ber_printf( ber, "{it{s", msgid, tag, dn );
	}

	if ( orig_dn != NULL ) {
		NSLDAPI_FREE( orig_dn );
	}
/*
 * can't use "dn" or "orig_dn" from this point on (they've been freed)
 */

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

	if ( tag != LDAP_REQ_DELETE &&
	    ( ber_write( ber, tmpber.ber_ptr, ( tmpber.ber_end -
	    tmpber.ber_ptr ), 0 ) != ( tmpber.ber_end - tmpber.ber_ptr )
	    || ber_printf( ber, "}}" ) == -1 )) {
		ber_free( ber, 1 );
		return( LDAP_ENCODING_ERROR );
	}

#ifdef LDAP_DEBUG
	if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
		LDAPDebug( LDAP_DEBUG_ANY, "re_encode_request new request is:\n",
		    0, 0, 0 );
		ber_dump( ber, 0 );
	}
#endif /* LDAP_DEBUG */

	*berp = ber;
	return( LDAP_SUCCESS );
}
Exemplo n.º 4
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 );
}
Exemplo n.º 5
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 );
}
Exemplo n.º 6
0
int
LDAP_CALL
ldap_create_sort_control ( 	
     LDAP *ld, 
     LDAPsortkey **sortKeyList,
     const char ctl_iscritical,
     LDAPControl **ctrlp   
)
{
	BerElement		*ber;
	int				i, rc;

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

	if ( sortKeyList == NULL || ctrlp == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
		return ( LDAP_PARAM_ERROR );
	}

	/* create a ber package to hold the controlValue */
	if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) ) != LDAP_SUCCESS ) {
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		return( LDAP_NO_MEMORY );
	}

	/* encode the start of the sequence of sequences into the ber */
	if ( ber_printf( ber, "{" ) == -1 ) {
		goto encoding_error_exit;
	}

	/* the sort control value will be encoded as a sequence of sequences
	   which are each encoded as one of the following: {s} or {sts} or {stb} or {ststb} 
	   since the orderingRule and reverseOrder flag are both optional */
	for ( i = 0; sortKeyList[i] != NULL; i++ ) {

		/* encode the attributeType into the ber */
		if ( ber_printf( ber, "{s", (sortKeyList[i])->sk_attrtype  )
		    == -1 ) {
			goto encoding_error_exit;
		}
		
		/* encode the optional orderingRule into the ber */
		if ( (sortKeyList[i])->sk_matchruleoid != NULL ) {
			if ( ber_printf( ber, "ts", LDAP_TAG_SK_MATCHRULE,
			    (sortKeyList[i])->sk_matchruleoid )
			    == -1 ) {
				goto encoding_error_exit;
			}
		} 

		/* Encode the optional reverseOrder flag into the ber. */
		/* If the flag is false, it should be absent. */
		if ( (sortKeyList[i])->sk_reverseorder ) {
			if ( ber_printf( ber, "tb}", LDAP_TAG_SK_REVERSE,
			    (sortKeyList[i])->sk_reverseorder ) == -1 ) {
				goto encoding_error_exit;
			}
		} else {
			if ( ber_printf( ber, "}" ) == -1 ) {
				goto encoding_error_exit;
			}
		}
	}

	/* encode the end of the sequence of sequences into the ber */
	if ( ber_printf( ber, "}" ) == -1 ) {
		goto encoding_error_exit;
	}

	rc = nsldapi_build_control( LDAP_CONTROL_SORTREQUEST, ber, 1,
	    ctl_iscritical, ctrlp );

	LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
	return( rc );

encoding_error_exit:
	LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
	ber_free( ber, 1 );
	return( LDAP_ENCODING_ERROR );
}
Exemplo n.º 7
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 );
}
Exemplo n.º 8
0
/*
 * Abandon all outstanding requests for msgid (included child requests
 * spawned when chasing referrals).  This function calls itself recursively.
 * No locking is done is this function so it must be done by the caller.
 * Returns an LDAP error code and sets it in LDAP *ld as well
 */
static int do_abandon(LDAP *ld, int origid, int msgid,
                      LDAPControl **serverctrls, LDAPControl **clientctrls) {
  BerElement *ber;
  int i, bererr, lderr, sendabandon;
  LDAPRequest *lr = NULL;

  /*
   * An abandon request looks like this:
   * AbandonRequest ::= MessageID
   */
  LDAPDebug(LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n", origid, msgid,
            0);

  /* optimistic */
  lderr = LDAP_SUCCESS;

  /*
   * Find the request that we are abandoning.  Don't send an
   * abandon message unless there is something to abandon.
   */
  sendabandon = 0;
  for (lr = ld->ld_requests; lr != NULL; lr = lr->lr_next) {
    if (lr->lr_msgid == msgid) { /* this message */
      if (origid == msgid && lr->lr_parent != NULL) {
        /* don't let caller abandon child requests! */
        lderr = LDAP_PARAM_ERROR;
        goto set_errorcode_and_return;
      }
      if (lr->lr_status == LDAP_REQST_INPROGRESS) {
        /*
         * We only need to send an abandon message if
         * the request is in progress.
         */
        sendabandon = 1;
      }
      break;
    }
    if (lr->lr_origid == msgid) { /* child:  abandon it */
      (void)do_abandon(ld, msgid, lr->lr_msgid, serverctrls, clientctrls);
      /* we ignore errors from child abandons... */
    }
  }

  if (ldap_msgdelete(ld, msgid) == 0) {
    /* we had all the results and deleted them */
    goto set_errorcode_and_return;
  }

  if (lr != NULL && sendabandon) {
    /* create a message to send */
    if ((lderr = nsldapi_alloc_ber_with_options(ld, &ber)) == LDAP_SUCCESS) {
      int abandon_msgid;

      LDAP_MUTEX_LOCK(ld, LDAP_MSGID_LOCK);
      abandon_msgid = ++ld->ld_msgid;
      LDAP_MUTEX_UNLOCK(ld, LDAP_MSGID_LOCK);
#ifdef CLDAP
      if (ld->ld_dbp->sb_naddr > 0) {
        bererr = ber_printf(ber, "{isti", abandon_msgid, ld->ld_cldapdn,
                            LDAP_REQ_ABANDON, msgid);
      } else {
#endif /* CLDAP */
        bererr =
            ber_printf(ber, "{iti", abandon_msgid, LDAP_REQ_ABANDON, msgid);
#ifdef CLDAP
      }
#endif /* CLDAP */

      if (bererr == -1 || (lderr = nsldapi_put_controls(ld, serverctrls, 1,
                                                        ber)) != LDAP_SUCCESS) {
        lderr = LDAP_ENCODING_ERROR;
        ber_free(ber, 1);
      } else {
        /* try to send the message */
        lderr =
            nsldapi_send_abandon_message(ld, lr->lr_conn, ber, abandon_msgid);
      }
    }
  }

  if (lr != NULL) {
    /*
     * Always call nsldapi_free_connection() so that the connection's
     * ref count is correctly decremented.  It is OK to always pass
     * 1 for the "unbind" parameter because doing so will only affect
     * connections that resulted from a child request (because the
     * default connection's ref count never goes to zero).
     */
    nsldapi_free_connection(ld, lr->lr_conn, NULL, NULL, 0 /* do not force */,
                            1 /* send unbind before closing */);

    /*
     * Free the entire request chain if we finished abandoning everything.
     */
    if (origid == msgid) {
      nsldapi_free_request(ld, lr, 0);
    }
  }

  /*
   * Record the abandoned message ID (used to discard any server responses
   * that arrive later).
   */
  LDAP_MUTEX_LOCK(ld, LDAP_ABANDON_LOCK);
  if (ld->ld_abandoned == NULL) {
    if ((ld->ld_abandoned = (int *)NSLDAPI_MALLOC(2 * sizeof(int))) == NULL) {
      lderr = LDAP_NO_MEMORY;
      LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);
      goto set_errorcode_and_return;
    }
    i = 0;
  } else {
    for (i = 0; ld->ld_abandoned[i] != -1; i++)
      ; /* NULL */
    if ((ld->ld_abandoned = (int *)NSLDAPI_REALLOC(
             (char *)ld->ld_abandoned, (i + 2) * sizeof(int))) == NULL) {
      lderr = LDAP_NO_MEMORY;
      LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);
      goto set_errorcode_and_return;
    }
  }
  ld->ld_abandoned[i] = msgid;
  ld->ld_abandoned[i + 1] = -1;
  LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);

set_errorcode_and_return:
  LDAP_SET_LDERRNO(ld, lderr, NULL, NULL);
  return (lderr);
}
Exemplo n.º 9
0
static int
simple_bind_nolock( LDAP *ld, const char *dn, const char *passwd,
    int unlock_permitted )
{
	BerElement	*ber;
	int		rc, msgid;

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

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

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

	if ( ld->ld_cache_on && ld->ld_cache_bind != NULL ) {
		struct berval	bv;

		bv.bv_val = (char *)passwd;
		bv.bv_len = strlen( passwd );
		/* if ( unlock_permitted ) LDAP_MUTEX_UNLOCK( ld ); */
		LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
		rc = (ld->ld_cache_bind)( ld, msgid, LDAP_REQ_BIND, dn, &bv,
		    LDAP_AUTH_SIMPLE );
		LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
		/* if ( unlock_permitted ) LDAP_MUTEX_LOCK( ld ); */
		if ( rc != 0 ) {
			return( rc );
		}
	}

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

	/* fill it in */
	if ( ber_printf( ber, "{it{ists}", msgid, LDAP_REQ_BIND,
	    NSLDAPI_LDAP_VERSION( ld ), dn, LDAP_AUTH_SIMPLE, passwd ) == -1 ) {
		LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
		ber_free( ber, 1 );
		return( -1 );
	}

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

	/* send the message */
	return( nsldapi_send_initial_request( ld, msgid, LDAP_REQ_BIND,
		(char *)dn, ber ));
}
Exemplo n.º 10
0
/* returns an LDAP error code and also sets it in ld */
int
nsldapi_build_search_req(
    LDAP		*ld, 
    const char		*base, 
    int			scope, 
    const char		*filter,
    char		**attrs, 
    int			attrsonly,
    LDAPControl		**serverctrls,
    LDAPControl		**clientctrls,	/* not used for anything yet */
    int			timelimit,	/* if -1, ld->ld_timelimit is used */
    int			sizelimit,	/* if -1, ld->ld_sizelimit is used */
    int			msgid,
    BerElement		**berp
)
{
	BerElement	*ber;
	int		err;
	char		*fdup;

	/*
	 * Create the search request.  It looks like this:
	 *	SearchRequest := [APPLICATION 3] SEQUENCE {
	 *		baseObject	DistinguishedName,
	 *		scope		ENUMERATED {
	 *			baseObject	(0),
	 *			singleLevel	(1),
	 *			wholeSubtree	(2)
	 *		},
	 *		derefAliases	ENUMERATED {
	 *			neverDerefaliases	(0),
	 *			derefInSearching	(1),
	 *			derefFindingBaseObj	(2),
	 *			alwaysDerefAliases	(3)
	 *		},
	 *		sizelimit	INTEGER (0 .. 65535),
	 *		timelimit	INTEGER (0 .. 65535),
	 *		attrsOnly	BOOLEAN,
	 *		filter		Filter,
	 *		attributes	SEQUENCE OF AttributeType
	 *	}
	 * wrapped in an ldap message.
	 */

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

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

	if ( sizelimit == -1 ) {
	    sizelimit = ld->ld_sizelimit;
	}

	if ( timelimit == -1 ) {
	    timelimit = ld->ld_timelimit;
	}

#ifdef CLDAP
	if ( ld->ld_sbp->sb_naddr > 0 ) {
	    err = ber_printf( ber, "{ist{seeiib", msgid,
		ld->ld_cldapdn, LDAP_REQ_SEARCH, base, scope, ld->ld_deref,
		sizelimit, timelimit, attrsonly );
	} else {
#endif /* CLDAP */
		err = ber_printf( ber, "{it{seeiib", msgid,
		    LDAP_REQ_SEARCH, base, scope, ld->ld_deref,
		    sizelimit, timelimit, attrsonly );
#ifdef CLDAP
	}
#endif /* CLDAP */

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

	fdup = nsldapi_strdup( filter );
	err = put_filter( ber, fdup );
	NSLDAPI_FREE( fdup );

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

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

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

	*berp = ber;
	return( LDAP_SUCCESS );
}