]> git.sur5r.net Git - openldap/blob - servers/ldapd/util.c
Round 2 of connection management changes.
[openldap] / servers / ldapd / util.c
1 /*
2  * Copyright (c) 1990 Regents of the University of Michigan.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of Michigan at Ann Arbor. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12
13 #include "portable.h"
14
15 #include <stdio.h>
16
17 #include <ac/ctype.h>
18 #include <ac/errno.h>
19 #include <ac/socket.h>
20 #include <ac/string.h>
21
22 #include <sys/ioctl.h>
23
24 #include <quipu/commonarg.h>
25 #include <quipu/ds_error.h>
26
27 #include "lber.h"
28 #include "ldap.h"
29 #include "common.h"
30
31 /*
32  * Print arbitrary stuff, for debugging.
33  */
34
35
36 #define BPLEN   48
37
38 void
39 bprint( char *data, int len )
40 {
41     static const char   hexdig[] = "0123456789abcdef";
42     char        out[ BPLEN ];
43     int         i = 0;
44
45     (void) memset( out, 0, BPLEN );
46     for ( ;; ) {
47         if ( len < 1 ) {
48             printf( "\t%s\n", ( i == 0 ) ? "(end)" : out );
49             break;
50         }
51
52         if ( isgraph( (unsigned char)*data )) {
53             out[ i ] = ' ';
54             out[ i+1 ] = *data;
55         } else {
56             out[ i ] = hexdig[ ( (unsigned char)*data & 0xf0 ) >> 4 ];
57             out[ i+1 ] = hexdig[ (unsigned char)*data & 0x0f ];
58         }
59         i += 2;
60         len--;
61         data++;
62
63         if ( i > BPLEN - 2 ) {
64             printf( "\t%s\n", out );
65             (void) memset( out, 0, BPLEN );
66             i = 0;
67             continue;
68         }
69         out[ i++ ] = ' ';
70     }
71 }
72
73 void
74 charlist_free( char **cl )
75 {
76         int     i;
77
78         if ( cl == NULL )
79                 return;
80
81         for ( i = 0; cl[i] != NULL; i++ )
82                 free( cl[i] );
83         free( (char *) cl );
84 }
85
86 int
87 get_ava( BerElement *ber, AVA *tava )
88 {
89         char                    *type, *value;
90
91         Debug( LDAP_DEBUG_TRACE, "get_ava\n", 0, 0, 0 );
92
93         /*
94          * An AVA looks like this:
95          *      AttributeValueAsertion ::= SEQUENCE {
96          *              attributeType   AttributeType,
97          *              attributeValue  AttributeValue
98          *      }
99          */
100
101         if ( ber_scanf( ber, "{aa}", &type, &value ) == LBER_ERROR )
102                 return( LDAP_PROTOCOL_ERROR );
103
104         if ( (tava->ava_type = str2AttrT( type )) == NULLAttrT ) {
105                 free( type );
106                 free( value );
107                 return( LDAP_UNDEFINED_TYPE );
108         }
109
110         if ( (tava->ava_value = ldap_str2AttrV( value,
111             tava->ava_type->oa_syntax )) == NULLAttrV ) {
112                 free( type );
113                 free( value );
114                 return( LDAP_INVALID_SYNTAX );
115         }
116
117         free( type );
118         free( value );
119
120         return( 0 );
121 }
122
123 int
124 chase_referral(
125     Sockbuf             *clientsb,
126     struct msg          *m,
127     struct DSError      *err,
128     char                **matched
129 )
130 {
131         ContinuationRef         cr;
132         struct access_point     *ap;
133         int                     rc, bound;
134         struct conn             *save, *dup, *found;
135
136         Debug( LDAP_DEBUG_TRACE, "chase_referral\n", 0, 0, 0 );
137
138         save = m->m_conn;
139         dup = conn_dup( m->m_conn );
140         m->m_conn = dup;
141         m->m_conn->c_ad = -1;
142
143         /* for each dsa candidate */
144         rc = LDAP_OTHER;
145         for ( cr = err->ERR_REFERRAL.DSE_ref_candidates;
146             cr != NULLCONTINUATIONREF; cr = cr->cr_next ) {
147
148                 /* for each access point listed for the dsa */
149                 for ( ap = cr->cr_accesspoints; ap != NULLACCESSPOINT;
150                     ap = ap->ap_next ) {
151 #ifdef LDAP_DEBUG
152                         if ( ldap_debug & LDAP_DEBUG_ARGS ) {
153                                 char    *str;
154
155                                 str = paddr2str( ap->ap_address, NULLNA );
156                                 fprintf( stderr, "Referring to (%s)...\n",
157                                     str );
158                         }
159 #endif
160
161                         if ( m->m_conn->c_paddr )
162                                 free( (char *) m->m_conn->c_paddr );
163                         m->m_conn->c_paddr = psap_cpy( ap->ap_address );
164
165                         if ( (found = conn_find( m->m_conn )) != NULL ) {
166                                 conn_free( m->m_conn );
167                                 m->m_conn = found;
168                                 m->m_conn->c_refcnt++;
169                                 conn_free( save );
170                                 return( LDAP_SUCCESS );
171                         }
172
173                         rc = do_bind_real( m->m_conn, &bound, matched );
174
175                         if ( rc == LDAP_SUCCESS ) {
176                                 conn_free( save );
177                                 conn_add( m->m_conn );
178                                 return( LDAP_SUCCESS );
179                         }
180                 }
181
182         }
183
184         /* so the conn can be found and freed later */
185         conn_free( m->m_conn );
186         m->m_conn = save;
187
188         return( rc );
189 }