/* Rewrite an LDAP DN in DER form * Input must be valid DN, therefore no error checking is done here. */ static int autoca_dnbv2der( Operation *op, struct berval *bv, struct berval *der ) { BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; LDAPDN dn; LDAPRDN rdn; LDAPAVA *ava; AttributeDescription *ad; int irdn, iava; ldap_bv2dn_x( bv, &dn, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ); ber_init2( ber, NULL, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); /* count RDNs, we need them in reverse order */ for (irdn = 0; dn[irdn]; irdn++); irdn--; /* DN is a SEQuence of RDNs */ ber_start_seq( ber, LBER_SEQUENCE ); for (; irdn >=0; irdn--) { /* RDN is a SET of AVAs */ ber_start_set( ber, LBER_SET ); rdn = dn[irdn]; for (iava = 0; rdn[iava]; iava++) { const char *text; char oid[1024]; struct berval bvo = { sizeof(oid), oid }; struct berval bva; /* AVA is a SEQuence of attr and value */ ber_start_seq( ber, LBER_SEQUENCE ); ava = rdn[iava]; ad = NULL; slap_bv2ad( &ava->la_attr, &ad, &text ); ber_str2bv( ad->ad_type->sat_oid, 0, 0, &bva ); ber_encode_oid( &bva, &bvo ); ber_put_berval( ber, &bvo, LBER_TAG_OID ); ber_put_berval( ber, &ava->la_value, LBER_TAG_UTF8 ); ber_put_seq( ber ); } ber_put_set( ber ); } ber_put_seq( ber ); ber_flatten2( ber, der, 0 ); ldap_dnfree_x( dn, op->o_tmpmemctx ); return 0; }
/* * Append a list of LDAPv3 controls to ber. If ctrls is NULL, use default * set of controls from ld. * Return an LDAP error code (LDAP_SUCCESS if all goes well). * If closeseq is non-zero, we do an extra ber_put_seq() as well. */ int nsldapi_put_controls( LDAP *ld, LDAPControl **ctrls, int closeseq, BerElement *ber ) { LDAPControl *c; int rc, i; rc = LDAP_ENCODING_ERROR; /* the most popular error */ /* if no controls were passed in, use global list from LDAP * */ LDAP_MUTEX_LOCK( ld, LDAP_CTRL_LOCK ); if ( ctrls == NULL ) { ctrls = ld->ld_servercontrols; } /* if there are no controls then we are done */ if ( ctrls == NULL || ctrls[ 0 ] == NULL ) { goto clean_exit; } /* * If we're using LDAPv2 or earlier we can't send any controls, so * we just ignore them unless one is marked critical, in which case * we return an error. */ if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) { for ( i = 0; ctrls != NULL && ctrls[i] != NULL; i++ ) { if ( ctrls[i]->ldctl_iscritical ) { rc = LDAP_NOT_SUPPORTED; goto error_exit; } } goto clean_exit; } /* * encode the controls as a Sequence of Sequence */ if ( ber_printf( ber, "t{", LDAP_TAG_CONTROLS ) == -1 ) { goto error_exit; } for ( i = 0; ctrls[i] != NULL; i++ ) { c = ctrls[i]; if ( ber_printf( ber, "{s", c->ldctl_oid ) == -1 ) { goto error_exit; } /* criticality is "BOOLEAN DEFAULT FALSE" */ /* therefore, it should only be encoded if it exists AND is TRUE */ if ( c->ldctl_iscritical ) { if ( ber_printf( ber, "b", (int)c->ldctl_iscritical ) == -1 ) { goto error_exit; } } if ( c->ldctl_value.bv_val != NULL ) { if ( ber_printf( ber, "o", c->ldctl_value.bv_val, (int)c->ldctl_value.bv_len /* XXX lossy cast */ ) == -1 ) { goto error_exit; } } if ( ber_put_seq( ber ) == -1 ) { goto error_exit; } } if ( ber_put_seq( ber ) == -1 ) { goto error_exit; } clean_exit: LDAP_MUTEX_UNLOCK( ld, LDAP_CTRL_LOCK ); if ( closeseq && ber_put_seq( ber ) == -1 ) { goto error_exit; } return( LDAP_SUCCESS ); error_exit: LDAP_MUTEX_UNLOCK( ld, LDAP_CTRL_LOCK ); LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); return( rc ); }