r3443: the next stage in the include files re-organisation.
[bbaumbach/samba-autobuild/.git] / source4 / ldap_server / ldap_server.c
1 /* 
2    Unix SMB/CIFS implementation.
3    LDAP server
4    Copyright (C) Volker Lendecke 2004
5    Copyright (C) Stefan Metzmacher 2004
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 /*
25   close the socket and shutdown a server_context
26 */
27 static void ldapsrv_terminate_connection(struct ldapsrv_connection *ldap_conn, const char *reason)
28 {
29         server_terminate_connection(ldap_conn->connection, reason);
30 }
31
32 /*
33   add a socket address to the list of events, one event per port
34 */
35 static void add_socket(struct server_service *service, 
36                        const struct model_ops *model_ops, 
37                        struct ipv4_addr *ifip)
38 {
39         struct server_socket *srv_sock;
40         uint16_t port = 389;
41         char *ip_str = talloc_strdup(service, sys_inet_ntoa(*ifip));
42
43         srv_sock = service_setup_socket(service, model_ops, "ipv4", ip_str, &port);
44
45         port = 3268;
46         srv_sock = service_setup_socket(service, model_ops, "ipv4", ip_str, &port);
47
48         talloc_free(ip_str);
49 }
50
51 /****************************************************************************
52  Open the socket communication.
53 ****************************************************************************/
54 static void ldapsrv_init(struct server_service *service,
55                          const struct model_ops *model_ops)
56 {       
57         struct ldapsrv_service *ldap_service;
58         struct ldapsrv_partition *part;
59
60         DEBUG(10,("ldapsrv_init\n"));
61
62         ldap_service = talloc_p(service, struct ldapsrv_service);
63         if (!ldap_service) {
64                 DEBUG(0,("talloc_p(service, struct ldapsrv_service) failed\n"));
65                 return;
66         }
67         ZERO_STRUCTP(ldap_service);
68
69         part = talloc_p(ldap_service, struct ldapsrv_partition);
70         if (!ldap_service) {
71                 DEBUG(0,("talloc_p(ldap_service, struct ldapsrv_partition) failed\n"));
72                 return;
73         }
74         part->base_dn = ""; /* RootDSE */
75         part->ops = ldapsrv_get_rootdse_partition_ops();
76
77         ldap_service->rootDSE = part;
78         DLIST_ADD_END(ldap_service->partitions, part, struct ldapsrv_partition *);
79
80         part = talloc_p(ldap_service, struct ldapsrv_partition);
81         if (!ldap_service) {
82                 DEBUG(0,("talloc_p(ldap_service, struct ldapsrv_partition) failed\n"));
83                 return;
84         }
85         part->base_dn = "*"; /* default partition */
86         part->ops = ldapsrv_get_sldb_partition_ops();
87
88         ldap_service->default_partition = part;
89         DLIST_ADD_END(ldap_service->partitions, part, struct ldapsrv_partition *);
90
91         service->private_data = ldap_service;
92
93         if (lp_interfaces() && lp_bind_interfaces_only()) {
94                 int num_interfaces = iface_count();
95                 int i;
96
97                 /* We have been given an interfaces line, and been 
98                    told to only bind to those interfaces. Create a
99                    socket per interface and bind to only these.
100                 */
101                 for(i = 0; i < num_interfaces; i++) {
102                         struct ipv4_addr *ifip = iface_n_ip(i);
103
104                         if (ifip == NULL) {
105                                 DEBUG(0,("ldapsrv_init: interface %d has NULL "
106                                          "IP address !\n", i));
107                                 continue;
108                         }
109
110                         add_socket(service, model_ops, ifip);
111                 }
112         } else {
113                 struct ipv4_addr ifip;
114
115                 /* Just bind to lp_socket_address() (usually 0.0.0.0) */
116                 ifip = interpret_addr2(lp_socket_address());
117                 add_socket(service, model_ops, &ifip);
118         }
119 }
120
121 /* This rw-buf api is made to avoid memcpy. For now do that like mad...  The
122    idea is to write into a circular list of buffers where the ideal case is
123    that a read(2) holds a complete request that is then thrown away
124    completely. */
125
126 void ldapsrv_consumed_from_buf(struct rw_buffer *buf,
127                                    size_t length)
128 {
129         memcpy(buf->data, buf->data+length, buf->length-length);
130         buf->length -= length;
131 }
132
133 static void peek_into_read_buf(struct rw_buffer *buf, uint8_t **out,
134                                size_t *out_length)
135 {
136         *out = buf->data;
137         *out_length = buf->length;
138 }
139
140 BOOL ldapsrv_append_to_buf(struct rw_buffer *buf, uint8_t *data, size_t length)
141 {
142         buf->data = realloc(buf->data, buf->length+length);
143
144         if (buf->data == NULL)
145                 return False;
146
147         memcpy(buf->data+buf->length, data, length);
148
149         buf->length += length;
150         return True;
151 }
152
153 static BOOL read_into_buf(struct socket_context *sock, struct rw_buffer *buf)
154 {
155         NTSTATUS status;
156         DATA_BLOB tmp_blob;
157         BOOL ret;
158         size_t nread;
159
160         tmp_blob = data_blob_talloc(sock, NULL, 1024);
161         if (tmp_blob.data == NULL) {
162                 return False;
163         }
164
165         status = socket_recv(sock, tmp_blob.data, tmp_blob.length, &nread, 0);
166         if (NT_STATUS_IS_ERR(status)) {
167                 DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
168                 talloc_free(tmp_blob.data);
169                 return False;
170         }
171
172         ret = ldapsrv_append_to_buf(buf, tmp_blob.data, tmp_blob.length);
173
174         talloc_free(tmp_blob.data);
175
176         return ret;
177 }
178
179 static BOOL ldapsrv_read_buf(struct ldapsrv_connection *conn)
180 {
181         NTSTATUS status;
182         DATA_BLOB tmp_blob;
183         DATA_BLOB creds;
184         BOOL ret;
185         uint8_t *buf;
186         int buf_length, sasl_length;
187         struct socket_context *sock = conn->connection->socket;
188         TALLOC_CTX *mem_ctx;
189         size_t nread;
190
191         if (!conn->gensec || !conn->session_info ||
192            !(gensec_have_feature(conn->gensec, GENSEC_WANT_SIGN) &&
193              gensec_have_feature(conn->gensec, GENSEC_WANT_SEAL))) {
194                 return read_into_buf(sock, &conn->in_buffer);
195         }
196
197         mem_ctx = talloc(conn, 0);
198         if (!mem_ctx) {
199                 DEBUG(0,("no memory\n"));
200                 return False;
201         }
202
203         tmp_blob = data_blob_talloc(mem_ctx, NULL, 1024);
204         if (tmp_blob.data == NULL) {
205                 talloc_free(mem_ctx);
206                 return False;
207         }
208
209         status = socket_recv(sock, tmp_blob.data, tmp_blob.length, &nread, 0);
210         if (NT_STATUS_IS_ERR(status)) {
211                 DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
212                 talloc_free(mem_ctx);
213                 return False;
214         }
215         tmp_blob.length = nread;
216
217         ret = ldapsrv_append_to_buf(&conn->sasl_in_buffer, tmp_blob.data, tmp_blob.length);
218         if (!ret) {
219                 talloc_free(mem_ctx);
220                 return False;
221         }
222
223         peek_into_read_buf(&conn->sasl_in_buffer, &buf, &buf_length);
224
225         if (buf_length < 4) {
226                 /* not enough yet */
227                 talloc_free(mem_ctx);
228                 return True;
229         }
230
231         sasl_length = RIVAL(buf, 0);
232
233         if (buf_length < (4 + sasl_length)) {
234                 /* not enough yet */
235                 talloc_free(mem_ctx);
236                 return True;
237         }
238
239         creds.data = buf + 4;
240         creds.length = gensec_sig_size(conn->gensec);
241
242         if (creds.length > sasl_length) {
243                 /* invalid packet? */
244                 talloc_free(mem_ctx);
245                 return False;
246         }
247
248         tmp_blob.data = buf + (4 + creds.length);
249         tmp_blob.length = (4 + sasl_length) - (4 + creds.length);
250
251         if (gensec_have_feature(conn->gensec, GENSEC_WANT_SEAL)) {
252                 status = gensec_unseal_packet(conn->gensec, mem_ctx,
253                                               tmp_blob.data, tmp_blob.length,
254                                               tmp_blob.data, tmp_blob.length,
255                                               &creds);
256                 if (!NT_STATUS_IS_OK(status)) {
257                         DEBUG(0,("gensec_unseal_packet: %s\n",nt_errstr(status)));
258                         talloc_free(mem_ctx);
259                         return False;
260                 }
261         } else {
262                 status = gensec_check_packet(conn->gensec, mem_ctx,
263                                               tmp_blob.data, tmp_blob.length,
264                                               tmp_blob.data, tmp_blob.length,
265                                               &creds);
266                 if (!NT_STATUS_IS_OK(status)) {
267                         DEBUG(0,("gensec_check_packet: %s\n",nt_errstr(status)));
268                         talloc_free(mem_ctx);
269                         return False;
270                 }
271         }
272
273         ret = ldapsrv_append_to_buf(&conn->in_buffer, tmp_blob.data, tmp_blob.length);
274         if (!ret) {
275                 talloc_free(mem_ctx);
276                 return False;
277         }
278
279         ldapsrv_consumed_from_buf(&conn->sasl_in_buffer, 4 + sasl_length);
280
281         talloc_free(mem_ctx);
282         return ret;
283 }
284
285 static BOOL write_from_buf(struct socket_context *sock, struct rw_buffer *buf)
286 {
287         NTSTATUS status;
288         DATA_BLOB tmp_blob;
289         size_t sendlen;
290
291         tmp_blob.data = buf->data;
292         tmp_blob.length = buf->length;
293
294         status = socket_send(sock, &tmp_blob, &sendlen, 0);
295         if (!NT_STATUS_IS_OK(status)) {
296                 DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
297                 return False;
298         }
299
300         ldapsrv_consumed_from_buf(buf, sendlen);
301
302         return True;
303 }
304
305 static BOOL ldapsrv_write_buf(struct ldapsrv_connection *conn)
306 {
307         NTSTATUS status;
308         DATA_BLOB tmp_blob;
309         DATA_BLOB creds;
310         DATA_BLOB sasl;
311         size_t sendlen;
312         BOOL ret;
313         struct socket_context *sock = conn->connection->socket;
314         TALLOC_CTX *mem_ctx;
315
316         if (!conn->gensec || !conn->session_info ||
317            !(gensec_have_feature(conn->gensec, GENSEC_WANT_SIGN) &&
318              gensec_have_feature(conn->gensec, GENSEC_WANT_SEAL))) {
319                 return write_from_buf(sock, &conn->out_buffer);
320         }
321
322         mem_ctx = talloc(conn, 0);
323         if (!mem_ctx) {
324                 DEBUG(0,("no memory\n"));
325                 return False;
326         }
327
328         tmp_blob.data = conn->out_buffer.data;
329         tmp_blob.length = conn->out_buffer.length;
330
331         if (tmp_blob.length == 0) {
332                 goto nodata;
333         }
334
335         if (gensec_have_feature(conn->gensec, GENSEC_WANT_SEAL)) {
336                 status = gensec_seal_packet(conn->gensec, mem_ctx,
337                                             tmp_blob.data, tmp_blob.length,
338                                             tmp_blob.data, tmp_blob.length,
339                                             &creds);
340                 if (!NT_STATUS_IS_OK(status)) {
341                         DEBUG(0,("gensec_seal_packet: %s\n",nt_errstr(status)));
342                         talloc_free(mem_ctx);
343                         return False;
344                 }
345         } else {
346                 status = gensec_sign_packet(conn->gensec, mem_ctx,
347                                             tmp_blob.data, tmp_blob.length,
348                                             tmp_blob.data, tmp_blob.length,
349                                             &creds);
350                 if (!NT_STATUS_IS_OK(status)) {
351                         DEBUG(0,("gensec_sign_packet: %s\n",nt_errstr(status)));
352                         talloc_free(mem_ctx);
353                         return False;
354                 }               
355         }
356
357         sasl = data_blob_talloc(mem_ctx, NULL, 4 + creds.length + tmp_blob.length);
358         if (!sasl.data) {
359                 DEBUG(0,("no memory\n"));
360                 talloc_free(mem_ctx);
361                 return False;
362         }
363
364         RSIVAL(sasl.data, 0, creds.length + tmp_blob.length);
365         memcpy(sasl.data + 4, creds.data, creds.length);
366         memcpy(sasl.data + 4 + creds.length, tmp_blob.data, tmp_blob.length);
367
368         ret = ldapsrv_append_to_buf(&conn->sasl_out_buffer, sasl.data, sasl.length);
369         if (!ret) {
370                 talloc_free(mem_ctx);
371                 return False;
372         }
373         ldapsrv_consumed_from_buf(&conn->out_buffer, tmp_blob.length);
374 nodata:
375         tmp_blob.data = conn->sasl_out_buffer.data;
376         tmp_blob.length = conn->sasl_out_buffer.length;
377
378         status = socket_send(sock, &tmp_blob, &sendlen, 0);
379         if (!NT_STATUS_IS_OK(status)) {
380                 DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
381                 talloc_free(mem_ctx);
382                 return False;
383         }
384
385         ldapsrv_consumed_from_buf(&conn->sasl_out_buffer, sendlen);
386
387         talloc_free(mem_ctx);
388
389         return True;
390 }
391
392 static BOOL ldap_encode_to_buf(struct ldap_message *msg, struct rw_buffer *buf)
393 {
394         DATA_BLOB blob;
395         BOOL res;
396
397         if (!ldap_encode(msg, &blob))
398                 return False;
399
400         res = ldapsrv_append_to_buf(buf, blob.data, blob.length);
401
402         data_blob_free(&blob);
403         return res;
404 }
405
406 NTSTATUS ldapsrv_do_responses(struct ldapsrv_connection *conn)
407 {
408         struct ldapsrv_call *call, *next_call = NULL;
409         struct ldapsrv_reply *reply, *next_reply = NULL;
410
411         for (call=conn->calls; call; call=next_call) {
412                 for (reply=call->replies; reply; reply=next_reply) {
413                         if (!ldap_encode_to_buf(&reply->msg, &conn->out_buffer)) {
414                                 return NT_STATUS_FOOBAR;
415                         }
416                         next_reply = reply->next;
417                         DLIST_REMOVE(call->replies, reply);
418                         reply->state = LDAPSRV_REPLY_STATE_SEND;
419                         talloc_free(reply);
420                 }
421                 next_call = call->next;
422                 DLIST_REMOVE(conn->calls, call);
423                 call->state = LDAPSRV_CALL_STATE_COMPLETE;
424                 talloc_free(call);
425         }
426
427         return NT_STATUS_OK;
428 }
429
430 NTSTATUS ldapsrv_flush_responses(struct ldapsrv_connection *conn)
431 {
432         return NT_STATUS_OK;
433 }
434
435 /*
436   called when a LDAP socket becomes readable
437 */
438 static void ldapsrv_recv(struct server_connection *conn, time_t t,
439                          uint16_t flags)
440 {
441         struct ldapsrv_connection *ldap_conn = conn->private_data;
442         uint8_t *buf;
443         int buf_length, msg_length;
444         DATA_BLOB blob;
445         ASN1_DATA data;
446         struct ldapsrv_call *call;
447         NTSTATUS status;
448
449         DEBUG(10,("ldapsrv_recv\n"));
450
451         if (!ldapsrv_read_buf(ldap_conn)) {
452                 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_read_buf() failed");
453                 return;
454         }
455
456         peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
457
458         while (buf_length > 0) {
459                 /* LDAP Messages are always SEQUENCES */
460
461                 if (!asn1_object_length(buf, buf_length, ASN1_SEQUENCE(0),
462                                         &msg_length)) {
463                         ldapsrv_terminate_connection(ldap_conn, "asn1_object_length() failed");
464                         return;
465                 }
466
467                 if (buf_length < msg_length) {
468                         /* Not enough yet */
469                         break;
470                 }
471
472                 /* We've got a complete LDAP request in the in-buffer, convert
473                  * that to a ldap_message and put it into the incoming
474                  * queue. */
475
476                 blob.data = buf;
477                 blob.length = msg_length;
478
479                 if (!asn1_load(&data, blob)) {
480                         ldapsrv_terminate_connection(ldap_conn, "asn1_load() failed");
481                         return;
482                 }
483
484                 call = talloc_p(ldap_conn, struct ldapsrv_call);
485                 if (!call) {
486                         ldapsrv_terminate_connection(ldap_conn, "no memory");
487                         return;         
488                 }
489
490                 ZERO_STRUCTP(call);
491                 call->state = LDAPSRV_CALL_STATE_NEW;
492                 call->conn = ldap_conn;
493                 call->request.mem_ctx = call;
494
495                 if (!ldap_decode(&data, &call->request)) {
496                         dump_data(0,buf, msg_length);
497                         asn1_free(&data);
498                         ldapsrv_terminate_connection(ldap_conn, "ldap_decode() failed");
499                         return;
500                 }
501
502                 asn1_free(&data);
503
504                 DLIST_ADD_END(ldap_conn->calls, call,
505                               struct ldapsrv_call *);
506
507                 ldapsrv_consumed_from_buf(&ldap_conn->in_buffer, msg_length);
508
509                 status = ldapsrv_do_call(call);
510                 if (!NT_STATUS_IS_OK(status)) {
511                         ldapsrv_terminate_connection(ldap_conn, "ldapsrv_do_call() failed");
512                         return;
513                 }
514
515                 peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
516         }
517
518         status = ldapsrv_do_responses(ldap_conn);
519         if (!NT_STATUS_IS_OK(status)) {
520                 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_do_responses() failed");
521                 return;
522         }
523
524         if ((ldap_conn->out_buffer.length > 0)||(ldap_conn->sasl_out_buffer.length > 0)) {
525                 conn->event.fde->flags |= EVENT_FD_WRITE;
526         }
527
528         return;
529 }
530         
531 /*
532   called when a LDAP socket becomes writable
533 */
534 static void ldapsrv_send(struct server_connection *conn, time_t t,
535                          uint16_t flags)
536 {
537         struct ldapsrv_connection *ldap_conn = conn->private_data;
538
539         DEBUG(10,("ldapsrv_send\n"));
540
541         if (!ldapsrv_write_buf(ldap_conn)) {
542                 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_write_buf() failed");
543                 return;
544         }
545
546         if (ldap_conn->out_buffer.length == 0 && ldap_conn->sasl_out_buffer.length == 0) {
547                 conn->event.fde->flags &= ~EVENT_FD_WRITE;
548         }
549
550         return;
551 }
552
553 /*
554   called when connection is idle
555 */
556 static void ldapsrv_idle(struct server_connection *conn, time_t t)
557 {
558         DEBUG(10,("ldapsrv_idle: not implemented!\n"));
559         return;
560 }
561
562 static void ldapsrv_close(struct server_connection *conn, const char *reason)
563 {
564         return;
565 }
566
567 /*
568   initialise a server_context from a open socket and register a event handler
569   for reading from that socket
570 */
571 static void ldapsrv_accept(struct server_connection *conn)
572 {
573         struct ldapsrv_connection *ldap_conn;
574
575         DEBUG(10, ("ldapsrv_accept\n"));
576
577         ldap_conn = talloc_p(conn, struct ldapsrv_connection);
578
579         if (ldap_conn == NULL)
580                 return;
581
582         ZERO_STRUCTP(ldap_conn);
583         ldap_conn->connection = conn;
584         ldap_conn->service = talloc_reference(ldap_conn, conn->service->private_data);
585
586         conn->private_data = ldap_conn;
587
588         return;
589 }
590
591 /*
592   called on a fatal error that should cause this server to terminate
593 */
594 static void ldapsrv_exit(struct server_service *service, const char *reason)
595 {
596         DEBUG(10,("ldapsrv_exit\n"));
597         return;
598 }
599
600 static const struct server_service_ops ldap_server_ops = {
601         .name                   = "ldap",
602         .service_init           = ldapsrv_init,
603         .accept_connection      = ldapsrv_accept,
604         .recv_handler           = ldapsrv_recv,
605         .send_handler           = ldapsrv_send,
606         .idle_handler           = ldapsrv_idle,
607         .close_connection       = ldapsrv_close,
608         .service_exit           = ldapsrv_exit, 
609 };
610
611 const struct server_service_ops *ldapsrv_get_ops(void)
612 {
613         return &ldap_server_ops;
614 }
615
616 NTSTATUS server_service_ldap_init(void)
617 {
618         return NT_STATUS_OK;    
619 }