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