~ubuntu-branches/ubuntu/gutsy/samba/gutsy-updates

« back to all changes in this revision

Viewing changes to source/nsswitch/winbindd_ldap.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Mitchell
  • Date: 2006-11-28 20:14:37 UTC
  • mfrom: (0.10.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061128201437-a6x4lzlhempazocp
Tags: 3.0.23d-1ubuntu1
* Merge from debian unstable.
* Drop python2.4-samba, replace with python-samba. Added Conflicts/Replaces
  on python2.4-samba
* Drop track-connection-dos.patch, ubuntu-winbind-panic.patch, 
  ubuntu-fix-ldap.patch, ubuntu-setlocale.patch, ubuntu-setlocale-fixes.patch
* Remaining Ubuntu changes:
  - Revert Debian's installation of mount.cifs and umount.cifs as suid
  - Comment out the default [homes] shares and add more verbose comments to
    explain what they do and how they work (closes: launchpad.net/27608)
  - Add a "valid users = %S" stanza to the commented-out [homes] section, to
    show users how to restrict access to \\server\username to only username.
  - Change the (commented-out) "printer admin" example to use "@lpadmin"
    instead of "@ntadmin", since the lpadmin group is used for spool admin.
  - Alter the panic-action script to encourage users to report their
    bugs in Ubuntu packages to Ubuntu, rather than reporting to Debian.
    Modify text to more closely match the Debian script
  - Munge our init script to deal with the fact that our implementation
    (or lack thereof) of log_daemon_msg and log_progress_msg differs
    from Debian's implementation of the same (Ubuntu #19691)
  - Kept ubuntu-auxsrc.patch: some auxilliary sources (undocumented in 
    previous changelogs)
  - Set default workgroup to MSHOME

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   Unix SMB/CIFS implementation.
3
 
 
4
 
   winbind ldap proxy code
5
 
 
6
 
   Copyright (C) Volker Lendecke
7
 
   
8
 
   This program is free software; you can redistribute it and/or modify
9
 
   it under the terms of the GNU General Public License as published by
10
 
   the Free Software Foundation; either version 2 of the License, or
11
 
   (at your option) any later version.
12
 
   
13
 
   This program is distributed in the hope that it will be useful,
14
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
   GNU General Public License for more details.
17
 
   
18
 
   You should have received a copy of the GNU General Public License
19
 
   along with this program; if not, write to the Free Software
20
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 
*/
22
 
 
23
 
#include "includes.h"
24
 
#include "winbindd.h"
25
 
 
26
 
/* This rw-buf api is made to avoid memcpy. For now do that like mad...  The
27
 
   idea is to write into a circular list of buffers where the ideal case is
28
 
   that a read(2) holds a complete request that is then thrown away
29
 
   completely. */
30
 
 
31
 
struct ldap_message_queue {
32
 
        struct ldap_message_queue *prev, *next;
33
 
        struct ldap_message *msg;
34
 
};
35
 
 
36
 
struct rw_buffer {
37
 
        uint8 *data;
38
 
        size_t ofs, length;
39
 
};
40
 
 
41
 
struct winbind_ldap_client {
42
 
        struct winbind_ldap_client *next, *prev;
43
 
        int sock;
44
 
        BOOL finished;
45
 
        struct rw_buffer in_buffer, out_buffer;
46
 
};
47
 
 
48
 
static struct winbind_ldap_client *ldap_clients;
49
 
 
50
 
struct winbind_ldap_server {
51
 
        struct winbind_ldap_server *next, *prev;
52
 
        int sock;
53
 
        BOOL ready;             /* Bind successful? */
54
 
        BOOL finished;
55
 
        struct rw_buffer in_buffer, out_buffer;
56
 
        int messageid;
57
 
};
58
 
        
59
 
static struct winbind_ldap_server *ldap_servers;
60
 
 
61
 
struct pending_ldap_message {
62
 
        struct pending_ldap_message *next, *prev;
63
 
        struct ldap_message *msg; /* The message the client sent us */
64
 
        int our_msgid;          /* The messageid we used */
65
 
        struct winbind_ldap_client *client;
66
 
};
67
 
 
68
 
struct pending_ldap_message *pending_messages;
69
 
 
70
 
static BOOL append_to_buf(struct rw_buffer *buf, uint8 *data, size_t length)
71
 
{
72
 
        buf->data = SMB_REALLOC(buf->data, buf->length+length);
73
 
 
74
 
        if (buf->data == NULL)
75
 
                return False;
76
 
 
77
 
        memcpy(buf->data+buf->length, data, length);
78
 
 
79
 
        buf->length += length;
80
 
        return True;
81
 
}
82
 
 
83
 
static BOOL read_into_buf(int fd, struct rw_buffer *buf)
84
 
{
85
 
        char tmp_buf[1024];
86
 
        int len;
87
 
 
88
 
        len = read(fd, tmp_buf, sizeof(tmp_buf));
89
 
        if (len == 0)
90
 
                return False;
91
 
 
92
 
        return append_to_buf(buf, tmp_buf, len);
93
 
}
94
 
 
95
 
static void peek_into_buf(struct rw_buffer *buf, uint8 **out,
96
 
                          size_t *out_length)
97
 
{
98
 
        *out = buf->data;
99
 
        *out_length = buf->length;
100
 
}
101
 
 
102
 
static void consumed_from_buf(struct rw_buffer *buf, size_t length)
103
 
{
104
 
        uint8 *new = memdup(buf->data+length, buf->length-length);
105
 
        free(buf->data);
106
 
        buf->data = new;
107
 
        buf->length -= length;
108
 
}
109
 
 
110
 
static BOOL write_out_of_buf(int fd, struct rw_buffer *buf)
111
 
{
112
 
        uint8 *tmp;
113
 
        size_t tmp_length, written;
114
 
 
115
 
        peek_into_buf(buf, &tmp, &tmp_length);
116
 
        if (tmp_length == 0)
117
 
                return True;
118
 
 
119
 
        written = write(fd, tmp, tmp_length);
120
 
        if (written < 0)
121
 
                return False;
122
 
 
123
 
        consumed_from_buf(buf, written);
124
 
        return True;
125
 
}
126
 
 
127
 
static BOOL ldap_append_to_buf(struct ldap_message *msg, struct rw_buffer *buf)
128
 
{
129
 
        DATA_BLOB blob;
130
 
        BOOL res;
131
 
 
132
 
        if (!ldap_encode(msg, &blob))
133
 
                return False;
134
 
 
135
 
        res = append_to_buf(buf, blob.data, blob.length);
136
 
 
137
 
        data_blob_free(&blob);
138
 
        return res;
139
 
}
140
 
 
141
 
static void new_ldap_client(int listen_sock)
142
 
{
143
 
        struct sockaddr_un sunaddr;
144
 
        struct winbind_ldap_client *client;
145
 
        socklen_t len;
146
 
        int sock;
147
 
        
148
 
        /* Accept connection */
149
 
        
150
 
        len = sizeof(sunaddr);
151
 
 
152
 
        do {
153
 
                sock = accept(listen_sock, (struct sockaddr *)&sunaddr, &len);
154
 
        } while (sock == -1 && errno == EINTR);
155
 
 
156
 
        if (sock == -1)
157
 
                return;
158
 
        
159
 
        DEBUG(6,("accepted socket %d\n", sock));
160
 
        
161
 
        /* Create new connection structure */
162
 
 
163
 
        client = SMB_MALLOC_P(struct winbind_ldap_client);
164
 
 
165
 
        if (client == NULL)
166
 
                return;
167
 
 
168
 
        ZERO_STRUCTP(client);
169
 
        
170
 
        client->sock = sock;
171
 
        client->finished = False;
172
 
        
173
 
        DLIST_ADD(ldap_clients, client);
174
 
}
175
 
 
176
 
static struct ldap_message *get_msg_from_buf(struct rw_buffer *buffer,
177
 
                                             BOOL *error)
178
 
{
179
 
        uint8 *buf;
180
 
        int buf_length, msg_length;
181
 
        DATA_BLOB blob;
182
 
        ASN1_DATA data;
183
 
        struct ldap_message *msg;
184
 
 
185
 
        DEBUG(10,("ldapsrv_recv\n"));
186
 
 
187
 
        *error = False;
188
 
 
189
 
        peek_into_buf(buffer, &buf, &buf_length);
190
 
 
191
 
        if (buf_length < 8) {
192
 
                /* Arbitrary heuristics: ldap messages are longer than eight
193
 
                 * bytes, and their tag length fits into the eight bytes */
194
 
                return NULL;
195
 
        }
196
 
 
197
 
        /* LDAP Messages are always SEQUENCES */
198
 
 
199
 
        if (!asn1_object_length(buf, buf_length, ASN1_SEQUENCE(0),
200
 
                                &msg_length))
201
 
                goto disconnect;
202
 
 
203
 
        if (buf_length < msg_length) {
204
 
                /* Not enough yet */
205
 
                return NULL;
206
 
        }
207
 
 
208
 
        /* We've got a complete LDAP request in the in-buffer */
209
 
 
210
 
        blob.data = buf;
211
 
        blob.length = msg_length;
212
 
 
213
 
        if (!asn1_load(&data, blob))
214
 
                goto disconnect;
215
 
 
216
 
        msg = new_ldap_message();
217
 
 
218
 
        if ((msg == NULL) || !ldap_decode(&data, msg)) {
219
 
                asn1_free(&data);
220
 
                goto disconnect;
221
 
        }
222
 
 
223
 
        asn1_free(&data);
224
 
 
225
 
        consumed_from_buf(buffer, msg_length);
226
 
 
227
 
        return msg;
228
 
 
229
 
 disconnect:
230
 
 
231
 
        *error = True;
232
 
        return NULL;
233
 
}
234
 
 
235
 
static int send_msg_to_server(struct ldap_message *msg,
236
 
                              struct winbind_ldap_server *server)
237
 
{
238
 
        int cli_messageid;
239
 
 
240
 
        cli_messageid = msg->messageid;
241
 
        msg->messageid = ldap_servers->messageid;
242
 
 
243
 
        if (!ldap_append_to_buf(msg, &ldap_servers->out_buffer))
244
 
                return -1;
245
 
 
246
 
        msg->messageid = cli_messageid;
247
 
        return ldap_servers->messageid++;
248
 
}
249
 
 
250
 
static int send_msg(struct ldap_message *msg)
251
 
{
252
 
        /* This is the scheduling routine that should decide where to send
253
 
         * stuff. The first attempt is easy: We only have one server. This
254
 
         * will change once we handle referrals etc. */
255
 
 
256
 
        SMB_ASSERT(ldap_servers != NULL);
257
 
 
258
 
        if (!ldap_servers->ready)
259
 
                return -1;
260
 
 
261
 
        return send_msg_to_server(msg, ldap_servers);
262
 
}
263
 
 
264
 
static void fake_bind_response(struct winbind_ldap_client *client,
265
 
                               int messageid)
266
 
{
267
 
        struct ldap_message *msg = new_ldap_message();
268
 
 
269
 
        if (msg == NULL) {
270
 
                client->finished = True;
271
 
                return;
272
 
        }
273
 
 
274
 
        msg->messageid = messageid;
275
 
        msg->type = LDAP_TAG_BindResponse;
276
 
        msg->r.BindResponse.response.resultcode = 0;
277
 
        msg->r.BindResponse.response.dn = "";
278
 
        msg->r.BindResponse.response.dn = "";
279
 
        msg->r.BindResponse.response.errormessage = "";
280
 
        msg->r.BindResponse.response.referral = "";
281
 
        ldap_append_to_buf(msg, &client->out_buffer);
282
 
        destroy_ldap_message(msg);
283
 
}
284
 
 
285
 
static int open_ldap_socket(void)
286
 
{
287
 
        static int fd = -1;
288
 
 
289
 
        if (fd >= 0)
290
 
                return fd;
291
 
 
292
 
        fd = create_pipe_sock(get_winbind_priv_pipe_dir(), "ldapi", 0750);
293
 
        return fd;
294
 
}
295
 
 
296
 
static BOOL do_sigterm = False;
297
 
 
298
 
static void ldap_termination_handler(int signum)
299
 
{
300
 
        do_sigterm = True;
301
 
        sys_select_signal();
302
 
}
303
 
 
304
 
static BOOL handled_locally(struct ldap_message *msg,
305
 
                            struct winbind_ldap_server *server)
306
 
{
307
 
        struct ldap_Result *r = &msg->r.BindResponse.response;
308
 
 
309
 
        if (msg->type != LDAP_TAG_BindResponse)
310
 
                return False;
311
 
 
312
 
        if (r->resultcode != 0) {
313
 
                destroy_ldap_message(msg);
314
 
                server->finished = True;
315
 
        }
316
 
        destroy_ldap_message(msg);
317
 
        server->ready = True;
318
 
        return True;
319
 
}
320
 
 
321
 
static void client_has_data(struct winbind_ldap_client *client)
322
 
{
323
 
                        
324
 
        struct ldap_message *msg;
325
 
 
326
 
        if (!read_into_buf(client->sock, &client->in_buffer)) {
327
 
                client->finished = True;
328
 
                return;
329
 
        }
330
 
 
331
 
        while ((msg = get_msg_from_buf(&client->in_buffer,
332
 
                                       &client->finished))) {
333
 
                struct pending_ldap_message *pending;
334
 
 
335
 
                if (msg->type == LDAP_TAG_BindRequest) {
336
 
                        fake_bind_response(client, msg->messageid);
337
 
                        destroy_ldap_message(msg);
338
 
                        continue;
339
 
                }
340
 
 
341
 
                if (msg->type == LDAP_TAG_UnbindRequest) {
342
 
                        destroy_ldap_message(msg);
343
 
                        client->finished = True;
344
 
                        break;
345
 
                }
346
 
 
347
 
                pending = SMB_MALLOC_P(struct pending_ldap_message);
348
 
                if (pending == NULL)
349
 
                        continue;
350
 
 
351
 
                pending->msg = msg;
352
 
                pending->client = client;
353
 
                pending->our_msgid = send_msg(msg);
354
 
 
355
 
                if (pending->our_msgid < 0) {
356
 
                        /* could not send */
357
 
                        client->finished = True;
358
 
                        free(pending);
359
 
                }
360
 
                DLIST_ADD(pending_messages, pending);
361
 
        }
362
 
}
363
 
 
364
 
static struct ldap_Result *ldap_msg2result(struct ldap_message *msg)
365
 
{
366
 
        switch(msg->type) {
367
 
        case LDAP_TAG_BindResponse:
368
 
                return &msg->r.BindResponse.response;
369
 
        case LDAP_TAG_SearchResultDone:
370
 
                return &msg->r.SearchResultDone;
371
 
        case LDAP_TAG_ModifyResponse:
372
 
                return &msg->r.ModifyResponse;
373
 
        case LDAP_TAG_AddResponse:
374
 
                return &msg->r.AddResponse;
375
 
        case LDAP_TAG_DelResponse:
376
 
                return &msg->r.DelResponse;
377
 
        case LDAP_TAG_ModifyDNResponse:
378
 
                return &msg->r.ModifyDNResponse;
379
 
        case LDAP_TAG_CompareResponse:
380
 
                return &msg->r.CompareResponse;
381
 
        case LDAP_TAG_ExtendedResponse:
382
 
                return &msg->r.ExtendedResponse.response;
383
 
        }
384
 
        return NULL;
385
 
}
386
 
 
387
 
static void server_has_data(struct winbind_ldap_server *server)
388
 
{
389
 
        struct ldap_message *msg;
390
 
 
391
 
        if (!read_into_buf(server->sock, &server->in_buffer)) {
392
 
                server->finished = True;
393
 
                return;
394
 
        }
395
 
 
396
 
        while ((msg = get_msg_from_buf(&server->in_buffer,
397
 
                                       &server->finished))) {
398
 
                struct pending_ldap_message *pending;
399
 
                struct rw_buffer *buf;
400
 
                struct ldap_Result *res;
401
 
 
402
 
                if (handled_locally(msg, server))
403
 
                        continue;
404
 
 
405
 
                res = ldap_msg2result(msg);
406
 
 
407
 
                if ( (res != NULL) && (res->resultcode == 10) )
408
 
                        DEBUG(5, ("Got Referral %s\n", res->referral));
409
 
 
410
 
                for (pending = pending_messages;
411
 
                     pending != NULL;
412
 
                     pending = pending->next) {
413
 
                        if (pending->our_msgid == msg->messageid)
414
 
                                break;
415
 
                }
416
 
 
417
 
                if (pending == NULL) {
418
 
                        talloc_destroy(msg->mem_ctx);
419
 
                        continue;
420
 
                }
421
 
 
422
 
                msg->messageid = pending->msg->messageid;
423
 
 
424
 
                buf = &pending->client->out_buffer;
425
 
                ldap_append_to_buf(msg, buf);
426
 
 
427
 
                if ( (msg->type != LDAP_TAG_SearchResultEntry) &&
428
 
                     (msg->type != LDAP_TAG_SearchResultReference) ) {
429
 
                        destroy_ldap_message(pending->msg);
430
 
                        DLIST_REMOVE(pending_messages,
431
 
                                     pending);
432
 
                        SAFE_FREE(pending);
433
 
                }
434
 
                destroy_ldap_message(msg);
435
 
        }
436
 
}
437
 
 
438
 
static void process_ldap_loop(void)
439
 
{
440
 
        struct winbind_ldap_client *client;
441
 
        struct winbind_ldap_server *server;
442
 
        fd_set r_fds, w_fds;
443
 
        int maxfd, listen_sock, selret;
444
 
        struct timeval timeout;
445
 
 
446
 
        /* Free up temporary memory */
447
 
 
448
 
        lp_talloc_free();
449
 
        main_loop_talloc_free();
450
 
 
451
 
        if (do_sigterm) {
452
 
#if 0
453
 
                TALLOC_CTX *mem_ctx = talloc_init("describe");
454
 
                DEBUG(0, ("%s\n", talloc_describe_all(mem_ctx)));
455
 
                talloc_destroy(mem_ctx);
456
 
#endif
457
 
                exit(0);
458
 
        }
459
 
 
460
 
        /* Initialise fd lists for select() */
461
 
 
462
 
        listen_sock = open_ldap_socket();
463
 
 
464
 
        if (listen_sock == -1) {
465
 
                perror("open_ldap_socket");
466
 
                exit(1);
467
 
        }
468
 
 
469
 
        maxfd = listen_sock;
470
 
 
471
 
        FD_ZERO(&r_fds);
472
 
        FD_ZERO(&w_fds);
473
 
        FD_SET(listen_sock, &r_fds);
474
 
 
475
 
        timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
476
 
        timeout.tv_usec = 0;
477
 
 
478
 
        /* Set up client readers and writers */
479
 
        
480
 
        client = ldap_clients;
481
 
 
482
 
        while (client != NULL) {
483
 
 
484
 
                if (client->finished) {
485
 
                        struct winbind_ldap_client *next = client->next;
486
 
                        DLIST_REMOVE(ldap_clients, client);
487
 
                        close(client->sock);
488
 
                        SAFE_FREE(client->in_buffer.data);
489
 
                        SAFE_FREE(client->out_buffer.data);
490
 
                        SAFE_FREE(client);
491
 
                        client = next;
492
 
                        continue;
493
 
                }
494
 
 
495
 
                if (client->sock > maxfd)
496
 
                        maxfd = client->sock;
497
 
 
498
 
                FD_SET(client->sock, &r_fds);
499
 
 
500
 
                if (client->out_buffer.length > 0)
501
 
                        FD_SET(client->sock, &w_fds);
502
 
 
503
 
                client = client->next;
504
 
        }
505
 
 
506
 
        /* And now the servers */
507
 
 
508
 
        server = ldap_servers;
509
 
 
510
 
        while (server != NULL) {
511
 
 
512
 
                if (server->finished) {
513
 
                        struct winbind_ldap_server *next = server->next;
514
 
                        DLIST_REMOVE(ldap_servers, server);
515
 
                        close(server->sock);
516
 
                        SAFE_FREE(server);
517
 
                        server = next;
518
 
                        continue;
519
 
                }
520
 
 
521
 
                if (server->sock > maxfd)
522
 
                        maxfd = server->sock;
523
 
 
524
 
                FD_SET(server->sock, &r_fds);
525
 
 
526
 
                if (server->out_buffer.length > 0)
527
 
                        FD_SET(server->sock, &w_fds);
528
 
 
529
 
                server = server->next;
530
 
        }
531
 
 
532
 
        selret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
533
 
 
534
 
        if (selret == 0)
535
 
                return;
536
 
 
537
 
        if (selret == -1 && errno != EINTR) {
538
 
                perror("select");
539
 
                exit(1);
540
 
        }
541
 
 
542
 
        if (FD_ISSET(listen_sock, &r_fds))
543
 
                new_ldap_client(listen_sock);
544
 
 
545
 
        for (client = ldap_clients; client != NULL; client = client->next) {
546
 
 
547
 
                if (FD_ISSET(client->sock, &r_fds))
548
 
                        client_has_data(client);
549
 
 
550
 
                if ((!client->finished) && FD_ISSET(client->sock, &w_fds))
551
 
                        write_out_of_buf(client->sock, &client->out_buffer);
552
 
        }
553
 
 
554
 
        for (server = ldap_servers; server != NULL; server = server->next) {
555
 
 
556
 
                if (FD_ISSET(server->sock, &r_fds))
557
 
                        server_has_data(server);
558
 
 
559
 
                if (!server->finished && FD_ISSET(server->sock, &w_fds))
560
 
                        write_out_of_buf(server->sock, &server->out_buffer);
561
 
        }
562
 
}
563
 
 
564
 
static BOOL setup_ldap_serverconn(void)
565
 
{
566
 
        char *host;
567
 
        uint16 port;
568
 
        BOOL ldaps;
569
 
        struct hostent *hp;
570
 
        struct in_addr ip;
571
 
        TALLOC_CTX *mem_ctx = talloc_init("server");
572
 
        struct ldap_message *msg;
573
 
        char *dn, *pw;
574
 
 
575
 
        ldap_servers = SMB_MALLOC_P(struct winbind_ldap_server);
576
 
 
577
 
        if ((ldap_servers == NULL) || (mem_ctx == NULL))
578
 
                return False;
579
 
 
580
 
        if (!ldap_parse_basic_url(mem_ctx, "ldap://192.168.234.1:3899/",
581
 
                                  &host, &port, &ldaps))
582
 
                return False;
583
 
        
584
 
        hp = sys_gethostbyname(host);
585
 
 
586
 
        if ((hp == NULL) || (hp->h_addr == NULL))
587
 
                return False;
588
 
 
589
 
        putip((char *)&ip, (char *)hp->h_addr);
590
 
 
591
 
        ZERO_STRUCTP(ldap_servers);
592
 
        ldap_servers->sock = open_socket_out(SOCK_STREAM, &ip, port, 10000);
593
 
        ldap_servers->messageid = 1;
594
 
 
595
 
        if (!fetch_ldap_pw(&dn, &pw))
596
 
                return False;
597
 
 
598
 
        msg = new_ldap_simple_bind_msg(dn, pw);
599
 
 
600
 
        SAFE_FREE(dn);
601
 
        SAFE_FREE(pw);
602
 
 
603
 
        if (msg == NULL)
604
 
                return False;
605
 
 
606
 
        msg->messageid = ldap_servers->messageid++;
607
 
 
608
 
        ldap_append_to_buf(msg, &ldap_servers->out_buffer);
609
 
 
610
 
        destroy_ldap_message(msg);
611
 
 
612
 
        return (ldap_servers->sock >= 0);
613
 
}
614
 
 
615
 
void do_ldap_proxy(void)
616
 
{
617
 
        int ldap_child;
618
 
 
619
 
        ldap_child = sys_fork();
620
 
 
621
 
        if (ldap_child != 0)
622
 
                return;
623
 
 
624
 
        /* tdb needs special fork handling */
625
 
        if (tdb_reopen_all() == -1) {
626
 
                DEBUG(0,("tdb_reopen_all failed.\n"));
627
 
                _exit(0);
628
 
        }
629
 
 
630
 
        if (!message_init()) {
631
 
                DEBUG(0, ("message_init failed\n"));
632
 
                _exit(0);
633
 
        }
634
 
 
635
 
        CatchSignal(SIGINT, ldap_termination_handler);
636
 
        CatchSignal(SIGQUIT, ldap_termination_handler);
637
 
        CatchSignal(SIGTERM, ldap_termination_handler);
638
 
 
639
 
        if (!setup_ldap_serverconn())
640
 
                return;
641
 
 
642
 
        while (1)
643
 
                process_ldap_loop();
644
 
 
645
 
        return;
646
 
}