]> git.sur5r.net Git - openldap/blob - libraries/libldap/references.c
a5e5afefd0def458478250a28e0622eb8ca1697e
[openldap] / libraries / libldap / references.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  *  references.c
8  */
9
10 #include "portable.h"
11
12 #include <stdio.h>
13
14 #include <ac/stdlib.h>
15
16 #include <ac/socket.h>
17 #include <ac/string.h>
18 #include <ac/time.h>
19
20 #include "ldap-int.h"
21
22 LDAPMessage *
23 ldap_first_reference( LDAP *ld, LDAPMessage *chain )
24 {
25         assert( ld != NULL );
26         assert( LDAP_VALID( ld ) );
27         assert( chain !=  NULL );
28
29         if ( ld == NULL || chain == NULL ) {
30                 return NULL;
31         }
32
33         return chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE
34                 ? chain
35                 : ldap_next_reference( ld, chain );
36 }
37
38 LDAPMessage *
39 ldap_next_reference( LDAP *ld, LDAPMessage *ref )
40 {
41         assert( ld != NULL );
42         assert( LDAP_VALID( ld ) );
43         assert( ref !=  NULL );
44
45         if ( ld == NULL || ref == NULL ) {
46                 return NULL;
47         }
48
49         for (
50                 ref = ref->lm_chain;
51                 ref != NULL;
52                 ref = ref->lm_chain )
53         {
54                 if( ref->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
55                         return( ref );
56                 }
57         }
58
59         return( NULL );
60 }
61
62 int
63 ldap_count_references( LDAP *ld, LDAPMessage *chain )
64 {
65         int     i;
66
67         assert( ld != NULL );
68         assert( LDAP_VALID( ld ) );
69         assert( chain !=  NULL );
70
71         if ( ld == NULL ) {
72                 return -1;
73         }
74
75         
76         for ( i = 0; chain != NULL; chain = chain->lm_chain ) {
77                 if( chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
78                         i++;
79                 }
80         }
81
82         return( i );
83 }
84
85 int
86 ldap_parse_reference( 
87         LDAP            *ld,    
88         LDAPMessage     *ref,
89         char            ***referralsp,
90         LDAPControl     ***serverctrls,
91         int             freeit)
92 {
93         BerElement be;
94         char **refs = NULL;
95         int rc;
96
97         assert( ld != NULL );
98         assert( LDAP_VALID( ld ) );
99         assert( ref !=  NULL );
100
101         if( ld == NULL || ref == NULL ||
102                 ref->lm_msgtype != LDAP_RES_SEARCH_REFERENCE )
103         {
104                 return LDAP_PARAM_ERROR;
105         }
106
107         /* make a private copy of BerElement */
108         AC_MEMCPY(&be, ref->lm_ber, sizeof(be));
109         
110         if ( ber_scanf( &be, "{v" /*}*/, &refs ) == LBER_ERROR ) {
111                 rc = LDAP_DECODING_ERROR;
112                 goto free_and_return;
113         }
114
115         if ( serverctrls == NULL ) {
116                 rc = LDAP_SUCCESS;
117                 goto free_and_return;
118         }
119
120         if ( ber_scanf( &be, /*{*/ "}" ) == LBER_ERROR ) {
121                 rc = LDAP_DECODING_ERROR;
122                 goto free_and_return;
123         }
124
125         rc = ldap_int_get_controls( &be, serverctrls );
126
127 free_and_return:
128
129         if( referralsp != NULL ) {
130                 /* provide references regradless of return code */
131                 *referralsp = refs;
132
133         } else {
134                 LDAP_VFREE( refs );
135         }
136
137         if( freeit ) {
138                 ldap_msgfree( ref );
139         }
140
141         if( rc != LDAP_SUCCESS ) {
142                 ld->ld_errno = rc;
143
144                 if( ld->ld_matched != NULL ) {
145                         LDAP_FREE( ld->ld_matched );
146                         ld->ld_matched = NULL;
147                 }
148
149                 if( ld->ld_error != NULL ) {
150                         LDAP_FREE( ld->ld_error );
151                         ld->ld_error = NULL;
152                 }
153         }
154
155         return rc;
156 }