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