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