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