BerElement * ldap_build_compare_req(LDAP *ld, char *dn, char *attr, struct berval *bvalue, LDAPControl **serverctrls) { BerElement *ber; int rc, rv; /* The compare request looks like this: * CompareRequest ::= SEQUENCE { * entry DistinguishedName, * ava SEQUENCE { * type AttributeType, * value AttributeValue * } * } * and must be wrapped in an LDAPMessage. */ /* create a message to send */ if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { ld->ld_errno = LDAP_NO_MEMORY; return( NULLBER ); } if ( ber_printf( ber, "{it{s{so}}", ++ld->ld_msgid, LDAP_REQ_COMPARE, dn, attr, bvalue->bv_val, bvalue->bv_len ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); return( NULLBER ); } /* LDAPv3 */ /* Code controls if any */ if (serverctrls && serverctrls[0]) { if (ldap_controls_code(ber, serverctrls) != LDAP_SUCCESS){ ld->ld_errno = LDAP_ENCODING_ERROR; return( NULLBER ); } } else if (ld->ld_srvctrls && ld->ld_srvctrls[0]) { /* Otherwise, is there any global server ctrls ? */ if (ldap_controls_code(ber, ld->ld_srvctrls) != LDAP_SUCCESS){ ld->ld_errno = LDAP_ENCODING_ERROR; return( NULLBER ); } } if (ber_printf(ber, "}") == -1) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free(ber, 1); return (NULLBER); } return (ber); }
int ldap_create_virtuallist_control(LDAP *ld, LDAPVirtualList *ldvlistp, LDAPControl **ctrlp) { BerElement *ber; int rc; if (NULL == ld) return (LDAP_PARAM_ERROR); if (NULL == ctrlp || NULL == ldvlistp) return (LDAP_PARAM_ERROR); if ((ber = alloc_ber_with_options(ld)) == NULLBER) { ld->ld_errno = LDAP_NO_MEMORY; return (LDAP_NO_MEMORY); } if (ber_printf(ber, "{ii", ldvlistp->ldvlist_before_count, ldvlistp->ldvlist_after_count) == -1) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free(ber, 1); return (LDAP_ENCODING_ERROR); } if (NULL == ldvlistp->ldvlist_attrvalue) { if (ber_printf(ber, "t{ii}}", LDAP_TAG_VLV_BY_INDEX, ldvlistp->ldvlist_index, ldvlistp->ldvlist_size) == -1) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free(ber, 1); return (LDAP_ENCODING_ERROR); } } else { if (ber_printf(ber, "to}", LDAP_TAG_VLV_BY_VALUE, ldvlistp->ldvlist_attrvalue, strlen(ldvlistp->ldvlist_attrvalue)) == -1) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free(ber, 1); return (LDAP_ENCODING_ERROR); } } rc = ldap_build_control(LDAP_CONTROL_VLVREQUEST, ber, 1, 1, ctrlp); ld->ld_errno = rc; return (rc); }
/* * ldap_modrdn - initiate an ldap (and X.500) modifyRDN operation. Parameters: * * ld LDAP descriptor * dn DN of the object to modify * newrdn RDN to give the object * deleteoldrdn nonzero means to delete old rdn values from the entry * * Example: * msgid = ldap_modrdn( ld, dn, newrdn ); */ int ldap_modrdn( LDAP *ld, char *dn, char *newrdn, int deleteoldrdn ) { BerElement *ber; int rv; /* * A modify rdn request looks like this: * ModifyRDNRequest ::= SEQUENCE { * entry DistinguishedName, * newrdn RelativeDistinguishedName, * deleteoldrdn BOOLEAN * } */ #ifdef _REENTRANT LOCK_LDAP(ld); #endif Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 193, "ldap_modrdn\n"), 0, 0, 0 ); /* create a message to send */ if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { #ifdef _REENTRANT UNLOCK_LDAP(ld); #endif return( -1 ); } if ( ber_printf( ber, "{it{ssb}}", ++ld->ld_msgid, LDAP_REQ_MODRDN, dn, newrdn, deleteoldrdn ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); #ifdef _REENTRANT UNLOCK_LDAP(ld); #endif return( -1 ); } /* send the message */ rv = send_initial_request( ld, LDAP_REQ_MODRDN, dn, ber ); #ifdef _REENTRANT UNLOCK_LDAP(ld); #endif return ( rv ); }
char * ldap_first_attribute( LDAP *ld, LDAPMessage *entry, BerElement **ber ) { int len; char *attrbuffer; if ((attrbuffer = (char *)malloc(LDAP_MAX_ATTR_LEN)) == NULL) { return (NULL); } Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 179, "ldap_first_attribute\n"), 0, 0, 0 ); if ( (*ber = alloc_ber_with_options( ld )) == NULLBER ) { free(attrbuffer); return( NULL ); } **ber = *entry->lm_ber; /* * Skip past the sequence, dn, sequence of sequence, snarf the * attribute type, and skip the set of values, leaving us * positioned right before the next attribute type/value sequence. */ len = LDAP_MAX_ATTR_LEN; if ( ber_scanf( *ber, "{x{{sx}", attrbuffer, &len ) == LBER_ERROR ) { ld->ld_errno = LDAP_DECODING_ERROR; ber_free( *ber, 0 ); *ber = NULL; free(attrbuffer); return( NULL ); } return( attrbuffer ); }
static int cldap_parsemsg( LDAP *ld, int msgid, BerElement *ber, LDAPMessage **res, char *base ) { unsigned int tag, len; int rc; size_t baselen, slen; char *dn, *p, *cookie; LDAPMessage *chain, *prev, *ldm; struct berval *bv; rc = LDAP_DECODING_ERROR; /* pessimistic */ ldm = chain = prev = NULLMSG; baselen = ( base == NULL ) ? 0 : strlen( base ); bv = NULL; for ( tag = ber_first_element( ber, &len, &cookie ); tag != LBER_DEFAULT && rc != LDAP_SUCCESS; tag = ber_next_element( ber, &len, cookie )) { if (( ldm = (LDAPMessage *)calloc( 1, sizeof(LDAPMessage))) == NULL || ( ldm->lm_ber = alloc_ber_with_options( ld )) == NULLBER ) { rc = LDAP_NO_MEMORY; break; /* return w/error*/ } ldm->lm_msgid = msgid; ldm->lm_msgtype = tag; if ( tag == LDAP_RES_SEARCH_RESULT ) { Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 125, "cldap_parsemsg got search result\n"), 0, 0, 0 ); if ( ber_get_stringal( ber, &bv ) == LBER_DEFAULT ) { break; /* return w/error */ } if ( ber_printf( ldm->lm_ber, "to", tag, bv->bv_val, bv->bv_len ) == -1 ) { break; /* return w/error */ } ber_bvfree( bv ); bv = NULL; rc = LDAP_SUCCESS; } else if ( tag == LDAP_RES_SEARCH_ENTRY ) { if ( ber_scanf( ber, "{aO", &dn, &bv ) == LBER_ERROR ) { break; /* return w/error */ } Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 126, "cldap_parsemsg entry %s\n"), dn, 0, 0 ); if ( dn != NULL && *(dn + ( slen = strlen(dn)) - 1) == '*' && baselen > 0 ) { /* * substitute original searchbase for trailing '*' */ if (( p = (char *)malloc( slen + baselen )) == NULL ) { rc = LDAP_NO_MEMORY; free( dn ); break; /* return w/error */ } strcpy( p, dn ); strcpy( p + slen - 1, base ); free( dn ); dn = p; } if ( ber_printf( ldm->lm_ber, "t{so}", tag, dn, bv->bv_val, bv->bv_len ) == -1 ) { break; /* return w/error */ } free( dn ); ber_bvfree( bv ); bv = NULL; } else { Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 127, "cldap_parsemsg got unknown tag %d\n"), tag, 0, 0 ); rc = LDAP_PROTOCOL_ERROR; break; /* return w/error */ } /* Reset message ber so we can read from it later. Gack! */ ldm->lm_ber->ber_end = ldm->lm_ber->ber_ptr; ldm->lm_ber->ber_ptr = ldm->lm_ber->ber_buf; #ifdef LDAP_DEBUG if ( ldap_debug & LDAP_DEBUG_PACKETS ) { fprintf( stderr, "cldap_parsemsg add message id %d type %d:\n", ldm->lm_msgid, ldm->lm_msgtype ); ber_dump( ldm->lm_ber, 1 ); } #endif /* LDAP_DEBUG */ #ifndef NO_CACHE if ( ld->ld_cache != NULL ) { add_result_to_cache( ld, ldm ); } #endif /* NO_CACHE */ if ( chain == NULL ) { chain = ldm; } else { prev->lm_chain = ldm; } prev = ldm; ldm = NULL; } /* dispose of any leftovers */ if ( ldm != NULL ) { if ( ldm->lm_ber != NULLBER ) { ber_free( ldm->lm_ber, 1 ); } free( ldm ); } if ( bv != NULL ) { ber_bvfree( bv ); } /* return chain, calling result2error if we got anything at all */ *res = chain; return(( *res == NULLMSG ) ? rc : ldap_result2error( ld, *res, 0 )); }
BerElement * ldap_build_search_req( LDAP *ld, char *base, int scope, char *filter, char **attrs, int attrsonly ) { BerElement *ber; int err; /* * 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 ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { return( NULLBER ); } if ( base == NULL ) { base = ""; } #ifdef CLDAP if ( ld->ld_sb.sb_naddr > 0 ) { err = ber_printf( ber, "{ist{seeiib", ++ld->ld_msgid, ld->ld_cldapdn, LDAP_REQ_SEARCH, base, scope, ld->ld_deref, ld->ld_sizelimit, ld->ld_timelimit, attrsonly ); } else { #endif /* CLDAP */ err = ber_printf( ber, "{it{seeiib", ++ld->ld_msgid, LDAP_REQ_SEARCH, base, scope, ld->ld_deref, ld->ld_sizelimit, ld->ld_timelimit, attrsonly ); #ifdef CLDAP } #endif /* CLDAP */ if ( err == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); return( NULLBER ); } filter = strdup( filter ); err = put_filter( ber, filter ); free( filter ); if ( err == -1 ) { ld->ld_errno = LDAP_FILTER_ERROR; ber_free( ber, 1 ); return( NULLBER ); } if ( ber_printf( ber, "{v}}}", attrs ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); return( NULLBER ); } return( ber ); }
BerElement * ldap_build_add_req(LDAP *ld, char *dn, LDAPMod **attrs, LDAPControl ** serverctrls) { BerElement * ber; int rc, i; /* * An add request looks like this: * AddRequest ::= [APPLICATION 8] SEQUENCE { * entry DistinguishedName, * attrs SEQUENCE OF SEQUENCE { * type AttributeType, * values SET OF AttributeValue * } * } */ /* create a message to send */ if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { ld->ld_errno = LDAP_NO_MEMORY; return( NULLBER ); } if ( ber_printf( ber, "{it{s{", ++ld->ld_msgid, LDAP_REQ_ADD, dn ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); return( NULLBER ); } /* for each attribute in the entry... */ for ( i = 0; attrs[i] != NULL; i++ ) { if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) { rc = ber_printf( ber, "{s[V]}", attrs[i]->mod_type, attrs[i]->mod_values ); } else { rc = ber_printf( ber, "{s[v]}", attrs[i]->mod_type, attrs[i]->mod_values ); } if ( rc == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); return(NULLBER); } } if ( ber_printf( ber, "}}" ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); return( NULLBER ); } /* LDAPv3 */ /* Code controls if any */ if (serverctrls && serverctrls[0]) { if (ldap_controls_code(ber, serverctrls) != LDAP_SUCCESS){ ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); return( NULLBER ); } } else if (ld->ld_srvctrls && ld->ld_srvctrls[0]) { /* Otherwise, is there any global server ctrls ? */ if (ldap_controls_code(ber, ld->ld_srvctrls) != LDAP_SUCCESS){ ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); return( NULLBER ); } } if ( ber_printf( ber, "}" ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); return( NULLBER ); } return (ber); }
/* * ldap_kerberos_bind1 - initiate a bind to the ldap server using * kerberos authentication. The dn is supplied. It is assumed the user * already has a valid ticket granting ticket. The msgid of the * request is returned on success (suitable for passing to ldap_result()), * -1 is returned if there's trouble. * * Example: * ldap_kerberos_bind1( ld, "cn=manager, o=university of michigan, c=us" ) */ int ldap_kerberos_bind1( LDAP *ld, char *dn ) { BerElement *ber; char *cred; int rc, credlen; char *get_kerberosv4_credentials(); #ifdef STR_TRANSLATION int str_translation_on; #endif /* STR_TRANSLATION */ /* * The bind request looks like this: * BindRequest ::= SEQUENCE { * version INTEGER, * name DistinguishedName, * authentication CHOICE { * krbv42ldap [1] OCTET STRING * krbv42dsa [2] OCTET STRING * } * } * all wrapped up in an LDAPMessage sequence. */ #if defined( SUN ) && defined( _REENTRANT ) int rv; LOCK_LDAP(ld); #endif Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 186, "ldap_kerberos_bind1\n"), 0, 0, 0 ); if ( dn == NULL ) dn = ""; if ( (cred = get_kerberosv4_credentials( ld, dn, "ldapserver", &credlen )) == NULL ) { #if defined( SUN ) && defined( _REENTRANT ) UNLOCK_LDAP(ld); #endif return( -1 ); /* ld_errno should already be set */ } /* create a message to send */ if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { free( cred ); #if defined( SUN ) && defined( _REENTRANT ) UNLOCK_LDAP(ld); #endif return( -1 ); } #ifdef STR_TRANSLATION if (( str_translation_on = (( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0 ))) { /* turn translation off */ ber->ber_options &= ~LBER_TRANSLATE_STRINGS; } #endif /* STR_TRANSLATION */ /* fill it in */ rc = ber_printf( ber, "{it{isto}}", ++ld->ld_msgid, LDAP_REQ_BIND, ld->ld_version, dn, LDAP_AUTH_KRBV41, cred, credlen ); #ifdef STR_TRANSLATION if ( str_translation_on ) { /* restore translation */ ber->ber_options |= LBER_TRANSLATE_STRINGS; } #endif /* STR_TRANSLATION */ if ( rc == -1 ) { free( cred ); ber_free( ber, 1 ); ld->ld_errno = LDAP_ENCODING_ERROR; #if defined( SUN ) && defined( _REENTRANT ) UNLOCK_LDAP(ld); #endif return( -1 ); } free( cred ); #ifndef NO_CACHE if ( ld->ld_cache != NULL ) { ldap_flush_cache( ld ); } #endif /* !NO_CACHE */ /* send the message */ #if defined( SUN ) && defined( _REENTRANT ) rv = send_initial_request( ld, LDAP_REQ_BIND, dn, ber ); UNLOCK_LDAP(ld); return ( rv ); #else return ( send_initial_request( ld, LDAP_REQ_BIND, dn, ber )); #endif }
/* * ldap_kerberos_bind2 - initiate a bind to the X.500 server using * kerberos authentication. The dn is supplied. It is assumed the user * already has a valid ticket granting ticket. The msgid of the * request is returned on success (suitable for passing to ldap_result()), * -1 is returned if there's trouble. * * Example: * ldap_kerberos_bind2( ld, "cn=manager, o=university of michigan, c=us" ) */ int ldap_kerberos_bind2( LDAP *ld, char *dn ) { BerElement *ber; char *cred; int rc, credlen; char *get_kerberosv4_credentials(); #ifdef STR_TRANSLATION int str_translation_on; #endif /* STR_TRANSLATION */ #if defined( SUN ) && defined( _REENTRANT ) int rv; LOCK_LDAP(ld); #endif Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 188, "ldap_kerberos_bind2\n"), 0, 0, 0 ); if ( dn == NULL ) dn = ""; if ( (cred = get_kerberosv4_credentials( ld, dn, "x500dsa", &credlen )) == NULL ) { #if defined( SUN ) && defined( _REENTRANT ) UNLOCK_LDAP(ld); #endif return( -1 ); /* ld_errno should already be set */ } /* create a message to send */ if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { free( cred ); #if defined( SUN ) && defined( _REENTRANT ) UNLOCK_LDAP(ld); #endif return( -1 ); } #ifdef STR_TRANSLATION if (( str_translation_on = (( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0 ))) { /* turn translation off */ ber->ber_options &= ~LBER_TRANSLATE_STRINGS; } #endif /* STR_TRANSLATION */ /* fill it in */ rc = ber_printf( ber, "{it{isto}}", ++ld->ld_msgid, LDAP_REQ_BIND, ld->ld_version, dn, LDAP_AUTH_KRBV42, cred, credlen ); #ifdef STR_TRANSLATION if ( str_translation_on ) { /* restore translation */ ber->ber_options |= LBER_TRANSLATE_STRINGS; } #endif /* STR_TRANSLATION */ free( cred ); if ( rc == -1 ) { ber_free( ber, 1 ); ld->ld_errno = LDAP_ENCODING_ERROR; #if defined( SUN ) && defined( _REENTRANT ) UNLOCK_LDAP(ld); #endif return( -1 ); } /* send the message */ #if defined( SUN ) && defined( _REENTRANT ) rv = send_initial_request( ld, LDAP_REQ_BIND, dn, ber ); UNLOCK_LDAP(ld); return ( rv ); #endif return ( send_initial_request( ld, LDAP_REQ_BIND, dn, ber )); }