1 /* $NetBSD: references.c,v 1.1.1.3 2010/12/12 15:21:34 adam Exp $ */ 2 3 /* references.c */ 4 /* OpenLDAP: pkg/ldap/libraries/libldap/references.c,v 1.24.2.5 2010/04/13 20:22:59 kurt Exp */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2010 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18 19 #include "portable.h" 20 21 #include <stdio.h> 22 23 #include <ac/stdlib.h> 24 25 #include <ac/socket.h> 26 #include <ac/string.h> 27 #include <ac/time.h> 28 29 #include "ldap-int.h" 30 31 LDAPMessage * 32 ldap_first_reference( LDAP *ld, LDAPMessage *chain ) 33 { 34 assert( ld != NULL ); 35 assert( LDAP_VALID( ld ) ); 36 assert( chain != NULL ); 37 38 return chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE 39 ? chain 40 : ldap_next_reference( ld, chain ); 41 } 42 43 LDAPMessage * 44 ldap_next_reference( LDAP *ld, LDAPMessage *ref ) 45 { 46 assert( ld != NULL ); 47 assert( LDAP_VALID( ld ) ); 48 assert( ref != NULL ); 49 50 for ( 51 ref = ref->lm_chain; 52 ref != NULL; 53 ref = ref->lm_chain ) 54 { 55 if( ref->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) { 56 return( ref ); 57 } 58 } 59 60 return( NULL ); 61 } 62 63 int 64 ldap_count_references( LDAP *ld, LDAPMessage *chain ) 65 { 66 int i; 67 68 assert( ld != NULL ); 69 assert( LDAP_VALID( ld ) ); 70 71 for ( i = 0; chain != NULL; chain = chain->lm_chain ) { 72 if( chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) { 73 i++; 74 } 75 } 76 77 return( i ); 78 } 79 80 int 81 ldap_parse_reference( 82 LDAP *ld, 83 LDAPMessage *ref, 84 char ***referralsp, 85 LDAPControl ***serverctrls, 86 int freeit) 87 { 88 BerElement be; 89 char **refs = NULL; 90 int rc; 91 92 assert( ld != NULL ); 93 assert( LDAP_VALID( ld ) ); 94 assert( ref != NULL ); 95 96 if( ref->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) { 97 return LDAP_PARAM_ERROR; 98 } 99 100 /* make a private copy of BerElement */ 101 AC_MEMCPY(&be, ref->lm_ber, sizeof(be)); 102 103 if ( ber_scanf( &be, "{v" /*}*/, &refs ) == LBER_ERROR ) { 104 rc = LDAP_DECODING_ERROR; 105 goto free_and_return; 106 } 107 108 if ( serverctrls == NULL ) { 109 rc = LDAP_SUCCESS; 110 goto free_and_return; 111 } 112 113 if ( ber_scanf( &be, /*{*/ "}" ) == LBER_ERROR ) { 114 rc = LDAP_DECODING_ERROR; 115 goto free_and_return; 116 } 117 118 rc = ldap_pvt_get_controls( &be, serverctrls ); 119 120 free_and_return: 121 122 if( referralsp != NULL ) { 123 /* provide references regradless of return code */ 124 *referralsp = refs; 125 126 } else { 127 LDAP_VFREE( refs ); 128 } 129 130 if( freeit ) { 131 ldap_msgfree( ref ); 132 } 133 134 if( rc != LDAP_SUCCESS ) { 135 ld->ld_errno = rc; 136 137 if( ld->ld_matched != NULL ) { 138 LDAP_FREE( ld->ld_matched ); 139 ld->ld_matched = NULL; 140 } 141 142 if( ld->ld_error != NULL ) { 143 LDAP_FREE( ld->ld_error ); 144 ld->ld_error = NULL; 145 } 146 } 147 148 return rc; 149 } 150