e196fbf46f71687990eb78cfa7d9fb276fc984f8
[obnox/samba/samba-obnox.git] / source4 / ldap_server / ldap_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    LDAP server
5
6    Copyright (C) Andrew Tridgell 2005
7    Copyright (C) Volker Lendecke 2004
8    Copyright (C) Stefan Metzmacher 2004
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "system/network.h"
26 #include "lib/events/events.h"
27 #include "auth/auth.h"
28 #include "auth/credentials/credentials.h"
29 #include "librpc/gen_ndr/ndr_samr.h"
30 #include "../lib/util/dlinklist.h"
31 #include "../lib/util/asn1.h"
32 #include "ldap_server/ldap_server.h"
33 #include "smbd/service_task.h"
34 #include "smbd/service_stream.h"
35 #include "smbd/service.h"
36 #include "smbd/process_model.h"
37 #include "lib/tls/tls.h"
38 #include "lib/messaging/irpc.h"
39 #include "lib/ldb/include/ldb.h"
40 #include "lib/ldb/include/ldb_errors.h"
41 #include "libcli/ldap/ldap_proto.h"
42 #include "system/network.h"
43 #include "lib/socket/netif.h"
44 #include "dsdb/samdb/samdb.h"
45 #include "param/param.h"
46 #include "../lib/tsocket/tsocket.h"
47 #include "../lib/util/tevent_ntstatus.h"
48 #include "../libcli/util/tstream.h"
49
50 static void ldapsrv_terminate_connection_done(struct tevent_req *subreq);
51
52 /*
53   close the socket and shutdown a server_context
54 */
55 static void ldapsrv_terminate_connection(struct ldapsrv_connection *conn,
56                                          const char *reason)
57 {
58         struct tevent_req *subreq;
59
60         if (conn->limits.reason) {
61                 return;
62         }
63
64         conn->limits.endtime = timeval_current_ofs(0, 500);
65
66         DEBUG(2,("ldapsrv_terminate_connection: %s - disconnecting\n",
67                  reason));
68
69         tevent_queue_stop(conn->sockets.send_queue);
70         if (conn->active_call) {
71                 tevent_req_cancel(conn->active_call);
72                 conn->active_call = NULL;
73         }
74
75         conn->limits.reason = talloc_strdup(conn, reason);
76         if (conn->limits.reason == NULL) {
77                 TALLOC_FREE(conn->sockets.tls);
78                 TALLOC_FREE(conn->sockets.sasl);
79                 TALLOC_FREE(conn->sockets.raw);
80                 stream_terminate_connection(conn->connection, reason);
81                 return;
82         }
83
84         subreq = tstream_disconnect_send(conn,
85                                          conn->connection->event.ctx,
86                                          conn->sockets.active);
87         if (subreq == NULL) {
88                 TALLOC_FREE(conn->sockets.tls);
89                 TALLOC_FREE(conn->sockets.sasl);
90                 TALLOC_FREE(conn->sockets.raw);
91                 stream_terminate_connection(conn->connection, reason);
92                 return;
93         }
94         tevent_req_set_endtime(subreq,
95                                conn->connection->event.ctx,
96                                conn->limits.endtime);
97         tevent_req_set_callback(subreq, ldapsrv_terminate_connection_done, conn);
98 }
99
100 static void ldapsrv_terminate_connection_done(struct tevent_req *subreq)
101 {
102         struct ldapsrv_connection *conn =
103                 tevent_req_callback_data(subreq,
104                 struct ldapsrv_connection);
105         int ret;
106         int sys_errno;
107
108         ret = tstream_disconnect_recv(subreq, &sys_errno);
109         TALLOC_FREE(subreq);
110
111         if (conn->sockets.active == conn->sockets.raw) {
112                 TALLOC_FREE(conn->sockets.tls);
113                 TALLOC_FREE(conn->sockets.sasl);
114                 TALLOC_FREE(conn->sockets.raw);
115                 stream_terminate_connection(conn->connection,
116                                             conn->limits.reason);
117                 return;
118         }
119
120         TALLOC_FREE(conn->sockets.tls);
121         TALLOC_FREE(conn->sockets.sasl);
122         conn->sockets.active = conn->sockets.raw;
123
124         subreq = tstream_disconnect_send(conn,
125                                          conn->connection->event.ctx,
126                                          conn->sockets.active);
127         if (subreq == NULL) {
128                 TALLOC_FREE(conn->sockets.raw);
129                 stream_terminate_connection(conn->connection,
130                                             conn->limits.reason);
131                 return;
132         }
133         tevent_req_set_endtime(subreq,
134                                conn->connection->event.ctx,
135                                conn->limits.endtime);
136         tevent_req_set_callback(subreq, ldapsrv_terminate_connection_done, conn);
137 }
138
139 /*
140   called when a LDAP socket becomes readable
141 */
142 void ldapsrv_recv(struct stream_connection *c, uint16_t flags)
143 {
144         smb_panic(__location__);
145 }
146
147 /*
148   called when a LDAP socket becomes writable
149 */
150 static void ldapsrv_send(struct stream_connection *c, uint16_t flags)
151 {
152         smb_panic(__location__);
153 }
154
155 static int ldapsrv_load_limits(struct ldapsrv_connection *conn)
156 {
157         TALLOC_CTX *tmp_ctx;
158         const char *attrs[] = { "configurationNamingContext", NULL };
159         const char *attrs2[] = { "lDAPAdminLimits", NULL };
160         struct ldb_message_element *el;
161         struct ldb_result *res = NULL;
162         struct ldb_dn *basedn;
163         struct ldb_dn *conf_dn;
164         struct ldb_dn *policy_dn;
165         unsigned int i;
166         int ret;
167
168         /* set defaults limits in case of failure */
169         conn->limits.initial_timeout = 120;
170         conn->limits.conn_idle_time = 900;
171         conn->limits.max_page_size = 1000;
172         conn->limits.search_timeout = 120;
173
174
175         tmp_ctx = talloc_new(conn);
176         if (tmp_ctx == NULL) {
177                 return -1;
178         }
179
180         basedn = ldb_dn_new(tmp_ctx, conn->ldb, NULL);
181         if ( ! ldb_dn_validate(basedn)) {
182                 goto failed;
183         }
184
185         ret = ldb_search(conn->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_BASE, attrs, NULL);
186         if (ret != LDB_SUCCESS) {
187                 goto failed;
188         }
189
190         if (res->count != 1) {
191                 goto failed;
192         }
193
194         conf_dn = ldb_msg_find_attr_as_dn(conn->ldb, tmp_ctx, res->msgs[0], "configurationNamingContext");
195         if (conf_dn == NULL) {
196                 goto failed;
197         }
198
199         policy_dn = ldb_dn_copy(tmp_ctx, conf_dn);
200         ldb_dn_add_child_fmt(policy_dn, "CN=Default Query Policy,CN=Query-Policies,CN=Directory Service,CN=Windows NT,CN=Services");
201         if (policy_dn == NULL) {
202                 goto failed;
203         }
204
205         ret = ldb_search(conn->ldb, tmp_ctx, &res, policy_dn, LDB_SCOPE_BASE, attrs2, NULL);
206         if (ret != LDB_SUCCESS) {
207                 goto failed;
208         }
209
210         if (res->count != 1) {
211                 goto failed;
212         }
213
214         el = ldb_msg_find_element(res->msgs[0], "lDAPAdminLimits");
215         if (el == NULL) {
216                 goto failed;
217         }
218
219         for (i = 0; i < el->num_values; i++) {
220                 char policy_name[256];
221                 int policy_value, s;
222
223                 s = sscanf((const char *)el->values[i].data, "%255[^=]=%d", policy_name, &policy_value);
224                 if (ret != 2 || policy_value == 0)
225                         continue;
226
227                 if (strcasecmp("InitRecvTimeout", policy_name) == 0) {
228                         conn->limits.initial_timeout = policy_value;
229                         continue;
230                 }
231                 if (strcasecmp("MaxConnIdleTime", policy_name) == 0) {
232                         conn->limits.conn_idle_time = policy_value;
233                         continue;
234                 }
235                 if (strcasecmp("MaxPageSize", policy_name) == 0) {
236                         conn->limits.max_page_size = policy_value;
237                         continue;
238                 }
239                 if (strcasecmp("MaxQueryDuration", policy_name) == 0) {
240                         conn->limits.search_timeout = policy_value;
241                         continue;
242                 }
243         }
244
245         return 0;
246
247 failed:
248         DEBUG(0, ("Failed to load ldap server query policies\n"));
249         talloc_free(tmp_ctx);
250         return -1;
251 }
252
253 static struct tevent_req *ldapsrv_process_call_send(TALLOC_CTX *mem_ctx,
254                                                     struct tevent_context *ev,
255                                                     struct tevent_queue *call_queue,
256                                                     struct ldapsrv_call *call);
257 static NTSTATUS ldapsrv_process_call_recv(struct tevent_req *req);
258
259 static bool ldapsrv_call_read_next(struct ldapsrv_connection *conn);
260 static void ldapsrv_accept_tls_done(struct tevent_req *subreq);
261
262 /*
263   initialise a server_context from a open socket and register a event handler
264   for reading from that socket
265 */
266 static void ldapsrv_accept(struct stream_connection *c,
267                            struct auth_session_info *session_info)
268 {
269         struct ldapsrv_service *ldapsrv_service = 
270                 talloc_get_type(c->private_data, struct ldapsrv_service);
271         struct ldapsrv_connection *conn;
272         struct cli_credentials *server_credentials;
273         struct socket_address *socket_address;
274         NTSTATUS status;
275         int port;
276         int ret;
277         struct tevent_req *subreq;
278         struct timeval endtime;
279
280         conn = talloc_zero(c, struct ldapsrv_connection);
281         if (!conn) {
282                 stream_terminate_connection(c, "ldapsrv_accept: out of memory");
283                 return;
284         }
285
286         conn->sockets.send_queue = tevent_queue_create(conn, "ldapsev send queue");
287         if (conn->sockets.send_queue == NULL) {
288                 stream_terminate_connection(c,
289                                             "ldapsrv_accept: tevent_queue_create failed");
290                 return;
291         }
292
293         TALLOC_FREE(c->event.fde);
294
295         ret = tstream_bsd_existing_socket(conn,
296                                           socket_get_fd(c->socket),
297                                           &conn->sockets.raw);
298         if (ret == -1) {
299                 stream_terminate_connection(c,
300                                             "ldapsrv_accept: out of memory");
301                 return;
302         }
303         socket_set_flags(c->socket, SOCKET_FLAG_NOCLOSE);
304
305         conn->connection  = c;
306         conn->service     = ldapsrv_service;
307         conn->lp_ctx      = ldapsrv_service->task->lp_ctx;
308
309         c->private_data   = conn;
310
311         socket_address = socket_get_my_addr(c->socket, conn);
312         if (!socket_address) {
313                 ldapsrv_terminate_connection(conn, "ldapsrv_accept: failed to obtain local socket address!");
314                 return;
315         }
316         port = socket_address->port;
317         talloc_free(socket_address);
318         if (port == 3268) /* Global catalog */ {
319                 conn->global_catalog = true;
320         }
321
322         server_credentials = cli_credentials_init(conn);
323         if (!server_credentials) {
324                 stream_terminate_connection(c, "Failed to init server credentials\n");
325                 return;
326         }
327
328         cli_credentials_set_conf(server_credentials, conn->lp_ctx);
329         status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx);
330         if (!NT_STATUS_IS_OK(status)) {
331                 stream_terminate_connection(c, talloc_asprintf(conn, "Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status)));
332                 return;
333         }
334         conn->server_credentials = server_credentials;
335
336         conn->session_info = talloc_move(conn, &session_info);
337
338         if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) {
339                 ldapsrv_terminate_connection(conn, "backend Init failed");
340                 return;
341         }
342
343         /* load limits from the conf partition */
344         ldapsrv_load_limits(conn); /* should we fail on error ? */
345
346         /* register the server */       
347         irpc_add_name(c->msg_ctx, "ldap_server");
348
349         conn->sockets.active = conn->sockets.raw;
350
351         if (port != 636) {
352                 ldapsrv_call_read_next(conn);
353                 return;
354         }
355
356         endtime = timeval_current_ofs(conn->limits.conn_idle_time, 0);
357
358         subreq = tstream_tls_accept_send(conn,
359                                          conn->connection->event.ctx,
360                                          conn->sockets.raw,
361                                          conn->service->tls_params);
362         if (subreq == NULL) {
363                 ldapsrv_terminate_connection(conn, "ldapsrv_accept: "
364                                 "no memory for tstream_tls_accept_send");
365                 return;
366         }
367         tevent_req_set_endtime(subreq,
368                                conn->connection->event.ctx,
369                                endtime);
370         tevent_req_set_callback(subreq, ldapsrv_accept_tls_done, conn);
371 }
372
373 static void ldapsrv_accept_tls_done(struct tevent_req *subreq)
374 {
375         struct ldapsrv_connection *conn =
376                 tevent_req_callback_data(subreq,
377                 struct ldapsrv_connection);
378         int ret;
379         int sys_errno;
380
381         ret = tstream_tls_accept_recv(subreq, &sys_errno,
382                                       conn, &conn->sockets.tls);
383         TALLOC_FREE(subreq);
384         if (ret == -1) {
385                 const char *reason;
386
387                 reason = talloc_asprintf(conn, "ldapsrv_accept_tls_loop: "
388                                          "tstream_tls_accept_recv() - %d:%s",
389                                          sys_errno, strerror(sys_errno));
390                 if (!reason) {
391                         reason = "ldapsrv_accept_tls_loop: "
392                                  "tstream_tls_accept_recv() - failed";
393                 }
394
395                 ldapsrv_terminate_connection(conn, reason);
396                 return;
397         }
398
399         conn->sockets.active = conn->sockets.tls;
400         ldapsrv_call_read_next(conn);
401 }
402
403 static void ldapsrv_call_read_done(struct tevent_req *subreq);
404
405 static bool ldapsrv_call_read_next(struct ldapsrv_connection *conn)
406 {
407         struct tevent_req *subreq;
408
409         if (timeval_is_zero(&conn->limits.endtime)) {
410                 conn->limits.endtime =
411                         timeval_current_ofs(conn->limits.initial_timeout, 0);
412         } else {
413                 conn->limits.endtime =
414                         timeval_current_ofs(conn->limits.conn_idle_time, 0);
415         }
416
417         /*
418          * The minimun size of a LDAP pdu is 7 bytes
419          *
420          * dumpasn1 -hh ldap-unbind-min.dat
421          *
422          *     <30 05 02 01 09 42 00>
423          *    0    5: SEQUENCE {
424          *     <02 01 09>
425          *    2    1:   INTEGER 9
426          *     <42 00>
427          *    5    0:   [APPLICATION 2]
428          *          :     Error: Object has zero length.
429          *          :   }
430          *
431          * dumpasn1 -hh ldap-unbind-windows.dat
432          *
433          *     <30 84 00 00 00 05 02 01 09 42 00>
434          *    0    5: SEQUENCE {
435          *     <02 01 09>
436          *    6    1:   INTEGER 9
437          *     <42 00>
438          *    9    0:   [APPLICATION 2]
439          *          :     Error: Object has zero length.
440          *          :   }
441          *
442          * This means using an initial read size
443          * of 7 is ok.
444          */
445         subreq = tstream_read_pdu_blob_send(conn,
446                                             conn->connection->event.ctx,
447                                             conn->sockets.active,
448                                             7, /* initial_read_size */
449                                             ldap_full_packet,
450                                             conn);
451         if (subreq == NULL) {
452                 ldapsrv_terminate_connection(conn, "ldapsrv_call_read_next: "
453                                 "no memory for tstream_read_pdu_blob_send");
454                 return false;
455         }
456         tevent_req_set_endtime(subreq,
457                                conn->connection->event.ctx,
458                                conn->limits.endtime);
459         tevent_req_set_callback(subreq, ldapsrv_call_read_done, conn);
460         return true;
461 }
462
463 static void ldapsrv_call_process_done(struct tevent_req *subreq);
464
465 static void ldapsrv_call_read_done(struct tevent_req *subreq)
466 {
467         struct ldapsrv_connection *conn =
468                 tevent_req_callback_data(subreq,
469                 struct ldapsrv_connection);
470         NTSTATUS status;
471         struct ldapsrv_call *call;
472         struct asn1_data *asn1;
473         DATA_BLOB blob;
474
475         call = talloc_zero(conn, struct ldapsrv_call);
476         if (!call) {
477                 ldapsrv_terminate_connection(conn, "no memory");
478                 return;
479         }
480
481         call->conn = conn;
482
483         status = tstream_read_pdu_blob_recv(subreq,
484                                             call,
485                                             &blob);
486         TALLOC_FREE(subreq);
487         if (!NT_STATUS_IS_OK(status)) {
488                 const char *reason;
489
490                 reason = talloc_asprintf(call, "ldapsrv_call_loop: "
491                                          "tstream_read_pdu_blob_recv() - %s",
492                                          nt_errstr(status));
493                 if (!reason) {
494                         reason = nt_errstr(status);
495                 }
496
497                 ldapsrv_terminate_connection(conn, reason);
498                 return;
499         }
500
501         asn1 = asn1_init(call);
502         if (asn1 == NULL) {
503                 ldapsrv_terminate_connection(conn, "no memory");
504                 return;
505         }
506
507         call->request = talloc(call, struct ldap_message);
508         if (call->request == NULL) {
509                 ldapsrv_terminate_connection(conn, "no memory");
510                 return;
511         }
512
513         if (!asn1_load(asn1, blob)) {
514                 ldapsrv_terminate_connection(conn, "asn1_load failed");
515                 return;
516         }
517
518         status = ldap_decode(asn1, samba_ldap_control_handlers(),
519                              call->request);
520         if (!NT_STATUS_IS_OK(status)) {
521                 ldapsrv_terminate_connection(conn, nt_errstr(status));
522                 return;
523         }
524
525         data_blob_free(&blob);
526
527
528         /* queue the call in the global queue */
529         subreq = ldapsrv_process_call_send(call,
530                                            conn->connection->event.ctx,
531                                            conn->service->call_queue,
532                                            call);
533         if (subreq == NULL) {
534                 ldapsrv_terminate_connection(conn, "ldapsrv_process_call_send failed");
535                 return;
536         }
537         tevent_req_set_callback(subreq, ldapsrv_call_process_done, call);
538         conn->active_call = subreq;
539 }
540
541 static void ldapsrv_call_writev_done(struct tevent_req *subreq);
542
543 static void ldapsrv_call_process_done(struct tevent_req *subreq)
544 {
545         struct ldapsrv_call *call =
546                 tevent_req_callback_data(subreq,
547                 struct ldapsrv_call);
548         struct ldapsrv_connection *conn = call->conn;
549         NTSTATUS status;
550         DATA_BLOB blob = data_blob_null;
551
552         conn->active_call = NULL;
553
554         status = ldapsrv_process_call_recv(subreq);
555         TALLOC_FREE(subreq);
556         if (!NT_STATUS_IS_OK(status)) {
557                 ldapsrv_terminate_connection(conn, nt_errstr(status));
558                 return;
559         }
560
561         /* build all the replies into a single blob */
562         while (call->replies) {
563                 DATA_BLOB b;
564                 bool ret;
565
566                 if (!ldap_encode(call->replies->msg, samba_ldap_control_handlers(), &b, call)) {
567                         DEBUG(0,("Failed to encode ldap reply of type %d\n",
568                                  call->replies->msg->type));
569                         ldapsrv_terminate_connection(conn, "ldap_encode failed");
570                         return;
571                 }
572
573                 ret = data_blob_append(call, &blob, b.data, b.length);
574                 data_blob_free(&b);
575
576                 talloc_set_name_const(blob.data, "Outgoing, encoded LDAP packet");
577
578                 if (!ret) {
579                         ldapsrv_terminate_connection(conn, "data_blob_append failed");
580                         return;
581                 }
582
583                 DLIST_REMOVE(call->replies, call->replies);
584         }
585
586         if (blob.length == 0) {
587                 TALLOC_FREE(call);
588
589                 ldapsrv_call_read_next(conn);
590                 return;
591         }
592
593         call->out_iov.iov_base = blob.data;
594         call->out_iov.iov_len = blob.length;
595
596         subreq = tstream_writev_queue_send(call,
597                                            conn->connection->event.ctx,
598                                            conn->sockets.active,
599                                            conn->sockets.send_queue,
600                                            &call->out_iov, 1);
601         if (subreq == NULL) {
602                 ldapsrv_terminate_connection(conn, "stream_writev_queue_send failed");
603                 return;
604         }
605         tevent_req_set_callback(subreq, ldapsrv_call_writev_done, call);
606 }
607
608 static void ldapsrv_call_postprocess_done(struct tevent_req *subreq);
609
610 static void ldapsrv_call_writev_done(struct tevent_req *subreq)
611 {
612         struct ldapsrv_call *call =
613                 tevent_req_callback_data(subreq,
614                 struct ldapsrv_call);
615         struct ldapsrv_connection *conn = call->conn;
616         int sys_errno;
617         int rc;
618
619         rc = tstream_writev_queue_recv(subreq, &sys_errno);
620         TALLOC_FREE(subreq);
621         if (rc == -1) {
622                 const char *reason;
623
624                 reason = talloc_asprintf(call, "ldapsrv_call_writev_done: "
625                                          "tstream_writev_queue_recv() - %d:%s",
626                                          sys_errno, strerror(sys_errno));
627                 if (reason == NULL) {
628                         reason = "ldapsrv_call_writev_done: "
629                                  "tstream_writev_queue_recv() failed";
630                 }
631
632                 ldapsrv_terminate_connection(conn, reason);
633                 return;
634         }
635
636         if (call->postprocess_send) {
637                 subreq = call->postprocess_send(call,
638                                                 conn->connection->event.ctx,
639                                                 call->postprocess_private);
640                 if (subreq == NULL) {
641                         ldapsrv_terminate_connection(conn, "ldapsrv_call_writev_done: "
642                                         "call->postprocess_send - no memory");
643                         return;
644                 }
645                 tevent_req_set_callback(subreq,
646                                         ldapsrv_call_postprocess_done,
647                                         call);
648                 return;
649         }
650
651         TALLOC_FREE(call);
652
653         ldapsrv_call_read_next(conn);
654 }
655
656 static void ldapsrv_call_postprocess_done(struct tevent_req *subreq)
657 {
658         struct ldapsrv_call *call =
659                 tevent_req_callback_data(subreq,
660                 struct ldapsrv_call);
661         struct ldapsrv_connection *conn = call->conn;
662         NTSTATUS status;
663
664         status = call->postprocess_recv(subreq);
665         TALLOC_FREE(subreq);
666         if (!NT_STATUS_IS_OK(status)) {
667                 const char *reason;
668
669                 reason = talloc_asprintf(call, "ldapsrv_call_postprocess_done: "
670                                          "call->postprocess_recv() - %s",
671                                          nt_errstr(status));
672                 if (reason == NULL) {
673                         reason = nt_errstr(status);
674                 }
675
676                 ldapsrv_terminate_connection(conn, reason);
677                 return;
678         }
679
680         TALLOC_FREE(call);
681
682         ldapsrv_call_read_next(conn);
683 }
684
685 struct ldapsrv_process_call_state {
686         struct ldapsrv_call *call;
687 };
688
689 static void ldapsrv_process_call_trigger(struct tevent_req *req,
690                                          void *private_data);
691
692 static struct tevent_req *ldapsrv_process_call_send(TALLOC_CTX *mem_ctx,
693                                                     struct tevent_context *ev,
694                                                     struct tevent_queue *call_queue,
695                                                     struct ldapsrv_call *call)
696 {
697         struct tevent_req *req;
698         struct ldapsrv_process_call_state *state;
699         bool ok;
700
701         req = tevent_req_create(mem_ctx, &state,
702                                 struct ldapsrv_process_call_state);
703         if (req == NULL) {
704                 return req;
705         }
706
707         state->call = call;
708
709         ok = tevent_queue_add(call_queue, ev, req,
710                               ldapsrv_process_call_trigger, NULL);
711         if (!ok) {
712                 tevent_req_nomem(NULL, req);
713                 return tevent_req_post(req, ev);
714         }
715
716         return req;
717 }
718
719 static void ldapsrv_process_call_trigger(struct tevent_req *req,
720                                          void *private_data)
721 {
722         struct ldapsrv_process_call_state *state =
723                 tevent_req_data(req,
724                 struct ldapsrv_process_call_state);
725         NTSTATUS status;
726
727         /* make the call */
728         status = ldapsrv_do_call(state->call);
729         if (!NT_STATUS_IS_OK(status)) {
730                 tevent_req_nterror(req, status);
731                 return;
732         }
733
734         tevent_req_done(req);
735 }
736
737 static NTSTATUS ldapsrv_process_call_recv(struct tevent_req *req)
738 {
739         NTSTATUS status;
740
741         if (tevent_req_is_nterror(req, &status)) {
742                 tevent_req_received(req);
743                 return status;
744         }
745
746         tevent_req_received(req);
747         return NT_STATUS_OK;
748 }
749
750 static void ldapsrv_accept_nonpriv(struct stream_connection *c)
751 {
752         struct ldapsrv_service *ldapsrv_service = talloc_get_type_abort(
753                 c->private_data, struct ldapsrv_service);
754         struct auth_session_info *session_info;
755         NTSTATUS status;
756
757         status = auth_anonymous_session_info(
758                 c, ldapsrv_service->task->lp_ctx, &session_info);
759         if (!NT_STATUS_IS_OK(status)) {
760                 stream_terminate_connection(c, "failed to setup anonymous "
761                                             "session info");
762                 return;
763         }
764         ldapsrv_accept(c, session_info);
765 }
766
767 static const struct stream_server_ops ldap_stream_nonpriv_ops = {
768         .name                   = "ldap",
769         .accept_connection      = ldapsrv_accept_nonpriv,
770         .recv_handler           = ldapsrv_recv,
771         .send_handler           = ldapsrv_send,
772 };
773
774 /* The feature removed behind an #ifdef until we can do it properly
775  * with an EXTERNAL bind. */
776
777 #define WITH_LDAPI_PRIV_SOCKET
778
779 #ifdef WITH_LDAPI_PRIV_SOCKET
780 static void ldapsrv_accept_priv(struct stream_connection *c)
781 {
782         struct ldapsrv_service *ldapsrv_service = talloc_get_type_abort(
783                 c->private_data, struct ldapsrv_service);
784         struct auth_session_info *session_info;
785
786         session_info = system_session(ldapsrv_service->task->lp_ctx);
787         if (!session_info) {
788                 stream_terminate_connection(c, "failed to setup system "
789                                             "session info");
790                 return;
791         }
792         ldapsrv_accept(c, session_info);
793 }
794
795 static const struct stream_server_ops ldap_stream_priv_ops = {
796         .name                   = "ldap",
797         .accept_connection      = ldapsrv_accept_priv,
798         .recv_handler           = ldapsrv_recv,
799         .send_handler           = ldapsrv_send,
800 };
801
802 #endif
803 /*
804   add a socket address to the list of events, one event per port
805 */
806 static NTSTATUS add_socket(struct tevent_context *event_context,
807                            struct loadparm_context *lp_ctx,
808                            const struct model_ops *model_ops,
809                            const char *address, struct ldapsrv_service *ldap_service)
810 {
811         uint16_t port = 389;
812         NTSTATUS status;
813         struct ldb_context *ldb;
814
815         status = stream_setup_socket(event_context, lp_ctx,
816                                      model_ops, &ldap_stream_nonpriv_ops,
817                                      "ipv4", address, &port, 
818                                      lpcfg_socket_options(lp_ctx),
819                                      ldap_service);
820         if (!NT_STATUS_IS_OK(status)) {
821                 DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
822                          address, port, nt_errstr(status)));
823                 return status;
824         }
825
826         if (tstream_tls_params_enabled(ldap_service->tls_params)) {
827                 /* add ldaps server */
828                 port = 636;
829                 status = stream_setup_socket(event_context, lp_ctx,
830                                              model_ops,
831                                              &ldap_stream_nonpriv_ops,
832                                              "ipv4", address, &port, 
833                                              lpcfg_socket_options(lp_ctx),
834                                              ldap_service);
835                 if (!NT_STATUS_IS_OK(status)) {
836                         DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
837                                  address, port, nt_errstr(status)));
838                         return status;
839                 }
840         }
841
842         /* Load LDAP database, but only to read our settings */
843         ldb = samdb_connect(ldap_service, ldap_service->task->event_ctx, 
844                             lp_ctx, system_session(lp_ctx));
845         if (!ldb) {
846                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
847         }
848
849         if (samdb_is_gc(ldb)) {
850                 port = 3268;
851                 status = stream_setup_socket(event_context, lp_ctx,
852                                              model_ops,
853                                              &ldap_stream_nonpriv_ops,
854                                              "ipv4", address, &port, 
855                                              lpcfg_socket_options(lp_ctx),
856                                              ldap_service);
857                 if (!NT_STATUS_IS_OK(status)) {
858                         DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n",
859                                  address, port, nt_errstr(status)));
860                         return status;
861                 }
862         }
863
864         /* And once we are bound, free the tempoary ldb, it will
865          * connect again on each incoming LDAP connection */
866         talloc_unlink(ldap_service, ldb);
867
868         return NT_STATUS_OK;
869 }
870
871 /*
872   open the ldap server sockets
873 */
874 static void ldapsrv_task_init(struct task_server *task)
875 {       
876         char *ldapi_path;
877 #ifdef WITH_LDAPI_PRIV_SOCKET
878         char *priv_dir;
879 #endif
880         const char *dns_host_name;
881         struct ldapsrv_service *ldap_service;
882         NTSTATUS status;
883         const struct model_ops *model_ops;
884
885         switch (lpcfg_server_role(task->lp_ctx)) {
886         case ROLE_STANDALONE:
887                 task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration", 
888                                       false);
889                 return;
890         case ROLE_DOMAIN_MEMBER:
891                 task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration", 
892                                       false);
893                 return;
894         case ROLE_DOMAIN_CONTROLLER:
895                 /* Yes, we want an LDAP server */
896                 break;
897         }
898
899         task_server_set_title(task, "task[ldapsrv]");
900
901         /* run the ldap server as a single process */
902         model_ops = process_model_startup(task->event_ctx, "single");
903         if (!model_ops) goto failed;
904
905         ldap_service = talloc_zero(task, struct ldapsrv_service);
906         if (ldap_service == NULL) goto failed;
907
908         ldap_service->task = task;
909
910         dns_host_name = talloc_asprintf(ldap_service, "%s.%s",
911                                         lpcfg_netbios_name(task->lp_ctx),
912                                         lpcfg_dnsdomain(task->lp_ctx));
913         if (dns_host_name == NULL) goto failed;
914
915         status = tstream_tls_params_server(ldap_service,
916                                            dns_host_name,
917                                            lpcfg_tls_enabled(task->lp_ctx),
918                                            lpcfg_tls_keyfile(ldap_service, task->lp_ctx),
919                                            lpcfg_tls_certfile(ldap_service, task->lp_ctx),
920                                            lpcfg_tls_cafile(ldap_service, task->lp_ctx),
921                                            lpcfg_tls_crlfile(ldap_service, task->lp_ctx),
922                                            lpcfg_tls_dhpfile(ldap_service, task->lp_ctx),
923                                            &ldap_service->tls_params);
924         if (!NT_STATUS_IS_OK(status)) {
925                 DEBUG(0,("ldapsrv failed tstream_tls_patams_server - %s\n",
926                          nt_errstr(status)));
927                 goto failed;
928         }
929
930         ldap_service->call_queue = tevent_queue_create(ldap_service, "ldapsrv_call_queue");
931         if (ldap_service->call_queue == NULL) goto failed;
932
933         if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) {
934                 struct interface *ifaces;
935                 int num_interfaces;
936                 int i;
937
938                 load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces);
939                 num_interfaces = iface_count(ifaces);
940
941                 /* We have been given an interfaces line, and been 
942                    told to only bind to those interfaces. Create a
943                    socket per interface and bind to only these.
944                 */
945                 for(i = 0; i < num_interfaces; i++) {
946                         const char *address = iface_n_ip(ifaces, i);
947                         status = add_socket(task->event_ctx, task->lp_ctx, model_ops, address, ldap_service);
948                         if (!NT_STATUS_IS_OK(status)) goto failed;
949                 }
950         } else {
951                 status = add_socket(task->event_ctx, task->lp_ctx, model_ops,
952                                     lpcfg_socket_address(task->lp_ctx), ldap_service);
953                 if (!NT_STATUS_IS_OK(status)) goto failed;
954         }
955
956         ldapi_path = private_path(ldap_service, task->lp_ctx, "ldapi");
957         if (!ldapi_path) {
958                 goto failed;
959         }
960
961         status = stream_setup_socket(task->event_ctx, task->lp_ctx,
962                                      model_ops, &ldap_stream_nonpriv_ops,
963                                      "unix", ldapi_path, NULL, 
964                                      lpcfg_socket_options(task->lp_ctx),
965                                      ldap_service);
966         talloc_free(ldapi_path);
967         if (!NT_STATUS_IS_OK(status)) {
968                 DEBUG(0,("ldapsrv failed to bind to %s - %s\n",
969                          ldapi_path, nt_errstr(status)));
970         }
971
972 #ifdef WITH_LDAPI_PRIV_SOCKET
973         priv_dir = private_path(ldap_service, task->lp_ctx, "ldap_priv");
974         if (priv_dir == NULL) {
975                 goto failed;
976         }
977         /*
978          * Make sure the directory for the privileged ldapi socket exists, and
979          * is of the correct permissions
980          */
981         if (!directory_create_or_exist(priv_dir, geteuid(), 0750)) {
982                 task_server_terminate(task, "Cannot create ldap "
983                                       "privileged ldapi directory", true);
984                 return;
985         }
986         ldapi_path = talloc_asprintf(ldap_service, "%s/ldapi", priv_dir);
987         talloc_free(priv_dir);
988         if (ldapi_path == NULL) {
989                 goto failed;
990         }
991
992         status = stream_setup_socket(task->event_ctx, task->lp_ctx,
993                                      model_ops, &ldap_stream_priv_ops,
994                                      "unix", ldapi_path, NULL,
995                                      lpcfg_socket_options(task->lp_ctx),
996                                      ldap_service);
997         talloc_free(ldapi_path);
998         if (!NT_STATUS_IS_OK(status)) {
999                 DEBUG(0,("ldapsrv failed to bind to %s - %s\n",
1000                          ldapi_path, nt_errstr(status)));
1001         }
1002
1003 #endif
1004         return;
1005
1006 failed:
1007         task_server_terminate(task, "Failed to startup ldap server task", true);
1008 }
1009
1010
1011 NTSTATUS server_service_ldap_init(void)
1012 {
1013         return register_server_service("ldap", ldapsrv_task_init);
1014 }