Beispiel #1
0
/* sets needed mutexes - no mutexes set to this point */
ber_int_t
ldap_send_initial_request(
	LDAP *ld,
	ber_tag_t msgtype,
	const char *dn,
	BerElement *ber,
	ber_int_t msgid)
{
	int rc = 1;
	ber_socket_t sd = AC_SOCKET_INVALID;

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

	LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
	if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd ) == -1 ) {
		/* not connected yet */
		rc = ldap_open_defconn( ld );

	}
	if ( ld->ld_defconn && ld->ld_defconn->lconn_status == LDAP_CONNST_CONNECTING )
		rc = ldap_int_check_async_open( ld, sd );
	if( rc < 0 ) {
		ber_free( ber, 1 );
		LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
		return( -1 );
	} else if ( rc == 0 ) {
		Debug( LDAP_DEBUG_TRACE,
			"ldap_open_defconn: successful\n",
			0, 0, 0 );
	}

#ifdef LDAP_CONNECTIONLESS
	if (LDAP_IS_UDP(ld)) {
		if (msgtype == LDAP_REQ_BIND) {
			LDAP_MUTEX_LOCK( &ld->ld_options.ldo_mutex );
			if (ld->ld_options.ldo_cldapdn)
				ldap_memfree(ld->ld_options.ldo_cldapdn);
			ld->ld_options.ldo_cldapdn = ldap_strdup(dn);
			ber_free( ber, 1 );
			LDAP_MUTEX_UNLOCK( &ld->ld_options.ldo_mutex );
			LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
			return 0;
		}
		if (msgtype != LDAP_REQ_ABANDON && msgtype != LDAP_REQ_SEARCH)
		{
			ber_free( ber, 1 );
			LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
			return LDAP_PARAM_ERROR;
		}
	}
#endif
	LDAP_MUTEX_LOCK( &ld->ld_req_mutex );
	rc = ldap_send_server_request( ld, ber, msgid, NULL,
		NULL, NULL, NULL, 0, 0 );
	LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );
	LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
	return(rc);
}
Beispiel #2
0
void
nsldapi_dump_requests_and_responses( LDAP *ld )
{
	LDAPRequest	*lr;
	LDAPMessage	*lm, *l;
	char        msg[256];

	ber_err_print( "** Outstanding Requests:\n" );
	LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
	if (( lr = ld->ld_requests ) == NULL ) {
		ber_err_print( "   Empty\n" );
	}
	for ( ; lr != NULL; lr = lr->lr_next ) {
	    sprintf( msg, " * msgid %d,  origid %d, status %s\n",
		lr->lr_msgid, lr->lr_origid, ( lr->lr_status ==
		LDAP_REQST_INPROGRESS ) ? "InProgress" :
		( lr->lr_status == LDAP_REQST_CHASINGREFS ) ? "ChasingRefs" :
		( lr->lr_status == LDAP_REQST_NOTCONNECTED ) ? "NotConnected" :
		( lr->lr_status == LDAP_REQST_CONNDEAD ) ? "Dead" :
		"Writing" );
	    ber_err_print( msg );
	    sprintf( msg, "   outstanding referrals %d, parent count %d\n",
		    lr->lr_outrefcnt, lr->lr_parentcnt );
	    ber_err_print( msg );
	    if ( lr->lr_binddn != NULL ) {
		    sprintf( msg, "   pending bind DN: <%s>\n", lr->lr_binddn );
		    ber_err_print( msg );
	    }
	}
	LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );

	ber_err_print( "** Response Queue:\n" );
	LDAP_MUTEX_LOCK( ld, LDAP_RESP_LOCK );
	if (( lm = ld->ld_responses ) == NULLMSG ) {
		ber_err_print( "   Empty\n" );
	}
	for ( ; lm != NULLMSG; lm = lm->lm_next ) {
		sprintf( msg, " * msgid %d,  type %d\n",
		    lm->lm_msgid, lm->lm_msgtype );
		ber_err_print( msg );
		if (( l = lm->lm_chain ) != NULL ) {
			ber_err_print( "   chained responses:\n" );
			for ( ; l != NULLMSG; l = l->lm_chain ) {
				sprintf( msg,
				    "  * msgid %d,  type %d\n",
				    l->lm_msgid, l->lm_msgtype );
				ber_err_print( msg );
			}
		}
	}
	LDAP_MUTEX_UNLOCK( ld, LDAP_RESP_LOCK );
}
Beispiel #3
0
void nsldapi_handle_reconnect( LDAP *ld )
{

	LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_handle_reconnect\n", 0, 0, 0 );
	
	/*
	 * 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 );
}
Beispiel #4
0
void
ldap_pvt_gettime( struct lutil_tm *ltm )
{
    struct timeval tv;
    static struct timeval prevTv;
    static int subs;

    struct tm tm;
    time_t t;

    gettimeofday( &tv, NULL );
    t = tv.tv_sec;

    LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
    if ( tv.tv_sec < prevTv.tv_sec
            || ( tv.tv_sec == prevTv.tv_sec && tv.tv_usec <= prevTv.tv_usec )) {
        subs++;
    } else {
        subs = 0;
        prevTv = tv;
    }
    LDAP_MUTEX_UNLOCK( &ldap_int_gettime_mutex );

    ltm->tm_usub = subs;

    ldap_pvt_gmtime( &t, &tm );

    ltm->tm_sec = tm.tm_sec;
    ltm->tm_min = tm.tm_min;
    ltm->tm_hour = tm.tm_hour;
    ltm->tm_mday = tm.tm_mday;
    ltm->tm_mon = tm.tm_mon;
    ltm->tm_year = tm.tm_year;
    ltm->tm_usec = tv.tv_usec;
}
int
ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
{
	int rc;
	LDAPConn *c;
	LDAPRequest *lr;
	LDAP	*ld;

	rc = ldap_create( &ld );
	if( rc != LDAP_SUCCESS ) {
		*ldp = NULL;
		return( rc );
	}

	/* Make it appear that a search request, msgid 0, was sent */
	lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ));
	if( lr == NULL ) {
		ldap_unbind_ext( ld, NULL, NULL );
		*ldp = NULL;
		return( LDAP_NO_MEMORY );
	}
	memset(lr, 0, sizeof( LDAPRequest ));
	lr->lr_msgid = 0;
	lr->lr_status = LDAP_REQST_INPROGRESS;
	lr->lr_res_errno = LDAP_SUCCESS;
	/* no mutex lock needed, we just created this ld here */
	ld->ld_requests = lr;

	LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
	/* Attach the passed socket as the *LDAP's connection */
	c = ldap_new_connection( ld, NULL, 1, 0, NULL, 0, 0 );
	if( c == NULL ) {
		ldap_unbind_ext( ld, NULL, NULL );
		*ldp = NULL;
		LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
		return( LDAP_NO_MEMORY );
	}
	ber_sockbuf_ctrl( c->lconn_sb, LBER_SB_OPT_SET_FD, fdp );
