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