123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- /* $OpenLDAP$ */
- /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2022 The OpenLDAP Foundation.
- * Portions Copyright 2008 Pierangelo Masarati.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
- /* ACKNOWLEDGEMENTS:
- * This work was initially developed by Pierangelo Masarati
- * for inclusion in OpenLDAP Software.
- */
- #include "portable.h"
- #include <stdio.h>
- #include <ac/stdlib.h>
- #include <ac/string.h>
- #include <ac/time.h>
- #include "ldap-int.h"
- int
- ldap_create_deref_control_value(
- LDAP *ld,
- LDAPDerefSpec *ds,
- struct berval *value )
- {
- BerElement *ber = NULL;
- ber_tag_t tag;
- int i;
- if ( ld == NULL || value == NULL || ds == NULL )
- {
- if ( ld )
- ld->ld_errno = LDAP_PARAM_ERROR;
- return LDAP_PARAM_ERROR;
- }
- assert( LDAP_VALID( ld ) );
- value->bv_val = NULL;
- value->bv_len = 0;
- ld->ld_errno = LDAP_SUCCESS;
- ber = ldap_alloc_ber_with_options( ld );
- if ( ber == NULL ) {
- ld->ld_errno = LDAP_NO_MEMORY;
- return ld->ld_errno;
- }
- tag = ber_printf( ber, "{" /*}*/ );
- if ( tag == LBER_ERROR ) {
- ld->ld_errno = LDAP_ENCODING_ERROR;
- goto done;
- }
- for ( i = 0; ds[i].derefAttr != NULL; i++ ) {
- int j;
- tag = ber_printf( ber, "{s{" /*}}*/ , ds[i].derefAttr );
- if ( tag == LBER_ERROR ) {
- ld->ld_errno = LDAP_ENCODING_ERROR;
- goto done;
- }
- for ( j = 0; ds[i].attributes[j] != NULL; j++ ) {
- tag = ber_printf( ber, "s", ds[i].attributes[ j ] );
- if ( tag == LBER_ERROR ) {
- ld->ld_errno = LDAP_ENCODING_ERROR;
- goto done;
- }
- }
- tag = ber_printf( ber, /*{{*/ "}N}" );
- if ( tag == LBER_ERROR ) {
- ld->ld_errno = LDAP_ENCODING_ERROR;
- goto done;
- }
- }
- tag = ber_printf( ber, /*{*/ "}" );
- if ( tag == LBER_ERROR ) {
- ld->ld_errno = LDAP_ENCODING_ERROR;
- goto done;
- }
- if ( ber_flatten2( ber, value, 1 ) == -1 ) {
- ld->ld_errno = LDAP_NO_MEMORY;
- }
- done:;
- if ( ber != NULL ) {
- ber_free( ber, 1 );
- }
- return ld->ld_errno;
- }
- int
- ldap_create_deref_control(
- LDAP *ld,
- LDAPDerefSpec *ds,
- int iscritical,
- LDAPControl **ctrlp )
- {
- struct berval value;
- if ( ctrlp == NULL ) {
- ld->ld_errno = LDAP_PARAM_ERROR;
- return ld->ld_errno;
- }
- ld->ld_errno = ldap_create_deref_control_value( ld, ds, &value );
- if ( ld->ld_errno == LDAP_SUCCESS ) {
- ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_DEREF,
- iscritical, &value, 0, ctrlp );
- if ( ld->ld_errno != LDAP_SUCCESS ) {
- LDAP_FREE( value.bv_val );
- }
- }
- return ld->ld_errno;
- }
- void
- ldap_derefresponse_free( LDAPDerefRes *dr )
- {
- for ( ; dr; ) {
- LDAPDerefRes *drnext = dr->next;
- LDAPDerefVal *dv;
- LDAP_FREE( dr->derefAttr );
- LDAP_FREE( dr->derefVal.bv_val );
- for ( dv = dr->attrVals; dv; ) {
- LDAPDerefVal *dvnext = dv->next;
- LDAP_FREE( dv->type );
- ber_bvarray_free( dv->vals );
- LDAP_FREE( dv );
- dv = dvnext;
- }
- LDAP_FREE( dr );
- dr = drnext;
- }
- }
- int
- ldap_parse_derefresponse_control(
- LDAP *ld,
- LDAPControl *ctrl,
- LDAPDerefRes **drp2 )
- {
- BerElementBuffer berbuf;
- BerElement *ber = (BerElement *)&berbuf;
- ber_tag_t tag;
- ber_len_t len;
- char *last;
- LDAPDerefRes *drhead = NULL, **drp;
- if ( ld == NULL || ctrl == NULL || drp2 == NULL ) {
- if ( ld )
- ld->ld_errno = LDAP_PARAM_ERROR;
- return LDAP_PARAM_ERROR;
- }
- /* Set up a BerElement from the berval returned in the control. */
- ber_init2( ber, &ctrl->ldctl_value, 0 );
- /* Extract the count and cookie from the control. */
- drp = &drhead;
- for ( tag = ber_first_element( ber, &len, &last );
- tag != LBER_DEFAULT;
- tag = ber_next_element( ber, &len, last ) )
- {
- LDAPDerefRes *dr;
- LDAPDerefVal **dvp;
- char *last2;
- dr = LDAP_CALLOC( 1, sizeof(LDAPDerefRes) );
- if ( dr == NULL ) {
- ldap_derefresponse_free( drhead );
- *drp2 = NULL;
- ld->ld_errno = LDAP_NO_MEMORY;
- return ld->ld_errno;
- }
- dvp = &dr->attrVals;
- tag = ber_scanf( ber, "{ao", &dr->derefAttr, &dr->derefVal );
- if ( tag == LBER_ERROR ) {
- goto done;
- }
- tag = ber_peek_tag( ber, &len );
- if ( tag == (LBER_CONSTRUCTED|LBER_CLASS_CONTEXT) ) {
- for ( tag = ber_first_element( ber, &len, &last2 );
- tag != LBER_DEFAULT;
- tag = ber_next_element( ber, &len, last2 ) )
- {
- LDAPDerefVal *dv;
- dv = LDAP_CALLOC( 1, sizeof(LDAPDerefVal) );
- if ( dv == NULL ) {
- ldap_derefresponse_free( drhead );
- LDAP_FREE( dr );
- *drp2 = NULL;
- ld->ld_errno = LDAP_NO_MEMORY;
- return ld->ld_errno;
- }
- tag = ber_scanf( ber, "{a[W]}", &dv->type, &dv->vals );
- if ( tag == LBER_ERROR ) {
- goto done;
- }
- *dvp = dv;
- dvp = &dv->next;
- }
- }
- tag = ber_scanf( ber, "}" );
- if ( tag == LBER_ERROR ) {
- goto done;
- }
- *drp = dr;
- drp = &dr->next;
- }
- tag = 0;
- done:;
- if ( tag == LBER_ERROR ) {
- if ( drhead != NULL ) {
- ldap_derefresponse_free( drhead );
- }
- *drp2 = NULL;
- ld->ld_errno = LDAP_DECODING_ERROR;
- } else {
- *drp2 = drhead;
- ld->ld_errno = LDAP_SUCCESS;
- }
- return ld->ld_errno;
- }
- int
- ldap_parse_deref_control(
- LDAP *ld,
- LDAPControl **ctrls,
- LDAPDerefRes **drp )
- {
- LDAPControl *c;
- if ( drp == NULL ) {
- ld->ld_errno = LDAP_PARAM_ERROR;
- return ld->ld_errno;
- }
- *drp = NULL;
- if ( ctrls == NULL ) {
- ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
- return ld->ld_errno;
- }
- c = ldap_control_find( LDAP_CONTROL_X_DEREF, ctrls, NULL );
- if ( c == NULL ) {
- /* No deref control was found. */
- ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
- return ld->ld_errno;
- }
- ld->ld_errno = ldap_parse_derefresponse_control( ld, c, drp );
- return ld->ld_errno;
- }
|