#ifdef LDAP_DEBUG
	ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_debug,
		LBER_SBIOD_LEVEL_PROVIDER, (void *)"int_" );
#endif
	ber_sockbuf_add_io( c->lconn_sb, &ber_sockbuf_io_tcp,
	  LBER_SBIOD_LEVEL_PROVIDER, NULL );
	ld->ld_defconn = c;
	LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );

	/* Add the connection to the *LDAP's select pool */
	ldap_mark_select_read( ld, c->lconn_sb );
	ldap_mark_select_write( ld, c->lconn_sb );

	/* Make this connection an LDAP V3 protocol connection */
	rc = LDAP_VERSION3;
	ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &rc );
	*ldp = ld;

	++ld->ld_defconn->lconn_refcnt;	/* so it never gets closed/freed */

	return( LDAP_SUCCESS );
}
Beispiel #6
0
LDAP *
ldap_open( LDAP_CONST char *host, int port )
{
	int rc;
	LDAP		*ld;

	Debug( LDAP_DEBUG_TRACE, "ldap_open(%s, %d)\n",
		host, port, 0 );

	ld = ldap_init( host, port );
	if ( ld == NULL ) {
		return( NULL );
	}

	LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
	rc = ldap_open_defconn( ld );
	LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );

	if( rc < 0 ) {
		ldap_ld_free( ld, 0, NULL, NULL );
		ld = NULL;
	}

	Debug( LDAP_DEBUG_TRACE, "ldap_open: %s\n",
		ld != NULL ? "succeeded" : "failed", 0, 0 );

	return ld;
}
Beispiel #7
0
static void
tlsg_ctx_ref( tls_ctx *ctx )
{
	tlsg_ctx *c = (tlsg_ctx *)ctx;
	LDAP_MUTEX_LOCK( &c->ref_mutex );
	c->refcount++;
	LDAP_MUTEX_UNLOCK( &c->ref_mutex );
}
Beispiel #8
0
int ldap_x_sasl_digest_md5_bind_s(
	LDAP *ld,
	char *user_name,
	struct berval *cred,
	LDAPControl **serverctrls,
	LDAPControl **clientctrls)
{
	struct berval	*challenge = NULL;
	int		errnum;
	char		*digest = NULL;
	struct berval	resp;

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

	/* Add debug */
	if (ld == NULL || user_name == NULL || cred == NULL ||
	    cred->bv_val == NULL)
		return (LDAP_PARAM_ERROR);

	if (ld->ld_version < LDAP_VERSION3)
		return (LDAP_PARAM_ERROR);

	errnum = ldap_sasl_bind_s(ld, NULL, LDAP_SASL_DIGEST_MD5,
		NULL, serverctrls, clientctrls, &challenge);

	if (errnum == LDAP_SASL_BIND_IN_PROGRESS) {
		if (challenge != NULL) {
			LDAPDebug(LDAP_DEBUG_TRACE,
				"SASL challenge: %s\n",
				challenge->bv_val, 0, 0);
			errnum = ldap_digest_md5_encode(challenge->bv_val,
				user_name, cred->bv_val, &digest);
			ber_bvfree(challenge);
			challenge = NULL;
			if (errnum == LDAP_SUCCESS) {
				resp.bv_val = digest;
				resp.bv_len = strlen(digest);
				LDAPDebug(LDAP_DEBUG_TRACE,
					"SASL reply: %s\n",
					digest, 0, 0);
				errnum = ldap_sasl_bind_s(ld, NULL,
					LDAP_SASL_DIGEST_MD5, &resp,
					serverctrls, clientctrls, &challenge);
				free(digest);
			}
			if (challenge != NULL)
				ber_bvfree(challenge);
		} else {
			errnum = LDAP_NO_MEMORY; /* TO DO: What val? */
		}
	}

	LDAP_MUTEX_LOCK(ld, LDAP_ERR_LOCK);
	ld->ld_errno = errnum;
	LDAP_MUTEX_UNLOCK(ld, LDAP_ERR_LOCK);
	return (errnum);
}
Beispiel #9
0
/*
 * initialize the default context
 */
