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