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