int
ldap_pvt_tls_init_def_ctx( int is_server )
{
	struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   
	int rc;
	LDAP_MUTEX_LOCK( &tls_def_ctx_mutex );
	rc = ldap_int_tls_init_ctx( lo, is_server );
	LDAP_MUTEX_UNLOCK( &tls_def_ctx_mutex );
	return rc;
}
Beispiel #10
0
/*
 * ldap_abandoned
 *
 * return the location of the message id in the array of abandoned
 * message ids, or -1
 */
static int
ldap_abandoned( LDAP *ld, ber_int_t msgid )
{
	int	ret, idx;
	assert( msgid >= 0 );

	LDAP_MUTEX_LOCK( &ld->ld_abandon_mutex );
	ret = ldap_int_bisect_find( ld->ld_abandoned, ld->ld_nabandoned, msgid, &idx );
	LDAP_MUTEX_UNLOCK( &ld->ld_abandon_mutex );
	return ret;
}
Beispiel #11
0
int
ldap_pvt_discard(
    LDAP *ld,
    ber_int_t msgid )
{
    int	rc;

    LDAP_MUTEX_LOCK( &ld->ld_req_mutex );
    rc = do_abandon( ld, msgid, msgid, NULL, 0 );
    LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );
    return rc;
}
Beispiel #12
0
/*
 * ldap_connect - Connect to an ldap server.
 *
 * Example:
 *	LDAP	*ld;
 *	ldap_initialize( &ld, url );
 *	ldap_connect( ld );
 */
int
ldap_connect( LDAP *ld )
{
	ber_socket_t sd = AC_SOCKET_INVALID;
	int rc = LDAP_SUCCESS;

	LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
	if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, &sd ) == -1 ) {
		rc = ldap_open_defconn( ld );
	}
	LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );

	return rc;
}
Beispiel #13
0
/*
 * LDAPv3 extended abandon.
 * Returns an LDAP error code.
 */
