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