r2447: let the server code use the new lib/socket/ stuff
[kai/samba.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 in_addr *ifip)
38 {
39         uint16_t port = 389;
40         char *ip_str = talloc_strdup(service->mem_ctx, inet_ntoa(*ifip));
41
42         service_setup_socket(service, model_ops, ip_str, &port);
43
44         talloc_free(ip_str);
45 }
46
47 /****************************************************************************
48  Open the socket communication.
49 ****************************************************************************/
50 static void ldapsrv_init(struct server_service *service,
51                          const struct model_ops *model_ops)
52 {       
53         DEBUG(1,("ldapsrv_init\n"));
54
55         if (lp_interfaces() && lp_bind_interfaces_only()) {
56                 int num_interfaces = iface_count();
57                 int i;
58
59                 /* We have been given an interfaces line, and been 
60                    told to only bind to those interfaces. Create a
61                    socket per interface and bind to only these.
62                 */
63                 for(i = 0; i < num_interfaces; i++) {
64                         struct in_addr *ifip = iface_n_ip(i);
65
66                         if (ifip == NULL) {
67                                 DEBUG(0,("ldapsrv_init: interface %d has NULL "
68                                          "IP address !\n", i));
69                                 continue;
70                         }
71
72                         add_socket(service, model_ops, ifip);
73                 }
74         } else {
75                 struct in_addr *ifip;
76                 TALLOC_CTX *mem_ctx = talloc_init("ldapsrv_init");
77
78                 if (!mem_ctx) {
79                         smb_panic("No memory");
80                 }       
81
82                 /* Just bind to lp_socket_address() (usually 0.0.0.0) */
83                 ifip = interpret_addr2(mem_ctx, lp_socket_address());
84                 add_socket(service, model_ops, ifip);
85
86                 talloc_destroy(mem_ctx);
87         }
88 }
89
90 /* This rw-buf api is made to avoid memcpy. For now do that like mad...  The
91    idea is to write into a circular list of buffers where the ideal case is
92    that a read(2) holds a complete request that is then thrown away
93    completely. */
94
95 static BOOL append_to_buf(struct rw_buffer *buf, uint8_t *data, size_t length)
96 {
97         buf->data = realloc(buf->data, buf->length+length);
98
99         if (buf->data == NULL)
100                 return False;
101
102         memcpy(buf->data+buf->length, data, length);
103
104         buf->length += length;
105         return True;
106 }
107
108 static BOOL read_into_buf(struct socket_context *sock, struct rw_buffer *buf)
109 {
110         NTSTATUS status;
111         DATA_BLOB tmp_blob;
112         BOOL ret;
113
114         status = socket_recv(sock, sock, &tmp_blob, 1024, 0);
115         if (!NT_STATUS_IS_OK(status)) {
116                 DEBUG(0,("socket_recv: %s\n",nt_errstr(status)));
117                 return False;
118         }
119
120         ret = append_to_buf(buf, tmp_blob.data, tmp_blob.length);
121
122         talloc_free(tmp_blob.data);
123
124         return ret;
125 }
126
127 static BOOL write_from_buf(struct socket_context *sock, struct rw_buffer *buf)
128 {
129         NTSTATUS status;
130         DATA_BLOB tmp_blob;
131         size_t sendlen;
132
133         tmp_blob.data = buf->data;
134         tmp_blob.length = buf->length;
135
136         status = socket_send(sock, sock, &tmp_blob, &sendlen, 0);
137         if (!NT_STATUS_IS_OK(status)) {
138                 return False;
139         }
140
141         if (buf->length != sendlen) {
142                 return False;
143         }
144
145         return True;
146 }
147
148 static void peek_into_read_buf(struct rw_buffer *buf, uint8_t **out,
149                                size_t *out_length)
150 {
151         *out = buf->data;
152         *out_length = buf->length;
153 }
154
155 static void consumed_from_read_buf(struct rw_buffer *buf,
156                                    size_t length)
157 {
158         memcpy(buf->data, buf->data+length, buf->length-length);
159         buf->length -= length;
160 }
161
162 static BOOL ldap_append_to_buf(struct ldap_message *msg, struct rw_buffer *buf)
163 {
164         DATA_BLOB blob;
165         BOOL res;
166
167         if (!ldap_encode(msg, &blob))
168                 return False;
169
170         res = append_to_buf(buf, blob.data, blob.length);
171
172         data_blob_free(&blob);
173         return res;
174 }
175
176 static void reply_unwilling(struct ldapsrv_connection *ldap_conn, int error)
177 {
178         struct ldap_message *msg;
179         struct ldap_ExtendedResponse *r;
180
181         msg = new_ldap_message();
182
183         if (msg == NULL) {
184                 ldapsrv_terminate_connection(ldap_conn, "new_ldap_message() failed");
185                 return;
186         }
187
188         msg->messageid = 0;
189         r = &msg->r.ExtendedResponse;   
190
191         /* When completely freaking out, OpenLDAP responds with an ExtResp */
192         msg->type = LDAP_TAG_ExtendedResponse;
193         r->response.resultcode = error;
194         r->response.dn = NULL;
195         r->response.errormessage = NULL;
196         r->response.referral = NULL;
197         r->name = NULL;
198         r->value.data = NULL;
199         r->value.length = 0;
200
201         ldap_append_to_buf(msg, &ldap_conn->out_buffer);
202
203         talloc_destroy(msg->mem_ctx);
204 }
205
206 static void ldap_reply_BindRequest(struct ldapsrv_connection *conn, 
207                                    struct ldap_message *request)
208 {
209         struct ldap_BindRequest *req = &request->r.BindRequest;
210
211         struct ldap_message *msg;
212         struct ldap_BindResponse *resp;
213
214         DEBUG(5, ("Binding as %s with pw %s\n",
215                   req->dn, req->creds.password));
216
217         msg = new_ldap_message();
218
219         if (msg == NULL) {
220                 ldapsrv_terminate_connection(conn, "new_ldap_message() failed");
221                 return;
222         }
223
224         resp = &msg->r.BindResponse;
225
226         msg->messageid = request->messageid;
227         msg->type = LDAP_TAG_BindResponse;
228         resp->response.resultcode = 0;
229         resp->response.dn = NULL;
230         resp->response.errormessage = NULL;
231         resp->response.referral = NULL;
232         resp->SASL.secblob = data_blob(NULL, 0);
233
234         ldap_append_to_buf(msg, &conn->out_buffer);
235         talloc_destroy(msg->mem_ctx);
236 }
237
238 static void ldap_reply_SearchRequest(struct ldapsrv_connection *conn,
239                                      struct ldap_message *request)
240 {
241         struct ldap_SearchRequest *req = &request->r.SearchRequest;
242
243         struct ldap_message *msg;
244         struct ldap_Result *resp;
245
246         DEBUG(10, ("Search filter: %s\n", req->filter));
247
248         msg = new_ldap_message();
249
250         if (msg == NULL) {
251                 ldapsrv_terminate_connection(conn, "new_ldap_message() failed");
252                 return;
253         }
254
255         msg->messageid = request->messageid;
256         resp = &msg->r.SearchResultDone;
257
258         /* Is this a rootdse request? */
259         if ((strlen(req->basedn) == 0) &&
260             (req->scope == LDAP_SEARCH_SCOPE_BASE) &&
261             strequal(req->filter, "(objectclass=*)")) {
262
263 #define ATTR_BLOB_CONST(val) data_blob(val, sizeof(val)-1)
264 #define ATTR_CONST_SINGLE(attr, blob, nam, val) do { \
265         attr.name = nam; \
266         attr.num_values = ARRAY_SIZE(blob); \
267         attr.values = blob; \
268         blob[0] = ATTR_BLOB_CONST(val); \
269 } while(0)
270 #define ATTR_CONST_SINGLE_NOVAL(attr, blob, nam) do { \
271         attr.name = nam;\
272         attr.num_values = ARRAY_SIZE(blob); \
273         attr.values = blob;\
274 } while(0)
275                 TALLOC_CTX *mem_ctx;
276                 struct ldap_attribute attrs[3];
277                 DATA_BLOB currentTime[1];
278                 DATA_BLOB supportedLDAPVersion[2];
279                 DATA_BLOB dnsHostName[1];
280
281                 mem_ctx = talloc_init("rootDSE");
282                 if (!mem_ctx) {
283                         ldapsrv_terminate_connection(conn, "no memory");
284                         return;
285                 }
286
287                 /* 
288                  * currentTime
289                  * 20040918090350.0Z
290                  */
291                 ATTR_CONST_SINGLE_NOVAL(attrs[0], currentTime, "currentTime");
292                 {
293                         char *str = ldap_timestring(mem_ctx, time(NULL));
294                         if (!str) {
295                                 ldapsrv_terminate_connection(conn, "no memory");
296                                 return;
297                         }
298                         currentTime[0] = data_blob(str, strlen(str));
299                         talloc_free(str);
300                 }
301
302                 /* 
303                  * subschemaSubentry 
304                  * CN=Aggregate,CN=Schema,CN=Configuration,DC=DOM,DC=TLD
305                  */
306
307                 /* 
308                  * dsServiceName
309                  * CN=NTDS Settings,CN=NETBIOSNAME,CN=Servers,CN=Default-First-Site,CN=Sites,CN=Configuration,DC=DOM,DC=TLD
310                  */
311
312                 /* 
313                  * namingContexts
314                  * DC=DOM,DC=TLD
315                  * CN=Configuration,DC=DOM,DC=TLD
316                  * CN=Schema,CN=Configuration,DC=DOM,DC=TLD
317                  * DC=DomainDnsZones,DC=DOM,DC=TLD
318                  * DC=ForestDnsZones,DC=DOM,DC=TLD
319                  */
320
321                 /* 
322                  * defaultNamingContext
323                  * DC=DOM,DC=TLD
324                  */
325
326                 /* 
327                  * schemaNamingContext
328                  * CN=Schema,CN=Configuration,DC=DOM,DC=TLD
329                  */
330
331                 /* 
332                  * configurationNamingContext
333                  * CN=Configuration,DC=DOM,DC=TLD
334                  */
335
336                 /* 
337                  * rootDomainNamingContext
338                  * DC=DOM,DC=TLD
339                  */
340
341                 /* 
342                  * supportedControl
343                  * 1.2.840.113556.1.4.319
344                  * 1.2.840.113556.1.4.801
345                  * 1.2.840.113556.1.4.473
346                  * 1.2.840.113556.1.4.528
347                  * 1.2.840.113556.1.4.417
348                  * 1.2.840.113556.1.4.619
349                  * 1.2.840.113556.1.4.841
350                  * 1.2.840.113556.1.4.529
351                  * 1.2.840.113556.1.4.805
352                  * 1.2.840.113556.1.4.521
353                  * 1.2.840.113556.1.4.970
354                  * 1.2.840.113556.1.4.1338
355                  * 1.2.840.113556.1.4.474
356                  * 1.2.840.113556.1.4.1339
357                  * 1.2.840.113556.1.4.1340
358                  * 1.2.840.113556.1.4.1413
359                  * 2.16.840.1.113730.3.4.9
360                  * 2.16.840.1.113730.3.4.10
361                  * 1.2.840.113556.1.4.1504
362                  * 1.2.840.113556.1.4.1852
363                  * 1.2.840.113556.1.4.802
364                  */
365
366                 /* 
367                  * supportedLDAPVersion 
368                  * 3
369                  * 2
370                  */
371                 ATTR_CONST_SINGLE_NOVAL(attrs[1], supportedLDAPVersion, "supportedLDAPVersion");
372                 supportedLDAPVersion[0] = ATTR_BLOB_CONST("3");
373                 supportedLDAPVersion[1] = ATTR_BLOB_CONST("2");
374
375                 /* 
376                  * supportedLDAPPolicies
377                  * MaxPoolThreads
378                  * MaxDatagramRecv
379                  * MaxReceiveBuffer
380                  * InitRecvTimeout
381                  * MaxConnections
382                  * MaxConnIdleTime
383                  * MaxPageSize
384                  * MaxQueryDuration
385                  * MaxTempTableSize
386                  * MaxResultSetSize
387                  * MaxNotificationPerConn
388                  * MaxValRange
389                  */
390
391                 /* 
392                  * highestCommittedUSN 
393                  * 4555
394                  */
395
396                 /* 
397                  * supportedSASLMechanisms
398                  * GSSAPI
399                  * GSS-SPNEGO
400                  * EXTERNAL
401                  * DIGEST-MD5
402                  */
403
404                 /* 
405                  * dnsHostName
406                  * netbiosname.dom.tld
407                  */
408                 ATTR_CONST_SINGLE_NOVAL(attrs[2], dnsHostName, "dnsHostName");
409                 dnsHostName[0] = data_blob(lp_netbios_name(),strlen(lp_netbios_name()));
410
411                 /* 
412                  * ldapServiceName
413                  * dom.tld:netbiosname$@DOM.TLD
414                  */
415
416                 /* 
417                  * serverName:
418                  * CN=NETBIOSNAME,CN=Servers,CN=Default-First-Site,CN=Sites,CN=Configuration,DC=DOM,DC=TLD
419                  */
420
421                 /* 
422                  * supportedCapabilities
423                  * 1.2.840.113556.1.4.800
424                  * 1.2.840.113556.1.4.1670
425                  * 1.2.840.113556.1.4.1791
426                  */
427
428                 /* 
429                  * isSynchronized:
430                  * TRUE/FALSE
431                  */
432
433                 /* 
434                  * isGlobalCatalogReady
435                  * TRUE/FALSE
436                  */
437
438                 /* 
439                  * domainFunctionality
440                  * 0
441                  */
442
443                 /* 
444                  * forestFunctionality
445                  * 0
446                  */
447
448                 /* 
449                  * domainControllerFunctionality
450                  * 2
451                  */
452
453                 msg->type = LDAP_TAG_SearchResultEntry;
454                 msg->r.SearchResultEntry.dn = "";
455                 msg->r.SearchResultEntry.num_attributes = ARRAY_SIZE(attrs);
456                 msg->r.SearchResultEntry.attributes = attrs;
457
458                 ldap_append_to_buf(msg, &conn->out_buffer);
459                 talloc_free(mem_ctx);
460         }
461
462         msg->type = LDAP_TAG_SearchResultDone;
463         resp->resultcode = 0;
464         resp->dn = NULL;
465         resp->errormessage = NULL;
466         resp->referral = NULL;
467
468         ldap_append_to_buf(msg, &conn->out_buffer);
469         talloc_destroy(msg->mem_ctx);
470 }
471
472 static void switch_ldap_message(struct ldapsrv_connection *conn,
473                          struct ldap_message *msg)
474 {
475         switch(msg->type) {
476         case LDAP_TAG_BindRequest:
477                 ldap_reply_BindRequest(conn, msg);
478                 break;
479         case LDAP_TAG_SearchRequest:
480                 ldap_reply_SearchRequest(conn, msg);
481                 break;
482         default:
483                 reply_unwilling(conn, 2);
484                 break;
485         }
486 }
487
488 static void ldap_queue_run(struct server_connection *conn)
489 {
490         struct ldapsrv_connection *ldap_conn = conn->private_data;
491         
492         while (ldap_conn->in_queue) {
493                 struct ldap_message_queue *req = ldap_conn->in_queue;
494                 DLIST_REMOVE(ldap_conn->in_queue, req);
495
496                 switch_ldap_message(ldap_conn, req->msg);
497                 talloc_destroy(req->msg->mem_ctx);
498         }
499 }
500
501 /*
502   called when a LDAP socket becomes readable
503 */
504 static void ldapsrv_recv(struct server_connection *conn, time_t t,
505                          uint16_t flags)
506 {
507         struct ldapsrv_connection *ldap_conn = conn->private_data;
508         uint8_t *buf;
509         int buf_length, msg_length;
510         DATA_BLOB blob;
511         ASN1_DATA data;
512         struct ldap_message *msg;
513         struct ldap_message_queue *queue_entry;
514
515         DEBUG(10,("ldapsrv_recv\n"));
516
517         if (!read_into_buf(conn->socket, &ldap_conn->in_buffer)) {
518                 ldapsrv_terminate_connection(ldap_conn, "read_into_buf() failed");
519                 return;
520         }
521
522         peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
523
524         while (buf_length > 0) {
525
526                 /* LDAP Messages are always SEQUENCES */
527
528                 if (!asn1_object_length(buf, buf_length, ASN1_SEQUENCE(0),
529                                         &msg_length)) {
530                         ldapsrv_terminate_connection(ldap_conn, "asn1_object_length() failed");
531                         return;
532                 }
533
534                 if (buf_length < msg_length) {
535                         /* Not enough yet */
536                         break;
537                 }
538
539                 /* We've got a complete LDAP request in the in-buffer, convert
540                  * that to a ldap_message and put it into the incoming
541                  * queue. */
542
543                 blob.data = buf;
544                 blob.length = msg_length;
545
546                 if (!asn1_load(&data, blob)) {
547                         ldapsrv_terminate_connection(ldap_conn, "asn1_load() failed");
548                         return;
549                 }
550
551                 msg = new_ldap_message();
552
553                 if ((msg == NULL) || !ldap_decode(&data, msg)) {
554                         ldapsrv_terminate_connection(ldap_conn, "ldap_decode() failed");
555                         return;
556                 }
557
558                 queue_entry = talloc_p(msg->mem_ctx, struct ldap_message_queue);
559
560                 if (queue_entry == NULL) {
561                         ldapsrv_terminate_connection(ldap_conn, "alloc_p(msg->mem_ctx, struct ldap_message_queue) failed");
562                         return;
563                 }
564
565                 queue_entry->msg = msg;
566
567                 DLIST_ADD_END(ldap_conn->in_queue, queue_entry,
568                               struct ldap_message_queue *);
569
570                 consumed_from_read_buf(&ldap_conn->in_buffer, msg_length);
571
572                 peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
573         }
574
575         ldap_queue_run(conn);
576
577         conn->event.fde->flags |= EVENT_FD_WRITE;
578
579         return;
580 }
581         
582 /*
583   called when a LDAP socket becomes writable
584 */
585 static void ldapsrv_send(struct server_connection *conn, time_t t,
586                          uint16_t flags)
587 {
588         struct ldapsrv_connection *ldap_conn = conn->private_data;
589
590         DEBUG(10,("ldapsrv_send\n"));
591
592         if (!write_from_buf(conn->socket, &ldap_conn->out_buffer)) {
593                 ldapsrv_terminate_connection(ldap_conn, "write_from_buf() failed");
594                 return;
595         }
596
597         conn->event.fde->flags &= ~EVENT_FD_WRITE;
598
599         return;
600 }
601
602 /*
603   called when connection is idle
604 */
605 static void ldapsrv_idle(struct server_connection *conn, time_t t)
606 {
607         DEBUG(10,("ldapsrv_idle: not implemented!\n"));
608         return;
609 }
610
611 static void ldapsrv_close(struct server_connection *conn, const char *reason)
612 {
613         struct ldapsrv_connection *ldap_conn = conn->private_data;
614
615         talloc_free(ldap_conn);
616
617         return;
618 }
619
620 /*
621   initialise a server_context from a open socket and register a event handler
622   for reading from that socket
623 */
624 static void ldapsrv_accept(struct server_connection *conn)
625 {
626         struct ldapsrv_connection *ldap_conn;
627
628         DEBUG(5, ("ldapsrv_accept\n"));
629
630         ldap_conn = talloc_p(NULL, struct ldapsrv_connection);
631
632         if (ldap_conn == NULL)
633                 return;
634
635         ZERO_STRUCTP(ldap_conn);
636         ldap_conn->connection = conn;
637
638         conn->private_data = ldap_conn;
639
640         return;
641 }
642
643 /*
644   called on a fatal error that should cause this server to terminate
645 */
646 static void ldapsrv_exit(struct server_service *service, const char *reason)
647 {
648         DEBUG(1,("ldapsrv_exit\n"));
649         return;
650 }
651
652 static const struct server_service_ops ldap_server_ops = {
653         .name                   = "ldap",
654         .service_init           = ldapsrv_init,
655         .accept_connection      = ldapsrv_accept,
656         .recv_handler           = ldapsrv_recv,
657         .send_handler           = ldapsrv_send,
658         .idle_handler           = ldapsrv_idle,
659         .close_connection       = ldapsrv_close,
660         .service_exit           = ldapsrv_exit, 
661 };
662
663 const struct server_service_ops *ldapsrv_get_ops(void)
664 {
665         return &ldap_server_ops;
666 }
667
668 NTSTATUS server_service_ldap_init(void)
669 {
670         return NT_STATUS_OK;    
671 }