]> git.sur5r.net Git - openldap/blob - servers/ldapd/main.c
f32c05b2207cf9514e0afdf5af9e0c8b167a8037
[openldap] / servers / ldapd / main.c
1 /*
2  * Copyright (c) 1990-1996 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  * Some code fragments to run from inetd stolen from the University
14  * of Minnesota gopher distribution, which had this copyright on it:
15  *
16  * Part of the Internet Gopher program, copyright (C) 1991
17  * University of Minnesota Microcomputer Workstation and Networks Center
18  */
19
20 #include "portable.h"
21
22 #include <stdio.h>
23
24 #include <ac/signal.h>
25 #include <ac/socket.h>
26 #include <ac/string.h>
27 #include <ac/syslog.h>
28 #include <ac/time.h>
29 #include <ac/unistd.h>
30 #include <ac/wait.h>
31
32 #ifdef LDAP_PROCTITLE
33 #include <ac/setproctitle.h>
34 #endif
35
36 #include <quipu/commonarg.h>
37 #include <quipu/ds_error.h>
38
39 #include "lber.h"
40 #include "ldap.h"
41 #include "common.h"
42 #include "lutil.h"              /* Get lutil_detach() */
43
44 #ifdef HAVE_TCPD
45 #include <tcpd.h>
46
47 int allow_severity = LOG_INFO;
48 int deny_severity = LOG_NOTICE;
49 #endif /* TCP_WRAPPERS */
50
51 static int      set_socket( int port, int udp );
52 static void     do_queries( int clientsock, int udp );
53 static RETSIGTYPE wait4child( int sig );
54 #ifdef LDAP_CONNECTIONLESS
55 static int      udp_init( int port, int createsocket );
56 #endif
57
58 #ifdef LDAP_DEBUG
59 int     ldap_debug;
60 #endif
61 int     version;
62 #ifdef LDAP_COMPAT
63 int     ldap_compat;
64 #endif
65 int     dosyslog;
66 int     do_tcp = 1;
67 #ifdef LDAP_CONNECTIONLESS
68 int     do_udp = 0;
69 #endif
70 int     idletime = DEFAULT_TIMEOUT;
71 int     referral_connection_timeout = DEFAULT_REFERRAL_TIMEOUT;
72 struct timeval  conn_start_tv;
73 #ifdef HAVE_KERBEROS
74 char    *krb_ldap_service = "ldapserver";
75 char    *krb_x500_service = "x500dsa";
76 char    *krb_x500_instance;
77 char    *krb_x500_nonce;
78 char    *kerberos_keyfile;
79 #endif
80
81 int     dtblsize;
82 int     RunFromInetd = 0;
83
84 static void
85 usage( char *name )
86 {
87         fprintf( stderr, "usage: %s [-d debuglvl] [-p port] [-l] [-c dsa] [-r referraltimeout]", name );
88 #ifdef LDAP_CONNECTIONLESS
89         fprintf( stderr, " [ -U | -t timeout ]" );
90 #else
91         fprintf( stderr, " [ -t timeout ]" );
92 #endif
93         fprintf( stderr, " [-I]" );
94 #ifdef HAVE_KERBEROS
95         fprintf( stderr, " [-i dsainstance]" );
96 #endif
97         fprintf( stderr, "\n" );
98 }
99
100 int
101 main( int argc, char **argv )
102 {
103         int                     tcps, ns;
104 #ifdef LDAP_CONNECTIONLESS
105         int                     udps;
106 #endif
107         int                     myport = LDAP_PORT;
108         int                     i, pid, socktype;
109         char                    *myname;
110         fd_set                  readfds;
111         struct hostent          *hp;
112         struct sockaddr_in      from;
113         int                     len;
114         int                     dsapargc;
115         char                    **dsapargv;
116 #ifdef LDAP_PROCTITLE
117         char                    title[80];
118 #endif
119
120 #ifdef VMS
121         /* Pick up socket from inetd-type server on VMS */
122         if ( (ns = socket_from_server( NULL )) > 0 )
123                 RunFromInetd = 1;
124 #else
125         /* Socket from inetd is usually 0 */
126         ns = 0;
127 #endif
128
129         /* for dsap_init */
130         if ( (dsapargv = (char **) malloc( 4 * sizeof(char *) )) == NULL ) {
131                 perror( "malloc" );
132                 exit( 1 );
133         }
134         dsapargv[0] = argv[0];
135         dsapargv[1] = 0;
136         dsapargv[2] = 0;
137         dsapargv[3] = 0;
138         dsapargc = 1;
139 #ifdef HAVE_KERBEROS
140         kerberos_keyfile = "";
141 #endif
142
143         /* process command line arguments */
144         while ( (i = getopt( argc, argv, "d:lp:f:i:c:r:t:IuU" )) != EOF ) {
145                 switch ( i ) {
146                 case 'c':       /* specify dsa to contact */
147                         dsapargv[1] = "-call";
148                         dsapargv[2] = strdup( optarg );
149                         dsapargc = 3;
150                         break;
151
152                 case 'd':       /* turn on debugging */
153 #ifdef LDAP_DEBUG
154                         ldap_debug = atoi( optarg );
155                         if ( ldap_debug & LDAP_DEBUG_PACKETS )
156                                 lber_debug = ldap_debug;
157 #else
158                         fprintf( stderr, "Not compiled with -DLDAP_DEBUG!\n" );
159 #endif
160                         break;
161
162                 case 'l':       /* do syslogging */
163                         dosyslog = 1;
164                         break;
165
166                 case 'p':       /* specify port number */
167                         myport = atoi( optarg );
168                         break;
169
170                 case 'r':       /* timeout for referral connections */
171                         referral_connection_timeout = atoi( optarg );
172                         break;
173
174                 case 't':       /* timeout for idle connections */
175                         idletime = atoi( optarg );
176                         break;
177
178 #ifdef HAVE_KERBEROS
179                 case 'f':       /* kerberos key file */
180                         kerberos_keyfile = strdup( optarg );
181                         break;
182
183                 case 'i':       /* x500 dsa kerberos instance */
184                         if ( krb_x500_instance != NULL )
185                                 free( krb_x500_instance );
186                         krb_x500_instance = strdup( optarg );
187                         break;
188 #endif
189
190                 case 'I':       /* Run from inetd */
191                         RunFromInetd = 1;
192                         break;
193
194 #ifdef LDAP_CONNECTIONLESS
195                 case 'U':       /* UDP only (no TCP) */
196                         do_tcp = 0;
197                         do_udp = 1;
198                         break;
199
200 #ifdef NOTYET
201                 case 'u':       /* allow UDP requests (CLDAP) */
202                         do_udp = 1;
203                         break;
204 #endif /* NOTYET */
205
206 #endif /* LDAP_CONNECTIONLESS */
207
208                 default:
209                         usage( argv[0] );
210                         exit( 1 );
211                 }
212         }
213
214         if ( optind < argc ) {
215                 usage( argv[ 0 ] );
216                 exit( 1 );
217         }
218
219 #ifdef LDAP_CONNECTIONLESS
220         if ( do_udp && !do_tcp && idletime != DEFAULT_TIMEOUT ) {
221                 usage( argv[ 0 ] );
222                 exit( 1 );
223         }
224 #endif
225
226         Debug( LDAP_DEBUG_TRACE, "%s", Versionstr, 0, 0 );
227
228 #ifdef HAVE_SYSCONF
229         dtblsize = sysconf( _SC_OPEN_MAX );
230 #elif HAVE_GETDTABLESIZE
231         dtblsize = getdtablesize();
232 #else
233         dtblsize = FD_SETSIZE;
234 #endif
235
236 #ifdef FD_SETSIZE
237         if( dtblsize > FD_SETSIZE ) {
238                 dtblsize = FD_SETSIZE;
239         }
240 #endif /* FD_SETSIZE */
241
242 #if defined(LDAP_PROCTITLE) && !defined( HAVE_SETPROCTITLE )
243         /* for setproctitle */
244         Argv = argv;
245         Argc = argc;
246 #endif
247
248         if ( (myname = strrchr( argv[0], '/' )) == NULL )
249                 myname = strdup( argv[0] );
250         else
251                 myname = strdup( myname + 1 );
252
253         /* 
254          * detach from the terminal if stderr is redirected or no
255          * debugging is wanted, and then arrange to reap children
256          * that have exited
257          */
258         if (!RunFromInetd) {
259 #ifdef LDAP_PROCTITLE
260                 setproctitle( "initializing" );
261 #endif
262 #ifndef VMS
263 #  ifdef LDAP_DEBUG
264                 lutil_detach( ldap_debug, 1 );
265 #  else
266                 lutil_detach( 0, 1 );
267 #  endif
268 #endif
269                 (void) SIGNAL( SIGCHLD, wait4child );
270                 (void) SIGNAL( SIGINT, log_and_exit );
271         }
272
273         /* 
274          * set up syslogging (if desired)
275          */
276         if ( dosyslog ) {
277 #ifdef LOG_LOCAL4
278                 openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL4 );
279 #else
280                 openlog( myname, OPENLOG_OPTIONS );
281 #endif
282         }
283
284         /* 
285          * load the syntax handlers, oidtables, and initialize some stuff,
286          * then start listening
287          */
288
289         (void) quipu_syntaxes();
290 #ifdef LDAP_USE_PP
291         (void) pp_quipu_init( argv[0] );
292 #endif
293 #if ISODEPACKAGE == IC
294 #if ICRELEASE > 2
295         dsa_operation_syntaxes();
296 #endif
297 #endif
298         (void) dsap_init( &dsapargc, &dsapargv );
299         (void) get_syntaxes();
300         if (RunFromInetd) {
301                 len = sizeof( socktype );
302                 getsockopt( ns, SOL_SOCKET, SO_TYPE, (char *)&socktype, &len );
303                 if ( socktype == SOCK_DGRAM ) {
304 #ifdef LDAP_CONNECTIONLESS
305                         Debug( LDAP_DEBUG_ARGS,
306                             "CLDAP request from unknown (%s)\n",
307                             inet_ntoa( from.sin_addr ), 0, 0 );
308                         conn_start_tv.tv_sec = 0;
309                         udp_init( 0, 0 );
310                         do_queries( ns, 1 );
311 #else /* LDAP_CONNECTIONLESS */
312                         Debug( LDAP_DEBUG_ARGS,
313                             "Compile with -DLDAP_CONNECTIONLESS for UDP support\n",0,0,0 );
314 #endif /* LDAP_CONNECTIONLESS */
315                         exit( 0 );
316                 }
317
318                 len = sizeof(from);
319                 if ( getpeername( ns, (struct sockaddr *) &from, &len )
320                     == 0 ) {
321                         hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
322                         sizeof(from.sin_addr.s_addr), AF_INET );
323                         Debug( LDAP_DEBUG_ARGS, "connection from %s (%s)\n",
324                             (hp == NULL) ? "unknown" : hp->h_name,
325                             inet_ntoa( from.sin_addr ), 0 );
326
327                         if ( dosyslog ) {
328                                 syslog( LOG_INFO, "connection from %s (%s)",
329                                     (hp == NULL) ? "unknown" : hp->h_name,
330                                     inet_ntoa( from.sin_addr ) );
331                         }
332
333 #ifdef LDAP_PROCTITLE
334                         sprintf( title, "%s %d\n", hp == NULL ?
335                             inet_ntoa( from.sin_addr ) : hp->h_name, myport );
336                         setproctitle( title );
337 #endif
338                 }
339                 gettimeofday( &conn_start_tv, (struct timezone *) NULL );
340                 do_queries( ns, 0 );
341
342                 exit( 0 );
343         }
344
345         if ( do_tcp )
346             tcps = set_socket( myport, 0 );
347
348 #ifdef LDAP_CONNECTIONLESS
349         if ( do_udp )
350                 udps = udp_init( myport, 1 );
351 #endif
352
353         /*
354          * loop, wait for a connection, then fork off a child to handle it
355          * if we are doing CLDAP as well, handle those requests on the fly
356          */
357
358 #ifdef LDAP_PROCTITLE
359 #ifdef LDAP_CONNECTIONLESS
360         sprintf( title, "listening %s/%s %d", do_tcp ? "tcp" : "",
361             do_udp ? "udp" : "", myport );
362 #else
363         sprintf( title, "listening %s %d", do_tcp ? "tcp" : "", myport );
364 #endif
365         setproctitle( title );
366 #endif
367
368         for ( ;; ) {
369                 FD_ZERO( &readfds );
370                 if ( do_tcp )
371                         FD_SET( tcps, &readfds );
372 #ifdef LDAP_CONNECTIONLESS
373                 if ( do_udp )
374                         FD_SET( udps, &readfds );
375 #endif
376
377                 if ( select( dtblsize, &readfds, 0, 0, 0 ) < 1 ) {
378 #ifdef LDAP_DEBUG
379                         if ( ldap_debug ) perror( "main select" );
380 #endif
381                         continue;
382                 }
383
384 #ifdef LDAP_CONNECTIONLESS
385                 if ( do_udp && FD_ISSET( udps, &readfds ) ) {
386                         do_queries( udps, 1 );
387                 }
388 #endif
389
390                 if ( !do_tcp || ! FD_ISSET( tcps, &readfds ) ) {
391                         continue;
392                 }
393
394                 len = sizeof(from);
395                 if ( (ns = accept( tcps, (struct sockaddr *) &from, &len ))
396                     == -1 ) {
397 #ifdef LDAP_DEBUG
398                         if ( ldap_debug ) perror( "accept" );
399 #endif
400                         continue;
401                 }
402
403                 hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
404                     sizeof(from.sin_addr.s_addr), AF_INET );
405
406 #ifdef HAVE_TCPD
407                 if ( !hosts_ctl("ldapd", (hp == NULL) ? "unknown" : hp->h_name,
408                         inet_ntoa( from.sin_addr ), STRING_UNKNOWN ) {
409
410                         Debug( LDAP_DEBUG_ARGS, "connection from %s (%s) denied.\n",
411                                 (hp == NULL) ? "unknown" : hp->h_name,
412                                 inet_ntoa( from.sin_addr ), 0 );
413
414                         if ( dosyslog ) {
415                                 syslog( LOG_NOTICE, "connection from %s (%s) denied.",
416                                     (hp == NULL) ? "unknown" : hp->h_name,
417                                     inet_ntoa( from.sin_addr ) );
418                         }
419
420                         close(ns);
421                         continue;
422                 }
423 #endif /* TCP_WRAPPERS */
424
425                 Debug( LDAP_DEBUG_ARGS, "connection from %s (%s)\n",
426                     (hp == NULL) ? "unknown" : hp->h_name,
427                     inet_ntoa( from.sin_addr ), 0 );
428
429
430                 if ( dosyslog ) {
431                         syslog( LOG_INFO, "connection from %s (%s)",
432                             (hp == NULL) ? "unknown" : hp->h_name,
433                             inet_ntoa( from.sin_addr ) );
434                 }
435
436 #ifdef VMS
437                 /* This is for debug on terminal on VMS */
438                 close( tcps );
439 #ifdef LDAP_PROCTITLE
440                 setproctitle( hp == NULL ? inet_ntoa( from.sin_addr ) :
441                     hp->h_name );
442 #endif
443                 gettimeofday( &conn_start_tv, (struct timezone *) NULL );
444                 (void) SIGNAL( SIGPIPE, log_and_exit );
445
446                 do_queries( ns, 0 );
447                 /* NOT REACHED */
448 #endif
449
450                 switch( pid = fork() ) {
451                 case 0:         /* child */
452                         close( tcps );
453 #ifdef LDAP_PROCTITLE
454                         sprintf( title, "%s (%d)\n", hp == NULL ?
455                                 inet_ntoa( from.sin_addr ) : hp->h_name,
456                                 myport );
457                         setproctitle( title );
458 #endif
459                         gettimeofday( &conn_start_tv, (struct timezone *) NULL );
460                         (void) SIGNAL( SIGPIPE, log_and_exit );
461
462                         do_queries( ns, 0 );
463                         break;
464
465                 case -1:        /* failed */
466 #ifdef LDAP_DEBUG
467                         if ( ldap_debug ) perror( "fork" );
468 #endif
469                         close( ns );
470                         syslog( LOG_ERR, "fork failed %m" );
471                         /* let things cool off */
472                         sleep( 15 );
473                         break;
474
475                 default:        /* parent */
476                         close( ns );
477                         Debug( LDAP_DEBUG_TRACE, "forked child %d\n", pid, 0,
478                             0 );
479                         break;
480                 }
481         }
482         /* NOT REACHED */
483 }
484
485 static void
486 do_queries(
487     int clientsock,
488     int udp             /* is this a UDP (CLDAP) request? */
489 )
490 {
491         fd_set          readfds;
492         int             rc;
493         struct timeval  timeout;
494         Sockbuf         sb;
495 #ifdef LDAP_CONNECTIONLESS
496         struct sockaddr saddr, faddr;
497         struct sockaddr *saddrlist[ 1 ];
498 #endif /* LDAP_CONNECTIONLESS */
499
500         Debug( LDAP_DEBUG_TRACE, "do_queries%s\n",
501             udp ? " udp" : "", 0, 0 );
502
503         /*
504          * Loop, wait for a request from the client or a response from
505          * a dsa, then handle it.  Dsap_ad is always a connection to the
506          * "default" dsa.  Other connections can be made as a result of
507          * a referral being chased down.  These association descriptors
508          * are kept track of with the message that caused the referral.
509          * The set_dsa_fds() routine traverses the list of outstanding
510          * messages, setting the appropriate bits in readfds.
511          */
512
513         if ( !udp ) {
514                 conn_init();
515         }
516
517         (void) memset( (void *) &sb, '\0', sizeof( sb ) );
518         sb.sb_sd = clientsock;
519         sb.sb_naddr = ( udp ) ? 1 : 0;
520 #ifdef LDAP_CONNECTIONLESS
521         sb.sb_addrs = (void **)saddrlist;
522         sb.sb_fromaddr = &faddr;
523         sb.sb_useaddr = saddrlist[ 0 ] = &saddr;
524 #endif
525         sb.sb_ber.ber_buf = NULL;
526         sb.sb_ber.ber_ptr = NULL;
527         sb.sb_ber.ber_end = NULL;
528
529         timeout.tv_sec = idletime;
530         timeout.tv_usec = 0;
531         for ( ;; ) {
532                 struct conn             *dsaconn;
533
534                 FD_ZERO( &readfds );
535                 FD_SET( clientsock, &readfds );
536                 conn_setfds( &readfds );
537
538 #ifdef LDAP_DEBUG
539                 if ( ldap_debug & LDAP_DEBUG_CONNS ) {
540                         int i;
541                         Debug( LDAP_DEBUG_CONNS, "FDLIST:", 0, 0, 0 );
542                         for ( i = 0; i < dtblsize; i++ ) {
543                                 if ( FD_ISSET( i, &readfds ) ) {
544                                         Debug( LDAP_DEBUG_CONNS, " %d", i, 0,
545                                             0);
546                                 }
547                         }
548                         Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
549                 }
550 #endif
551
552                 /* 
553                  * hack - because of lber buffering, there might be stuff
554                  * already waiting for us on the client sock.
555                  */
556
557                 if ( sb.sb_ber.ber_ptr >= sb.sb_ber.ber_end ) {
558                         if ( (rc = select( dtblsize, &readfds, 0, 0,
559                             udp ? 0 : &timeout )) < 1 ) {
560 #ifdef LDAP_DEBUG
561                                 if ( ldap_debug ) perror( "do_queries select" );
562 #endif
563                                 if ( rc == 0 )
564                                         log_and_exit( 0 ); /* idle timeout */
565
566                                 Debug( LDAP_DEBUG_ANY, "select returns %d!\n",
567                                     rc, 0, 0 );
568
569                                 /* client gone away - we can too */
570                                 if ( isclosed( clientsock ) )
571                                         log_and_exit( 0 );
572
573                                 /*
574                                  * check if a dsa conn has gone away -
575                                  * mark it bad if so
576                                  */
577                                 conn_badfds();
578
579                                 continue;
580                         }
581                 }
582
583                 if ( sb.sb_ber.ber_ptr < sb.sb_ber.ber_end ||
584                     FD_ISSET( clientsock, &readfds ) ) {
585                         client_request( &sb, conns, udp );
586                 } else {
587                         if ( (dsaconn = conn_getfd( &readfds )) == NULL ) {
588                                 Debug( LDAP_DEBUG_ANY, "No DSA activity!\n",
589                                     0, 0, 0 );
590                                 continue;
591                         }
592
593                         dsa_response( dsaconn, &sb );
594                 }
595         }
596         /* NOT REACHED */
597 }
598
599 static int
600 set_socket(
601     int port,
602     int udp     /* UDP port? */
603 )
604 {
605         int                     s, i;
606         struct sockaddr_in      addr;
607
608         if ( (s = socket( AF_INET, udp ? SOCK_DGRAM:SOCK_STREAM, 0 )) == -1 ) {
609                 perror( "socket" );
610                 exit( 1 );
611         }
612
613         /* set option so clients can't keep us from coming back up */
614         i = 1;
615         if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (void *) &i, sizeof(i) )
616             < 0 ) {
617                 perror( "setsockopt" );
618                 exit( 1 );
619         }
620
621         /* bind to a name */
622         (void)memset( (void *)&addr, '\0', sizeof( addr ));
623         addr.sin_family = AF_INET;
624         addr.sin_addr.s_addr = INADDR_ANY;
625         addr.sin_port = htons( port );
626         if ( bind( s, (struct sockaddr *) &addr, sizeof(addr) ) ) {
627                 perror( "bind" );
628                 exit( 1 );
629         }
630
631         if ( !udp ) {
632                 /* listen for connections */
633                 if ( listen( s, 5 ) == -1 ) {
634                         perror( "listen" );
635                         exit( 1 );
636                 }
637         }
638  
639         Debug( LDAP_DEBUG_TRACE, "listening on %s port %d\n",
640                 udp ? "udp" : "tcp", port, 0 );
641
642         return( s );
643 }
644
645 static RETSIGTYPE
646 wait4child( int sig )
647 {
648 #ifndef HAVE_WAITPID
649         WAITSTATUSTYPE     status;
650 #endif
651
652         Debug( LDAP_DEBUG_TRACE, "parent: catching child status\n", 0, 0, 0 );
653
654 #ifdef HAVE_WAITPID
655         while( waitpid( (pid_t) -1, (int *) NULL, WAIT_FLAGS ) > 0 )
656                 ;       /* NULL */
657 #else
658         while ( wait4( (pid_t) -1, &status, WAIT_FLAGS, 0 ) > 0 )
659                 ;       /* NULL */
660 #endif
661
662         (void) SIGNAL( SIGCHLD, wait4child );
663 }
664
665
666 RETSIGTYPE
667 log_and_exit( int exitcode )
668 {
669         struct timeval  tv;
670
671         if ( dosyslog ) {
672                 if ( conn_start_tv.tv_sec == 0 ) {
673                         syslog( LOG_INFO, "UDP exit(%d)", exitcode );
674                 } else {
675                         gettimeofday( &tv, (struct timezone *)NULL );
676                         syslog( LOG_INFO, "TCP closed %d seconds,  exit(%d)",
677                             tv.tv_sec - conn_start_tv.tv_sec, exitcode );
678                 }
679         }
680
681         exit( exitcode );
682 }
683
684
685 #ifdef LDAP_CONNECTIONLESS
686 static int
687 udp_init(
688     int port,
689     int createsocket
690 )
691 {
692         int     s, bound;
693         char    *matched;
694
695         if ( createsocket )
696                 s = set_socket( port, 1 );
697
698         conn_init();
699         conns->c_dn = strdup("");
700         conns->c_cred = strdup("");
701         conns->c_credlen = 0;
702         conns->c_method = LDAP_AUTH_SIMPLE;
703
704        if ( dsa_address == NULL || (conns->c_paddr = str2paddr( dsa_address ))
705             == NULLPA ) {
706                 fprintf(stderr, "Bad DSA address (%s)\n", dsa_address ?
707                     dsa_address : "NULL" );
708                 exit( 1 );
709         } else {
710                 conns->c_paddr = psap_cpy(conns->c_paddr);
711         }
712
713         if ( do_bind_real(conns, &bound, &matched) != LDAP_SUCCESS) {
714                 fprintf(stderr, "Cannot bind to directory\n");
715                 exit( 1 );
716         }
717         if ( matched != NULL )
718                 free( matched );
719
720         return( createsocket ? s : 0 );
721 }
722 #endif