]> git.sur5r.net Git - openldap/blob - servers/ldapd/association.c
Blindly added Autoconf support to ldapd.
[openldap] / servers / ldapd / association.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/errno.h>
18 #include <ac/socket.h>
19 #include <ac/string.h>
20 #include <ac/time.h>
21
22 #include <quipu/commonarg.h>
23 #include <quipu/ds_error.h>
24 #include "lber.h"
25 #include "ldap.h"
26
27 #if ISODEPACKAGE == IC
28 #include <ll/isoaddrs.h>
29 #else
30 #include <isoaddrs.h>
31 #endif
32 #include "common.h"
33
34 #ifdef HAVE_SYS_IOCTL_H 
35 #include <sys/ioctl.h>
36 #endif
37 #ifdef HAVE_SYS_FILIO_H 
38 #include <sys/filio.h>
39 #endif
40
41 #ifdef __hpux
42 #define FIOGETOWN       FIOGSAIOOWN
43 #endif
44
45 struct conn     *conns;
46
47 struct conn *conn_dup( struct conn *cn )
48 {
49         struct conn     *new;
50         struct PSAPaddr *psap_cpy();
51
52         if ( (new = (struct conn *) malloc( sizeof(struct conn) )) == NULL )
53                 return( NULL );
54
55         *new = *cn;
56         new->c_next = NULL;
57         new->c_time = 0L;
58         new->c_paddr = psap_cpy( cn->c_paddr );
59         new->c_dn = strdup( cn->c_dn );
60         if ( new->c_credlen > 0 ) {
61                 new->c_cred = (char *) malloc( cn->c_credlen );
62                 SAFEMEMCPY( new->c_cred, cn->c_cred, cn->c_credlen );
63         } else {
64                 new->c_cred = "";
65         }
66         new->c_credlen = cn->c_credlen;
67         new->c_refcnt = 1;
68
69         return( new );
70 }
71
72 int
73 conn_init()
74 {
75         extern char     *dsa_address;
76         struct PSAPaddr *addr, *psap_cpy();
77
78         if ( (conns = (struct conn *) malloc( sizeof(struct conn) )) == NULL ) {
79                 Debug( LDAP_DEBUG_ANY, "conn_init: malloc failed\n", 0, 0, 0 );
80                 return( -1 );
81         }
82
83         conns->c_ad = -1;
84         conns->c_dn = NULL;
85         conns->c_cred = NULL;
86         conns->c_credlen = 0;
87
88         if ( dsa_address == NULL || (addr = str2paddr( dsa_address ))
89             == NULLPA ) {
90                 conns->c_paddr = NULLPA;
91                 Debug( LDAP_DEBUG_ANY, "conn_init: bad DSA address (%s)\n",
92                     dsa_address ? dsa_address : "NULL", 0, 0 );
93         } else {
94             conns->c_paddr = psap_cpy( addr );
95         }
96
97         conns->c_refcnt = 1;    /* this conn is never deleted */
98         conns->c_next = NULL;
99
100         return( 0 );
101 }
102
103 void
104 conn_free( struct conn *conn )
105 {
106         struct timeval  tv;
107         extern int      referral_connection_timeout;
108
109         Debug( LDAP_DEBUG_TRACE, "conn_free (%s): refcnt is %d\n",
110             paddr2str( conn->c_paddr, NULLNA ), conn->c_refcnt, 0 );
111
112         if ( --conn->c_refcnt > 0 )
113                 return;
114
115         gettimeofday( &tv, (struct timezone *)NULL );
116         if ( conn->c_time != 0L && (tv.tv_sec - conn->c_time)
117             < referral_connection_timeout ) {
118                 Debug( LDAP_DEBUG_TRACE, "conn_free: referral conn ttl is %d\n",
119                     referral_connection_timeout - (tv.tv_sec - conn->c_time),
120                     0, 0 );
121                 return;
122         }
123
124
125         conn_del( conn );
126
127         if ( conn->c_paddr )
128                 free( (char *) conn->c_paddr );
129         if ( conn->c_dn )
130                 free( conn->c_dn );
131         if ( conn->c_credlen > 0 )
132                 free( conn->c_cred );
133         free( conn );
134 }
135
136 void
137 conn_del( struct conn *conn )
138 {
139         struct conn     *tmp, *prev;
140
141         Debug( LDAP_DEBUG_TRACE, "conn_del (%s)\n",
142             paddr2str( conn->c_paddr, NULLNA ), 0, 0 );
143
144         prev = NULL;
145         for ( tmp = conns; tmp != NULL; tmp = tmp->c_next ) {
146                 if ( tmp == conn )
147                         break;
148                 prev = tmp;
149         }
150
151         if ( tmp == NULL ) {
152                 Debug( LDAP_DEBUG_ANY, "conn_del: cannot find conn\n", 0, 0,
153                     0 );
154                 return;
155         }
156
157         if ( prev == NULL ) {
158                 conns = conns->c_next;  /* delete head of list */
159         } else {
160                 prev->c_next = tmp->c_next;
161         }
162 }
163
164 void
165 conn_setfds( fd_set *fds )
166 {
167         struct conn     *tmp;
168
169         for ( tmp = conns; tmp != NULL; tmp = tmp->c_next ) {
170                 if ( tmp->c_ad != -1 )
171                         FD_SET( tmp->c_ad, fds );
172         }
173 }
174
175 void
176 conn_badfds()
177 {
178         struct conn     *tmp;
179
180         for ( tmp = conns; tmp != NULL; tmp = tmp->c_next ) {
181                 if ( isclosed( tmp->c_ad ) ) {
182                         Debug( LDAP_DEBUG_ANY, "conn_badfds: fd %d is bad\n",
183                             tmp->c_ad, 0, 0 );
184                         tmp->c_ad = -1;
185                 }
186         }
187 }
188
189 struct conn *conn_getfd( fd_set *fds )
190 {
191         struct conn     *tmp;
192
193         for ( tmp = conns; tmp != NULL; tmp = tmp->c_next ) {
194                 if ( tmp->c_ad != -1 )
195                         if ( FD_ISSET( tmp->c_ad, fds ) )
196                                 return( tmp );
197         }
198
199         return( NULL );
200 }
201
202 void
203 conn_add( struct conn *new )
204 {
205         struct timeval  tv;
206
207 #ifdef LDAP_DEBUG
208         if ( ldap_debug & LDAP_DEBUG_CONNS ) {
209                 char    *str;
210
211                 str = paddr2str( new->c_paddr, NULLNA );
212                 Debug( LDAP_DEBUG_CONNS, "conn_add: (%s)\n", str, 0, 0 );
213         }
214 #endif
215
216         gettimeofday( &tv, (struct timezone *)NULL );
217         new->c_time = tv.tv_sec;
218         new->c_next = conns;
219         new->c_refcnt = 1;
220         conns = new;
221 }
222
223 static psap_cmp( struct PSAPaddr *a, struct PSAPaddr *b )
224 {
225         return( bcmp( (char *) a, (char *) b, sizeof(struct PSAPaddr) ) );
226 }
227
228 struct conn *conn_find( struct conn *c )
229 {
230         struct conn     *tmp;
231
232 #ifdef LDAP_DEBUG
233         if ( ldap_debug & LDAP_DEBUG_CONNS ) {
234                 char    *str;
235
236                 str = paddr2str( c->c_paddr, NULLNA );
237                 Debug( LDAP_DEBUG_CONNS, "conn_find: (%s)\n", str, 0, 0 );
238         }
239 #endif
240         for ( tmp = conns; tmp != NULL; tmp = tmp->c_next ) {
241 #ifdef LDAP_DEBUG
242                 if ( ldap_debug & LDAP_DEBUG_CONNS ) {
243                         char    *str;
244
245                         str = paddr2str( tmp->c_paddr, NULLNA );
246                         Debug( LDAP_DEBUG_CONNS, "conn_find: compare to (%s)\n",
247                             str, 0, 0 );
248                 }
249 #endif
250                 if ( psap_cmp( tmp->c_paddr, c->c_paddr ) == 0
251                     && strcmp( tmp->c_dn, c->c_dn ) == 0
252                     && tmp->c_credlen == c->c_credlen
253                     && bcmp( tmp->c_cred, c->c_cred, c->c_credlen ) == 0 ) {
254                         Debug( LDAP_DEBUG_CONNS, "conn_find: found\n", 0,
255                             0, 0 );
256                         return( tmp );
257                 }
258         }
259
260         Debug( LDAP_DEBUG_CONNS, "conn_find: not found\n", 0, 0, 0 );
261         return( NULL );
262 }
263
264 void
265 conn_close()
266 {
267         struct conn     *tmp;
268
269         for ( tmp = conns; tmp != NULL; tmp = tmp->c_next ) {
270                 if ( tmp->c_ad != -1 )
271                         dap_unbind( tmp->c_ad );
272         }
273 }
274
275 int
276 isclosed( int ad )
277 {
278         int             o;
279         extern int      errno;
280
281         if ( ioctl( ad, FIOGETOWN, &o ) < 0 )
282                 return( errno == EBADF ? 1 : 0 );
283         else
284                 return( 0 );
285 }