int LDAP_CALL ldap_abandon_ext(LDAP *ld, int msgid, LDAPControl **serverctrls,
                               LDAPControl **clientctrls) {
  int rc;

  LDAPDebug(LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0);

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

  LDAP_MUTEX_LOCK(ld, LDAP_CONN_LOCK);
  LDAP_MUTEX_LOCK(ld, LDAP_REQ_LOCK);
  rc = do_abandon(ld, msgid, msgid, serverctrls, clientctrls);

  /*
   * XXXmcs should use cache function pointers to hook in memcache
   */
  ldap_memcache_abandon(ld, msgid);

  LDAP_MUTEX_UNLOCK(ld, LDAP_REQ_LOCK);
  LDAP_MUTEX_UNLOCK(ld, LDAP_CONN_LOCK);

  return (rc);
}
Beispiel #14
0
/* returns the message id of the request or -1 if an error occurs */
int
nsldapi_send_initial_request( LDAP *ld, int msgid, unsigned long msgtype,
	char *dn, BerElement *ber )
{
	LDAPServer	*servers;
	
	LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_send_initial_request\n", 0,0,0 );

#ifdef LDAP_DNS
	LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
	if (( ld->ld_options & LDAP_BITOPT_DNS ) != 0 && ldap_is_dns_dn( dn )) {
		if (( servers = dn2servers( ld, dn )) == NULL ) {
			ber_free( ber, 1 );
			LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
			return( -1 );
		}

#ifdef LDAP_DEBUG
		if ( ldap_debug & LDAP_DEBUG_TRACE ) {
			LDAPServer	*srv;
			char    msg[256];

			for ( srv = servers; srv != NULL;
			    srv = srv->lsrv_next ) {
				sprintf( msg,
				    "LDAP server %s:  dn %s, port %d\n",
				    srv->lsrv_host, ( srv->lsrv_dn == NULL ) ?
				    "(default)" : srv->lsrv_dn,
				    srv->lsrv_port );
				ber_err_print( msg );
			}
		}
#endif /* LDAP_DEBUG */
	} else {
#endif /* LDAP_DNS */
		/*
		 * use of DNS is turned off or this is an LDAP DN...
		 * use our default connection
		 */
		servers = NULL;
#ifdef LDAP_DNS
	}	
	LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
#endif /* LDAP_DNS */

	return( nsldapi_send_server_request( ld, ber, msgid, NULL,
	    servers, NULL, ( msgtype == LDAP_REQ_BIND ) ? dn : NULL, 0 ));
}
Beispiel #15
0
struct tm *
ldap_pvt_localtime( const time_t *timep, struct tm *result )
{
    struct tm *tm_ptr;

    LDAP_MUTEX_LOCK( &ldap_int_gmtime_mutex );
    tm_ptr = localtime( timep );
    if ( tm_ptr == NULL ) {
        result = NULL;

    } else {
        *result = *tm_ptr;
    }
    LDAP_MUTEX_UNLOCK( &ldap_int_gmtime_mutex );

    return result;
}
Beispiel #16
0
void
ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
{
	LDAPConn	*lc;
   	char		timebuf[32];

	Debug( LDAP_DEBUG_TRACE, "** ld %p Connection%s:\n", (void *)ld, all ? "s" : "", 0 );
	LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
	for ( lc = lconns; lc != NULL; lc = lc->lconn_next ) {
		if ( lc->lconn_server != NULL ) {
			Debug( LDAP_DEBUG_TRACE, "* host: %s  port: %d%s\n",
				( lc->lconn_server->lud_host == NULL ) ? "(null)"
				: lc->lconn_server->lud_host,
				lc->lconn_server->lud_port, ( lc->lconn_sb ==
				ld->ld_sb ) ? "  (default)" : "" );
		}
		Debug( LDAP_DEBUG_TRACE, "  refcnt: %d  status: %s\n", lc->lconn_refcnt,
			( lc->lconn_status == LDAP_CONNST_NEEDSOCKET )
				? "NeedSocket" :
				( lc->lconn_status == LDAP_CONNST_CONNECTING )
					? "Connecting" : "Connected", 0 );
		Debug( LDAP_DEBUG_TRACE, "  last used: %s%s\n",
			ldap_pvt_ctime( &lc->lconn_lastused, timebuf ),
			lc->lconn_rebind_inprogress ? "  rebind in progress" : "", 0 );
		if ( lc->lconn_rebind_inprogress ) {
			if ( lc->lconn_rebind_queue != NULL) {
				int	i;

				for ( i = 0; lc->lconn_rebind_queue[i] != NULL; i++ ) {
					int	j;
					for( j = 0; lc->lconn_rebind_queue[i][j] != 0; j++ ) {
						Debug( LDAP_DEBUG_TRACE, "    queue %d entry %d - %s\n",
							i, j, lc->lconn_rebind_queue[i][j] );
					}
				}
			} else {
				Debug( LDAP_DEBUG_TRACE, "    queue is empty\n", 0, 0, 0 );
			}
		}
		Debug( LDAP_DEBUG_TRACE, "\n", 0, 0, 0 );
		if ( !all ) {
			break;
		}
	}
	LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
}
Beispiel #17
0
/*
 * ldap_msgdelete - delete a message.  It returns:
 *	0	if the entire message was deleted
 *	-1	if the message was not found, or only part of it was found
 */
