Esempio n. 1
0
/*
 * Pull the oid returned by the server and the data out of an extended
 * operation result.  Return an LDAP error code.
 */
int LDAP_CALL ldap_parse_extended_result(
    LDAP *ld, LDAPMessage *res, char **retoidp, /* may be NULL */
    struct berval **retdatap,                   /* may be NULL */
    int freeit) {
  struct berelement ber;
  ber_len_t len;
  ber_int_t err;
  char *m, *e, *roid;
  struct berval *rdata;

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

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

  if (!NSLDAPI_VALID_LDAPMESSAGE_EXRESULT_POINTER(res)) {
    return (LDAP_PARAM_ERROR);
  }

  m = e = NULL;
  ber = *(res->lm_ber);
  if (NSLDAPI_LDAP_VERSION(ld) < LDAP_VERSION3) {
    LDAP_SET_LDERRNO(ld, LDAP_NOT_SUPPORTED, NULL, NULL);
    return (LDAP_NOT_SUPPORTED);
  }

  if (ber_scanf(&ber, "{iaa", &err, &m, &e) == LBER_ERROR) {
    goto decoding_error;
  }
  roid = NULL;
  if (ber_peek_tag(&ber, &len) == LDAP_TAG_EXOP_RES_OID) {
    if (ber_scanf(&ber, "a", &roid) == LBER_ERROR) {
      goto decoding_error;
    }
  }
  if (retoidp != NULL) {
    *retoidp = roid;
  } else if (roid != NULL) {
    NSLDAPI_FREE(roid);
  }

  rdata = NULL;
  if (ber_peek_tag(&ber, &len) == LDAP_TAG_EXOP_RES_VALUE) {
    if (ber_scanf(&ber, "O", &rdata) == LBER_ERROR) {
      goto decoding_error;
    }
  }
  if (retdatap != NULL) {
    *retdatap = rdata;
  } else if (rdata != NULL) {
    ber_bvfree(rdata);
  }

  LDAP_SET_LDERRNO(ld, err, m, e);

  if (freeit) {
    ldap_msgfree(res);
  }

  return (LDAP_SUCCESS);

decoding_error:;
  LDAP_SET_LDERRNO(ld, LDAP_DECODING_ERROR, NULL, NULL);
  return (LDAP_DECODING_ERROR);
}
Esempio n. 2
0
int
LDAP_CALL
ldap_parse_sort_control ( 	
     LDAP *ld, 
     LDAPControl **ctrlp,  
     unsigned long *result,
     char **attribute
)
{
	BerElement *ber;
	int i, foundSortControl;
	LDAPControl *sortCtrlp;
	unsigned long len, tag;
	char *attr;

	if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || result == NULL ||
		attribute == NULL ) {
	    return( LDAP_PARAM_ERROR );
	}


	/* find the sortControl in the list of controls if it exists */
	if ( ctrlp == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
		return ( LDAP_CONTROL_NOT_FOUND );
	} 
	foundSortControl = 0;
	for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundSortControl )); i++ ) {
		foundSortControl = !strcmp( ctrlp[i]->ldctl_oid, LDAP_CONTROL_SORTRESPONSE );
	}
	if ( !foundSortControl ) {
		LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
		return ( LDAP_CONTROL_NOT_FOUND );
	} else {
		/* let local var point to the sortControl */
		sortCtrlp = ctrlp[i-1];			
	}

	/*  allocate a Ber element with the contents of the sort_control's struct berval */
	if ( ( ber = ber_init( &sortCtrlp->ldctl_value ) ) == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		return( LDAP_NO_MEMORY );
	}		

	/* decode the result from the Berelement */
	if ( ber_scanf( ber, "{i", result ) == LBER_ERROR ) {
		LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
		ber_free( ber, 1 );
		return( LDAP_DECODING_ERROR );
	}

	/* if the server returned one, decode the attribute from the Ber element */
	if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SR_ATTRTYPE ) {
		if ( ber_scanf( ber, "ta", &tag, &attr ) == LBER_ERROR ) {
			LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
			ber_free( ber, 1 );
			return( LDAP_DECODING_ERROR );
		}
		*attribute = attr;		  
	} else {
		*attribute = NULL;
	}

	if ( ber_scanf( ber, "}" ) == LBER_ERROR ) {
		LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
		ber_free( ber, 1 );
		return( LDAP_DECODING_ERROR );
	}

	/* the ber encoding is no longer needed */
	ber_free(ber,1);

	return( LDAP_SUCCESS );
}
Esempio n. 3
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 );
}
Esempio n. 4
0
/* returns an LDAP error code that indicates if parse succeeded or not */
int
LDAP_CALL
ldap_parse_sasl_bind_result(
    LDAP		*ld,
    LDAPMessage		*res,
    struct berval	**servercredp,
    int			freeit
)
{
	BerElement	ber;
	int		rc, err;
    ber_int_t	along;
	ber_len_t	len;
	char		*m, *e;

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

	/*
	 * the ldapv3 SASL bind response looks like this:
	 *
	 *	BindResponse ::= [APPLICATION 1] SEQUENCE {
	 *		COMPONENTS OF LDAPResult,
	 *		serverSaslCreds [7] OCTET STRING OPTIONAL
	 *	}
	 *
	 * all wrapped up in an LDAPMessage sequence.
	 */

	if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ||
	    !NSLDAPI_VALID_LDAPMESSAGE_BINDRESULT_POINTER( res )) {
		return( LDAP_PARAM_ERROR );
	}

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

	if ( servercredp != NULL ) {
		*servercredp = NULL;
	}

	ber = *(res->lm_ber);	/* struct copy */

	/* skip past message id, matched dn, error message ... */
	rc = ber_scanf( &ber, "{iaa}", &along, &m, &e );

	if ( rc != LBER_ERROR &&
	    ber_peek_tag( &ber, &len ) == LDAP_TAG_SASL_RES_CREDS ) {
		rc = ber_get_stringal( &ber, servercredp );
	}

	if ( freeit ) {
		ldap_msgfree( res );
	}

	if ( rc == LBER_ERROR ) {
		err = LDAP_DECODING_ERROR;
	} else {
		err = (int) along;
	}

	LDAP_SET_LDERRNO( ld, err, m, e );
	/* this is a little kludge for the 3.0 Barracuda/hammerhead relese */
	/* the docs state that the return is either LDAP_DECODING_ERROR */
	/* or LDAP_SUCCESS.  Here we match the docs...  it's cleaner in 3.1 */

	if ( LDAP_DECODING_ERROR == err ) {
		return (LDAP_DECODING_ERROR);
	} else {
		return( LDAP_SUCCESS );
	}
}
int
LDAP_CALL
ldap_parse_userstatus_control ( 	
									LDAP *ld, 
									LDAPControl **ctrlp,  
									LDAPuserstatus *us
															)
{
	BerElement *ber = NULL;
	int			i, foundUSControl;
	LDAPControl *USCtrlp = NULL;
	ber_tag_t	tag;

	if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || us == NULL ) {
	    return( LDAP_PARAM_ERROR );
	}

	/* find the control in the list of controls if it exists */
	if ( ctrlp == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
		return ( LDAP_CONTROL_NOT_FOUND );
	} 
	foundUSControl = 0;
	for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundUSControl )); i++ ) {
		foundUSControl = !strcmp( ctrlp[i]->ldctl_oid, LDAP_CONTROL_ACCOUNT_USABLE );
	}
	if ( !foundUSControl ) {
		LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
		return ( LDAP_CONTROL_NOT_FOUND );
	} else {
		/* let local var point to the control */
		USCtrlp = ctrlp[i-1];			
	}

	/*  allocate a Ber element with the contents of the control's struct berval */
	if ( ( ber = ber_init( &USCtrlp->ldctl_value ) ) == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		return( LDAP_NO_MEMORY );
	}

	memset( us, 0, sizeof(struct LDAPuserstatus) );

    /*
     * The control value should look like this:
     *
	 *	ACCOUNT_USABLE_RESPONSE::= CHOICE {
	 * 		is_available		[0] INTEGER, ** seconds before expiration **
	 *		is_not_available	[1] More_info
	 *	}
	 *	More_info::= SEQUENCE {
	 *		inactive				[0] BOOLEAN DEFAULT FALSE,    
	 *		reset					[1] BOOLEAN DEFAULT FALSE,    
	 *		expired					[2] BOOLEAN DEFAULT FALSE,    
	 *		remaining_grace			[3] INTEGER OPTIONAL,
	 *		seconds_before_unlock	[4] INTEGER OPTIONAL
	 *	}
	 */

	if ( ( ber_scanf( ber, "t", &tag ) ) == LBER_ERROR ) {
		LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
		ber_free( ber, 1 );
		return( LDAP_DECODING_ERROR );
	}

    tag = (( tag & LBER_CONSTRUCTED ) == LBER_CONSTRUCTED ) ? 1 : 0;

	if ( !tag ) {
		us->us_available = 1;
		if ( ber_scanf( ber, "i", &us->us_expire ) == LBER_ERROR ) {
			LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
			ber_free( ber, 1 );
			return( LDAP_DECODING_ERROR );
		}
	} else {
		us->us_available = 0;
		tag = 0;
		if ( ( ber_scanf( ber, "{t", &tag ) ) == LBER_ERROR ) {
			LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
			ber_free( ber, 1 );
			return( LDAP_DECODING_ERROR );
		}
        while ( tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET ) {
            tag = tag & (~LBER_CLASS_CONTEXT);
            switch (tag)
			{
				case 0:
                    if ( ber_scanf( ber, "b", &us->us_inactive ) == LBER_ERROR ) {
                        LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
                        ber_free( ber, 1 );
                        return( LDAP_DECODING_ERROR );
                    }
                    us->us_inactive = ( us->us_inactive != 0 ) ? 1 : 0;
                    break;
				case 1:
                    if ( ber_scanf( ber, "b", &us->us_reset ) == LBER_ERROR ) {
                        LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
                        ber_free( ber, 1 );
                        return( LDAP_DECODING_ERROR );
                    }
                    us->us_reset = ( us->us_reset != 0 ) ? 1 : 0;
                    break;
				case 2:
                    if ( ber_scanf( ber, "b", &us->us_expired ) == LBER_ERROR ) {
                        LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
                        ber_free( ber, 1 );
                        return( LDAP_DECODING_ERROR );
                    }
                    us->us_expired = ( us->us_expired != 0 ) ? 1 : 0;
                    break;
                case 3:
                    if ( ber_scanf( ber, "i", &us->us_remaining ) == LBER_ERROR ) {
                        LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
                        ber_free( ber, 1 );
                        return( LDAP_DECODING_ERROR );
                    }
                    break;
                case 4:
                    if ( ber_scanf( ber, "i", &us->us_seconds ) == LBER_ERROR ) {
                        LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
                        ber_free( ber, 1 );
                        return( LDAP_DECODING_ERROR );
                    }
                    break;
                default:
                    LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
                    ber_free( ber, 1 );
                    return( LDAP_DECODING_ERROR );
            }
            ber_scanf( ber, "t", &tag );
        }
	}

	/* the ber encoding is no longer needed */
	ber_free( ber, 1 );
	return( LDAP_SUCCESS );
}
Esempio n. 6
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 );
}
Esempio n. 7
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 ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
		return( LDAP_PARAM_ERROR );
	}
	
	if ( msgidp == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
		return( LDAP_PARAM_ERROR );
	}
	
	if ( ( ld->ld_options & LDAP_BITOPT_RECONNECT ) != 0 ) {
		nsldapi_handle_reconnect( ld );
	}	

	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,
		    cred->bv_len );

	} 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,
			    cred->bv_len );
		}
	}

	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 );
}
Esempio n. 8
0
int
LDAP_CALL
ldap_url_search( LDAP *ld, const char *url, int attrsonly )
{
	int		err, msgid;
	LDAPURLDesc	*ludp;
	BerElement	*ber;
	LDAPServer	*srv;
	char		*host;

	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
		return( -1 );		/* punt */
	}

	if ( ldap_url_parse( url, &ludp ) != 0 ) {
		LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
		return( -1 );
	}

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

	if ( nsldapi_build_search_req( ld, ludp->lud_dn, ludp->lud_scope,
	    ludp->lud_filter, ludp->lud_attrs, attrsonly, NULL, NULL,
	    -1, -1, msgid, &ber ) != LDAP_SUCCESS ) {
		return( -1 );
	}

	err = 0;

	if ( ludp->lud_host == NULL ) {
		host = ld->ld_defhost;
	} else {
		host = ludp->lud_host;
	}

	if (( srv = (LDAPServer *)NSLDAPI_CALLOC( 1, sizeof( LDAPServer )))
	    == NULL || ( host != NULL &&
	    ( srv->lsrv_host = nsldapi_strdup( host )) == NULL )) {
		if ( srv != NULL ) {
			NSLDAPI_FREE( srv );
		}
		LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
		err = -1;
	} else {
		if ( ludp->lud_port == 0 ) {
			if (( ludp->lud_options & LDAP_URL_OPT_SECURE ) == 0 ) {
				srv->lsrv_port = LDAP_PORT;
			} else {
				srv->lsrv_port = LDAPS_PORT;
			}
		} else {
			 srv->lsrv_port = ludp->lud_port;
		}
	}

	if (( ludp->lud_options & LDAP_URL_OPT_SECURE ) != 0 ) {
		srv->lsrv_options |= LDAP_SRV_OPT_SECURE;
	}

	if ( err != 0 ) {
		ber_free( ber, 1 );
	} else {
		err = nsldapi_send_server_request( ld, ber, msgid, NULL, srv,
		    NULL, NULL, 1 );
	}

	ldap_free_urldesc( ludp );
	return( err );
}
Esempio n. 9
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 );
}
Esempio n. 10
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 );
}
Esempio n. 11
0
static int
do_vals2text(
	LDAP			*ld,
	char			*buf,		/* NULL for "use internal" */
	char			**vals,
	char			*label,
	int			labelwidth,	/* 0 means use default */
	unsigned long		syntaxid,
	writeptype		writeproc,
	void			*writeparm,
	char			*eol,
	int			rdncount,
	char			*urlprefix
)
{
    int		err, i, html, writeoutval, freebuf, notascii;
    char	*p, *s, *outval;

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || writeproc == NULL ) {
	return( LDAP_PARAM_ERROR );
    }

    if ( vals == NULL ) {
	return( LDAP_SUCCESS );
    }

    html = ( urlprefix != NULL );

    switch( LDAP_GET_SYN_TYPE( syntaxid )) {
    case LDAP_SYN_TYPE_TEXT:
    case LDAP_SYN_TYPE_BOOLEAN:
	break;		/* we only bother with these two types... */
    default:
	return( LDAP_SUCCESS );
    }

    if ( labelwidth == 0 || labelwidth < 0 ) {
	labelwidth = DEF_LABEL_WIDTH;
    }

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

    output_label( buf, label, labelwidth, writeproc, writeparm, eol, html );

    for ( i = 0; vals[ i ] != NULL; ++i ) {
	for ( p = vals[ i ]; *p != '\0'; ++p ) {
	    if ( !isascii( *p )) {
		break;
	    }
	}
	notascii = ( *p != '\0' );
	outval = notascii ? dgettext(TEXT_DOMAIN,
		"(unable to display non-ASCII text value)")
		: vals[ i ];

	writeoutval = 0;	/* if non-zero, write outval after switch */

	switch( syntaxid ) {
	case LDAP_SYN_CASEIGNORESTR:
	    ++writeoutval;
	    break;

	case LDAP_SYN_RFC822ADDR:
	    if ( html ) {
		strcpy( buf, "<DD><A HREF=\"mailto:" );
		strcat_escaped( buf, outval );
		sprintf( buf + strlen( buf ), "\">%s</A><BR>%s", outval, eol );
		(*writeproc)( writeparm, buf, strlen( buf ));
	    } else {
		++writeoutval;
	    }
	    break;

	case LDAP_SYN_DN:	/* for now */
	    output_dn( buf, outval, labelwidth, rdncount, writeproc,
		    writeparm, eol, urlprefix );
	    break;

	case LDAP_SYN_MULTILINESTR:
	    if ( i > 0 && !html ) {
		output_label( buf, label, labelwidth, writeproc,
			writeparm, eol, html );
	    }

	    p = s = outval;
	    while (( s = strchr( s, '$' )) != NULL ) {
		*s++ = '\0';
		while ( ldap_utf8isspace( s )) {
		    ++s;
		}
		if ( html ) {
		    sprintf( buf, "<DD>%s<BR>%s", p, eol );
		} else {
		    sprintf( buf, "%-*s%s%s", labelwidth, " ", p, eol );
		}
		(*writeproc)( writeparm, buf, strlen( buf ));
		p = s;
	    }
	    outval = p;
	    ++writeoutval;
	    break;

	case LDAP_SYN_BOOLEAN:
	    outval = toupper( outval[ 0 ] ) == 'T' ?
		dgettext(TEXT_DOMAIN, "TRUE") : dgettext(TEXT_DOMAIN, "FALSE");
	    ++writeoutval;
	    break;

	case LDAP_SYN_TIME:
	case LDAP_SYN_DATE:
	    outval = time2text( outval, syntaxid == LDAP_SYN_DATE );
	    ++writeoutval;
	    break;

	case LDAP_SYN_LABELEDURL:
	    if ( !notascii && ( p = strchr( outval, '$' )) != NULL ) {
		*p++ = '\0';
		while ( ldap_utf8isspace( p )) {
		    ++p;
		}
		s = outval;
	    } else if ( !notascii && ( s = strchr( outval, ' ' )) != NULL ) {
		*s++ = '\0';
		while ( ldap_utf8isspace( s )) {
		    ++s;
		}
		p = outval;
	    } else {
		s = "URL";
		p = outval;
	    }

	    /*
	     * at this point `s' points to the label & `p' to the URL
	     */
	    if ( html ) {
		sprintf( buf, "<DD><A HREF=\"%s\">%s</A><BR>%s", p, s, eol );
	    } else {
		sprintf( buf, "%-*s%s%s%-*s%s%s", labelwidth, " ",
		    s, eol, labelwidth + 2, " ",p , eol );
	    }
	    (*writeproc)( writeparm, buf, strlen( buf ));
	    break;

	default:
	    sprintf( buf, dgettext(TEXT_DOMAIN,
		" Can't display item type %ld%s"),
		    syntaxid, eol );
	    (*writeproc)( writeparm, buf, strlen( buf ));
	}

	if ( writeoutval ) {
	    if ( html ) {
		sprintf( buf, "<DD>%s<BR>%s", outval, eol );
	    } else {
		sprintf( buf, "%-*s%s%s", labelwidth, " ", outval, eol );
	    }
	    (*writeproc)( writeparm, buf, strlen( buf ));
	}
    }

    if ( freebuf ) {
	NSLDAPI_FREE( buf );
    }

    return( LDAP_SUCCESS );
}
Esempio n. 12
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 );
}
Esempio n. 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 );
}
Esempio n. 14
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 );
}