1 /*
2 * Copyright (c) 2001 by Sun Microsystems, Inc.
3 * All rights reserved.
4 */
5
6 /*
7 * The contents of this file are subject to the Netscape Public
8 * License Version 1.1 (the "License"); you may not use this file
9 * except in compliance with the License. You may obtain a copy of
10 * the License at http://www.mozilla.org/NPL/
11 *
12 * Software distributed under the License is distributed on an "AS
13 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * rights and limitations under the License.
16 *
17 * The Original Code is Mozilla Communicator client code, released
18 * March 31, 1998.
19 *
20 * The Initial Developer of the Original Code is Netscape
21 * Communications Corporation. Portions created by Netscape are
22 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
23 * Rights Reserved.
24 *
25 * Contributor(s):
26 */
27 /*
28 * referral.c - routines for handling LDAPv3 referrals and references.
29 */
30
31 #include "ldap-int.h"
32
33
34 LDAPMessage *
35 LDAP_CALL
ldap_first_reference(LDAP * ld,LDAPMessage * res)36 ldap_first_reference( LDAP *ld, LDAPMessage *res )
37 {
38 if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || res == NULLMSG ) {
39 return( NULLMSG );
40 }
41
42 if ( res->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
43 return( res );
44 }
45
46 return( ldap_next_reference( ld, res ));
47 }
48
49
50 LDAPMessage *
51 LDAP_CALL
ldap_next_reference(LDAP * ld,LDAPMessage * ref)52 ldap_next_reference( LDAP *ld, LDAPMessage *ref )
53 {
54 if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || ref == NULLMSG ) {
55 return( NULLMSG ); /* punt */
56 }
57
58 for ( ref = ref->lm_chain; ref != NULLMSG; ref = ref->lm_chain ) {
59 if ( ref->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
60 return( ref );
61 }
62 }
63
64 return( NULLMSG );
65 }
66
67
68 int
69 LDAP_CALL
ldap_count_references(LDAP * ld,LDAPMessage * res)70 ldap_count_references( LDAP *ld, LDAPMessage *res )
71 {
72 int i;
73
74 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
75 return( -1 );
76 }
77
78 for ( i = 0; res != NULL; res = res->lm_chain ) {
79 if ( res->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
80 ++i;
81 }
82 }
83
84 return( i );
85 }
86
87
88 /*
89 * returns an LDAP error code.
90 */
91 int
92 LDAP_CALL
ldap_parse_reference(LDAP * ld,LDAPMessage * ref,char *** referralsp,LDAPControl *** serverctrlsp,int freeit)93 ldap_parse_reference( LDAP *ld, LDAPMessage *ref, char ***referralsp,
94 LDAPControl ***serverctrlsp, int freeit )
95 {
96 int err;
97
98 if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ||
99 !NSLDAPI_VALID_LDAPMESSAGE_REFERENCE_POINTER( ref )) {
100 return( LDAP_PARAM_ERROR );
101 }
102
103 err = nsldapi_parse_reference( ld, ref->lm_ber, referralsp,
104 serverctrlsp );
105
106 LDAP_SET_LDERRNO( ld, err, NULL, NULL );
107
108 if ( freeit ) {
109 ldap_msgfree( ref );
110 }
111
112 return( err );
113 }
114
115
116 /*
117 * returns an LDAP error code indicating success or failure of parsing
118 * does NOT set any error information inside "ld"
119 */
120 int
nsldapi_parse_reference(LDAP * ld,BerElement * rber,char *** referralsp,LDAPControl *** serverctrlsp)121 nsldapi_parse_reference( LDAP *ld, BerElement *rber, char ***referralsp,
122 LDAPControl ***serverctrlsp )
123 {
124 int err;
125 BerElement ber;
126 char **refs;
127
128 /*
129 * Parse a searchResultReference message. These are used in LDAPv3
130 * and beyond and look like this:
131 *
132 * SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
133 *
134 * all wrapped up in an LDAPMessage sequence which looks like this:
135 *
136 * LDAPMessage ::= SEQUENCE {
137 * messageID MessageID,
138 * SearchResultReference
139 * controls [0] Controls OPTIONAL
140 * }
141 *
142 * ldap_result() pulls out the message id, so by the time a result
143 * message gets here we are conveniently sitting at the start of the
144 * SearchResultReference itself.
145 */
146 err = LDAP_SUCCESS; /* optimistic */
147 ber = *rber; /* struct copy */
148
149 if ( ber_scanf( &ber, "{v", &refs ) == LBER_ERROR ) {
150 err = LDAP_DECODING_ERROR;
151 } else if ( serverctrlsp != NULL ) {
152 /* pull out controls (if requested and any are present) */
153 if ( ber_scanf( &ber, "}" ) == LBER_ERROR ) {
154 err = LDAP_DECODING_ERROR;
155 } else {
156 err = nsldapi_get_controls( &ber, serverctrlsp );
157 }
158 }
159
160 if ( referralsp == NULL ) {
161 ldap_value_free( refs );
162 } else {
163 *referralsp = refs;
164 }
165
166 return( err );
167 }
168
169 #ifdef _SOLARIS_SDK
170
ldap_get_reference_urls(LDAP * ld,LDAPMessage * res)171 char ** ldap_get_reference_urls(LDAP *ld, LDAPMessage *res)
172 {
173 BerElement tmp;
174 char **urls = NULL;
175
176 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_get_reference_urls\n", 0, 0, 0 );
177
178 if (res == NULL){
179 ld->ld_errno = LDAP_PARAM_ERROR;
180 return (NULL);
181 }
182 tmp = *res->lm_ber; /* struct copy */
183 if ( ber_scanf( &tmp, "{v}", &urls) == LBER_ERROR){
184 ld->ld_errno = LDAP_DECODING_ERROR;
185 return (NULL);
186 }
187 return (urls);
188 }
189
190 #endif /* _SOLARIS_SDK */
191
192