int
ldap_msgdelete( LDAP *ld, int msgid )
{
	LDAPMessage	*lm, *prev;
	int		rc = 0;

	assert( ld != NULL );

	Debug( LDAP_DEBUG_TRACE, "ldap_msgdelete ld=%p msgid=%d\n",
		(void *)ld, msgid, 0 );

	LDAP_MUTEX_LOCK( &ld->ld_res_mutex );
	prev = NULL;
	for ( lm = ld->ld_responses; lm != NULL; lm = lm->lm_next ) {
		if ( lm->lm_msgid == msgid ) {
			break;
		}
		prev = lm;
	}

	if ( lm == NULL ) {
		rc = -1;

	} else {
		if ( prev == NULL ) {
			ld->ld_responses = lm->lm_next;
		} else {
			prev->lm_next = lm->lm_next;
		}
	}
	LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex );
	if ( lm ) {
		switch ( ldap_msgfree( lm ) ) {
		case LDAP_RES_SEARCH_ENTRY:
		case LDAP_RES_SEARCH_REFERENCE:
		case LDAP_RES_INTERMEDIATE:
			rc = -1;
			break;

		default:
			break;
		}
	}

	return rc;
}
Beispiel #18
0
/*
 * return a pointer to the bind DN for the default connection (a copy is
 * not made).  If there is no bind DN available, NULL is returned.
 */
char *
nsldapi_get_binddn( LDAP *ld )
{
    char	*binddn;

    binddn = NULL;	/* default -- assume they are not bound */

    LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
    if ( NULL != ld->ld_defconn && LDAP_CONNST_CONNECTED ==
            ld->ld_defconn->lconn_status && ld->ld_defconn->lconn_bound ) {
        if (( binddn = ld->ld_defconn->lconn_binddn ) == NULL ) {
            binddn = "";
        }
    }
    LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );

    return( binddn );
}
Beispiel #19
0
/*
 * ldap_mark_abandoned
 */
static int
ldap_mark_abandoned( LDAP *ld, ber_int_t msgid )
{
	int	ret, idx;

	assert( msgid >= 0 );
	LDAP_MUTEX_LOCK( &ld->ld_abandon_mutex );
	ret = ldap_int_bisect_find( ld->ld_abandoned, ld->ld_nabandoned, msgid, &idx );
	if (ret <= 0) {		/* error or already deleted by another thread */
		LDAP_MUTEX_UNLOCK( &ld->ld_abandon_mutex );
		return ret;
	}
	/* still in abandoned array, so delete */
	ret = ldap_int_bisect_delete( &ld->ld_abandoned, &ld->ld_nabandoned,
		msgid, idx );
	LDAP_MUTEX_UNLOCK( &ld->ld_abandon_mutex );
	return ret;
}
Beispiel #20
0
/*
 * ldap_sasl_interactive_bind_ext_s
 *
 * This function extends ldap_sasl_interactive_bind_s by allowing
 * controls received from the server to be returned as rctrl. The
 * caller must pass in a valid LDAPControl** pointer and free the
 * array of controls when finished with them e.g.
 * LDAPControl **retctrls = NULL;
 * ...
 * ldap_sasl_interactive_bind_ext_s(ld, ...., &retctrls);
 * ...
 * ldap_controls_free(retctrls);
 * Only the controls from the server during the last bind step are returned -
 * intermediate controls (if any, usually not) are discarded.
 */
