]> git.sur5r.net Git - openldap/blob - libraries/libldap/references.c
Add OpenLDAP RCSid to *.[ch] in clients, libraries, and servers.
[openldap] / libraries / libldap / references.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-1999 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/ctype.h>
17 #include <ac/socket.h>
18 #include <ac/string.h>
19 #include <ac/time.h>
20
21 #include "ldap-int.h"
22
23 LDAPMessage *
24 ldap_first_reference( LDAP *ld, LDAPMessage *chain )
25 {
26         assert( ld != NULL );
27         assert( LDAP_VALID( ld ) );
28         assert( chain !=  NULL );
29
30         if ( ld == NULL || chain == NULL ) {
31                 return NULL;
32         }
33
34         return chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE
35                 ? chain
36                 : ldap_next_reference( ld, chain );
37 }
38
39 LDAPMessage *
40 ldap_next_reference( LDAP *ld, LDAPMessage *ref )
41 {
42         assert( ld != NULL );
43         assert( LDAP_VALID( ld ) );
44         assert( ref !=  NULL );
45
46         if ( ld == NULL || ref == NULL ) {
47                 return NULL;
48         }
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         assert( chain !=  NULL );
71
72         if ( ld == NULL ) {
73                 return -1;
74         }
75
76         
77         for ( i = 0; chain != NULL; chain = chain->lm_chain ) {
78                 if( chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
79                         i++;
80                 }
81         }
82
83         return( i );
84 }
85
86 int
87 ldap_parse_reference( 
88         LDAP            *ld,    
89         LDAPMessage     *ref,
90         char            ***referralsp,
91         LDAPControl     ***serverctrls,
92         int             freeit)
93 {
94         BerElement be;
95         char **refs = NULL;
96         int rc;
97
98         assert( ld != NULL );
99         assert( LDAP_VALID( ld ) );
100         assert( ref !=  NULL );
101
102         if( ld == NULL || ref == NULL ||
103                 ref->lm_msgtype != LDAP_RES_SEARCH_REFERENCE )
104         {
105                 return LDAP_PARAM_ERROR;
106         }
107
108         /* make a private copy of BerElement */
109         SAFEMEMCPY(&be, ref->lm_ber, sizeof(be));
110         
111         if ( ber_scanf( &be, "{v" /*}*/, &refs ) == LBER_ERROR ) {
112                 rc = LDAP_DECODING_ERROR;
113                 goto free_and_return;
114         }
115
116         if ( serverctrls == NULL ) {
117                 rc = LDAP_SUCCESS;
118                 goto free_and_return;
119         }
120
121         if ( ber_scanf( &be, /*{*/ "}" ) == LBER_ERROR ) {
122                 rc = LDAP_DECODING_ERROR;
123                 goto free_and_return;
124         }
125
126         rc = ldap_int_get_controls( &be, serverctrls );
127
128 free_and_return:
129
130         if( referralsp != NULL ) {
131                 /* provide references regradless of return code */
132                 *referralsp = refs;
133
134         } else {
135                 ldap_value_free( refs );
136         }
137
138         if( freeit ) {
139                 ldap_msgfree( ref );
140         }
141
142         if( rc != LDAP_SUCCESS ) {
143                 ld->ld_errno = rc;
144
145                 if( ld->ld_matched != NULL ) {
146                         LDAP_FREE( ld->ld_matched );
147                         ld->ld_matched = NULL;
148                 }
149
150                 if( ld->ld_error != NULL ) {
151                         LDAP_FREE( ld->ld_error );
152                         ld->ld_error = NULL;
153                 }
154         }
155
156         return rc;
157 }