int
LDAP_CALL
ldap_sasl_interactive_bind_ext_s( LDAP *ld, const char *dn,
        const char *saslMechanism,
        LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
        LDAP_SASL_INTERACT_PROC *callback, void *defaults, LDAPControl ***rctrl )
{
#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
        char *smechs;
#endif
        int rc;

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

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

        if ((flags == LDAP_SASL_INTERACTIVE) && (callback == NULL)) {
                return( LDAP_PARAM_ERROR );
        }

        LDAP_MUTEX_LOCK(ld, LDAP_SASL_LOCK );

        if( saslMechanism == NULL || *saslMechanism == '\0' ) {
#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
                rc = nsldapi_get_sasl_mechs( ld, &smechs );
                if( rc != LDAP_SUCCESS ) {
                        LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
                        return( rc );
                }
                saslMechanism = smechs;
#else
                LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
                return( LDAP_PARAM_ERROR );
#endif /* LDAP_SASLIO_GET_MECHS_FROM_SERVER */
        }

        rc = nsldapi_sasl_do_bind( ld, dn, saslMechanism,
                        flags, callback, defaults, sctrl, cctrl, rctrl);

        LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
        return( rc );
}
Beispiel #21
0
static void
tlsg_ctx_free ( tls_ctx *ctx )
{
	tlsg_ctx *c = (tlsg_ctx *)ctx;
	int refcount;

	if ( !c ) return;

	LDAP_MUTEX_LOCK( &c->ref_mutex );
	refcount = --c->refcount;
	LDAP_MUTEX_UNLOCK( &c->ref_mutex );
	if ( refcount )
		return;
	gnutls_priority_deinit( c->prios );
	gnutls_certificate_free_credentials( c->cred );
	if ( c->dh_params )
		gnutls_dh_params_deinit( c->dh_params );
	ber_memfree ( c );
}
Beispiel #22
0
/* returns an LDAP error code and also sets error inside LDAP * */
int
nsldapi_alloc_ber_with_options( LDAP *ld, BerElement **berp )
{
	int	err;

	LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
    	if (( *berp = ber_alloc_t( ld->ld_lberoptions )) == NULLBER ) {
		err = LDAP_NO_MEMORY;
		LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	} else {
		err = LDAP_SUCCESS;
#ifdef STR_TRANSLATION
		nsldapi_set_ber_options( ld, *berp );
#endif /* STR_TRANSLATION */
	}
	LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );

	return( err );
}
Beispiel #23
0
void
LDAP_CALL
ldap_set_rebind_proc( LDAP *ld, LDAP_REBINDPROC_CALLBACK *rebindproc,
                      void *arg )
{
    if ( ld == NULL ) {
        if ( !nsldapi_initialized ) {
            nsldapi_initialize_defaults();
        }
        ld = &nsldapi_ld_defaults;
    }

    if ( NSLDAPI_VALID_LDAP_POINTER( ld )) {
        LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
        ld->ld_rebind_fn = rebindproc;
        ld->ld_rebind_arg = arg;
        LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
    }
}
Beispiel #24
0
static void
tlsg_ctx_free ( tls_ctx *ctx )
{
	tlsg_ctx *c = (tlsg_ctx *)ctx;
	int refcount;

	if ( !c ) return;

	LDAP_MUTEX_LOCK( &c->ref_mutex );
	refcount = --c->refcount;
	LDAP_MUTEX_UNLOCK( &c->ref_mutex );
	if ( refcount )
		return;
#ifdef HAVE_CIPHERSUITES
	gnutls_priority_deinit( c->prios );
#else
	LDAP_FREE( c->kx_list );
#endif
	gnutls_certificate_free_credentials( c->cred );
	ber_memfree ( c );
}
Beispiel #25
0
LDAP *
ldap_dup( LDAP *old )
{
	LDAP			*ld;

	if ( old == NULL ) {
		return( NULL );
	}

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

	if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
		return( NULL );
	}
   
	LDAP_MUTEX_LOCK( &old->ld_ldcmutex );
	ld->ldc = old->ldc;
	old->ld_ldcrefcnt++;
	LDAP_MUTEX_UNLOCK( &old->ld_ldcmutex );
	return ( ld );
}
Beispiel #26
0
char *ldap_pvt_ctime( const time_t *tp, char *buf )
{
#ifdef USE_CTIME_R
# if (CTIME_R_NARGS > 3) || (CTIME_R_NARGS < 2)
#	error "CTIME_R_NARGS should be 2 or 3"
# elif CTIME_R_NARGS > 2 && defined(CTIME_R_RETURNS_INT)
    return( ctime_r(tp,buf,26) < 0 ? 0 : buf );
# elif CTIME_R_NARGS > 2
    return ctime_r(tp,buf,26);
# else
    return ctime_r(tp,buf);
# endif

#else

    LDAP_MUTEX_LOCK( &ldap_int_ctime_mutex );
    AC_MEMCPY( buf, ctime(tp), 26 );
    LDAP_MUTEX_UNLOCK( &ldap_int_ctime_mutex );

    return buf;
#endif
}
Beispiel #27
0
LDAP *LDAP_CALL ldap_open(const char *host, int port) {
  LDAP *ld;

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

  if ((ld = ldap_init(host, port)) == NULL) {
    return (NULL);
  }

  LDAP_MUTEX_LOCK(ld, LDAP_CONN_LOCK);
  if (nsldapi_open_ldap_defconn(ld) < 0) {
    LDAP_MUTEX_UNLOCK(ld, LDAP_CONN_LOCK);
    ldap_ld_free(ld, NULL, NULL, 0);
    return (NULL);
  }

  LDAP_MUTEX_UNLOCK(ld, LDAP_CONN_LOCK);
  LDAPDebug(LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n",
            (ld->ld_host == NULL) ? "(null)" : ld->ld_host, 0, 0);

  return (ld);
}
Beispiel #28
0
/*
 * ldap_abandon_ext - perform an ldap extended abandon operation.
 *
 * Parameters:
 *	ld			LDAP descriptor
 *	msgid		The message id of the operation to abandon
 *	scntrls		Server Controls
 *	ccntrls		Client Controls
 *
 * ldap_abandon_ext returns a LDAP error code.
 *		(LDAP_SUCCESS if everything went ok)
 *
 * Example:
 *	ldap_abandon_ext( ld, msgid, scntrls, ccntrls );
 */
int
ldap_abandon_ext(
    LDAP *ld,
    int msgid,
    LDAPControl **sctrls,
    LDAPControl **cctrls )
{
    int	rc;

    Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );

    /* check client controls */
    LDAP_MUTEX_LOCK( &ld->ld_req_mutex );

    rc = ldap_int_client_controls( ld, cctrls );
    if ( rc == LDAP_SUCCESS ) {
        rc = do_abandon( ld, msgid, msgid, sctrls, 1 );
    }

    LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );

    return rc;
}
Beispiel #29
0
/*
 * ldap_result - wait for an ldap result response to a message from the
 * ldap server.  If msgid is LDAP_RES_ANY (-1), any message will be
 * accepted.  If msgid is LDAP_RES_UNSOLICITED (0), any unsolicited
 * message is accepted.  Otherwise ldap_result will wait for a response
 * with msgid.  If all is LDAP_MSG_ONE (0) the first message with id
 * msgid will be accepted, otherwise, ldap_result will wait for all
 * responses with id msgid and then return a pointer to the entire list
 * of messages.  In general, this is only useful for search responses,
 * which can be of three message types (zero or more entries, zero or
 * search references, followed by an ldap result).  An extension to
 * LDAPv3 allows partial extended responses to be returned in response
 * to any request.  The type of the first message received is returned.
 * When waiting, any messages that have been abandoned/discarded are 
 * discarded.
 *
 * Example:
 *	ldap_result( s, msgid, all, timeout, result )
 */
int
ldap_result(
	LDAP *ld,
	int msgid,
	int all,
	struct timeval *timeout,
	LDAPMessage **result )
{
	int		rc;

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

	Debug( LDAP_DEBUG_TRACE, "ldap_result ld %p msgid %d\n", (void *)ld, msgid, 0 );

	if (ld->ld_errno == LDAP_LOCAL_ERROR || ld->ld_errno == LDAP_SERVER_DOWN)
		return -1;

	LDAP_MUTEX_LOCK( &ld->ld_res_mutex );
	rc = wait4msg( ld, msgid, all, timeout, result );
	LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex );

	return rc;
}
Beispiel #30
0
int
ldap_ld_free(
	LDAP *ld,
	int close,
	LDAPControl **sctrls,
	LDAPControl **cctrls )
{
	LDAPMessage	*lm, *next;
	int		err = LDAP_SUCCESS;

	LDAP_MUTEX_LOCK( &ld->ld_ldcmutex );
	/* Someone else is still using this ld. */
	if (ld->ld_ldcrefcnt > 1) {	/* but not last thread */
		/* clean up self only */
		ld->ld_ldcrefcnt--;
		if ( ld->ld_error != NULL ) {
			LDAP_FREE( ld->ld_error );
			ld->ld_error = NULL;
		}

		if ( ld->ld_matched != NULL ) {
			LDAP_FREE( ld->ld_matched );
			ld->ld_matched = NULL;
		}
		if ( ld->ld_referrals != NULL) {
			LDAP_VFREE(ld->ld_referrals);
			ld->ld_referrals = NULL;
		}  
		LDAP_MUTEX_UNLOCK( &ld->ld_ldcmutex );
		LDAP_FREE( (char *) ld );
		return( err );
	}

	/* This ld is the last thread. */

	/* free LDAP structure and outstanding requests/responses */
	LDAP_MUTEX_LOCK( &ld->ld_req_mutex );
	while ( ld->ld_requests != NULL ) {
		ldap_free_request( ld, ld->ld_requests );
	}
	LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );
	LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );

	/* free and unbind from all open connections */
	while ( ld->ld_conns != NULL ) {
		ldap_free_connection( ld, ld->ld_conns, 1, close );
	}
	LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
	LDAP_MUTEX_LOCK( &ld->ld_res_mutex );
	for ( lm = ld->ld_responses; lm != NULL; lm = next ) {
		next = lm->lm_next;
		ldap_msgfree( lm );
	}
    
	if ( ld->ld_abandoned != NULL ) {
		LDAP_FREE( ld->ld_abandoned );
		ld->ld_abandoned = NULL;
	}
	LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex );
	LDAP_MUTEX_LOCK( &ld->ld_ldopts_mutex );

	/* final close callbacks */
	{
		ldaplist *ll, *next;

		for ( ll = ld->ld_options.ldo_conn_cbs; ll; ll = next ) {
			ldap_conncb *cb = ll->ll_data;
			next = ll->ll_next;
			cb->lc_del( ld, NULL, cb );
			LDAP_FREE( ll );
		}
	}

	if ( ld->ld_error != NULL ) {
		LDAP_FREE( ld->ld_error );
		ld->ld_error = NULL;
	}

	if ( ld->ld_matched != NULL ) {
		LDAP_FREE( ld->ld_matched );
		ld->ld_matched = NULL;
	}

	if ( ld->ld_referrals != NULL) {
		LDAP_VFREE(ld->ld_referrals);
		ld->ld_referrals = NULL;
	}  
    
	if ( ld->ld_selectinfo != NULL ) {
		ldap_free_select_info( ld->ld_selectinfo );
		ld->ld_selectinfo = NULL;
	}

	if ( ld->ld_options.ldo_defludp != NULL ) {
		ldap_free_urllist( ld->ld_options.ldo_defludp );
		ld->ld_options.ldo_defludp = NULL;
	}

#ifdef LDAP_CONNECTIONLESS
	if ( ld->ld_options.ldo_peer != NULL ) {
		LDAP_FREE( ld->ld_options.ldo_peer );
		ld->ld_options.ldo_peer = NULL;
	}

	if ( ld->ld_options.ldo_cldapdn != NULL ) {
		LDAP_FREE( ld->ld_options.ldo_cldapdn );
		ld->ld_options.ldo_cldapdn = NULL;
	}
#endif

#ifdef HAVE_CYRUS_SASL
	if ( ld->ld_options.ldo_def_sasl_mech != NULL ) {
		LDAP_FREE( ld->ld_options.ldo_def_sasl_mech );
		ld->ld_options.ldo_def_sasl_mech = NULL;
	}

	if ( ld->ld_options.ldo_def_sasl_realm != NULL ) {
		LDAP_FREE( ld->ld_options.ldo_def_sasl_realm );
		ld->ld_options.ldo_def_sasl_realm = NULL;
	}

	if ( ld->ld_options.ldo_def_sasl_authcid != NULL ) {
		LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid );
		ld->ld_options.ldo_def_sasl_authcid = NULL;
	}

	if ( ld->ld_options.ldo_def_sasl_authzid != NULL ) {
		LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid );
		ld->ld_options.ldo_def_sasl_authzid = NULL;
	}
#endif

#ifdef HAVE_TLS
	ldap_int_tls_destroy( &ld->ld_options );
#endif

	if ( ld->ld_options.ldo_sctrls != NULL ) {
		ldap_controls_free( ld->ld_options.ldo_sctrls );
		ld->ld_options.ldo_sctrls = NULL;
	}

	if ( ld->ld_options.ldo_cctrls != NULL ) {
		ldap_controls_free( ld->ld_options.ldo_cctrls );
		ld->ld_options.ldo_cctrls = NULL;
	}
	LDAP_MUTEX_UNLOCK( &ld->ld_ldopts_mutex );

	ber_sockbuf_free( ld->ld_sb );   
   
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_destroy( &ld->ld_msgid_mutex );
	ldap_pvt_thread_mutex_destroy( &ld->ld_conn_mutex );
	ldap_pvt_thread_mutex_destroy( &ld->ld_req_mutex );
	ldap_pvt_thread_mutex_destroy( &ld->ld_res_mutex );
	ldap_pvt_thread_mutex_destroy( &ld->ld_abandon_mutex );
	ldap_pvt_thread_mutex_destroy( &ld->ld_ldopts_mutex );
	ldap_pvt_thread_mutex_unlock( &ld->ld_ldcmutex );
	ldap_pvt_thread_mutex_destroy( &ld->ld_ldcmutex );
#endif
#ifndef NDEBUG
	LDAP_TRASH(ld);
#endif
	LDAP_FREE( (char *) ld->ldc );
	LDAP_FREE( (char *) ld );
   
	return( err );
}