2 Unix SMB/CIFS implementation.
4 Copyright (C) Volker Lendecke 2004
5 Copyright (C) Stefan Metzmacher 2004
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.
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.
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.
25 close the socket and shutdown a server_context
27 static void ldapsrv_terminate_connection(struct ldapsrv_connection *ldap_conn, const char *reason)
29 server_terminate_connection(ldap_conn->connection, reason);
33 add a socket address to the list of events, one event per port
35 static void add_socket(struct server_service *service,
36 const struct model_ops *model_ops,
37 struct ipv4_addr *ifip)
39 struct server_socket *srv_sock;
41 char *ip_str = talloc_strdup(service, sys_inet_ntoa(*ifip));
43 srv_sock = service_setup_socket(service, model_ops, "ipv4", ip_str, &port);
46 srv_sock = service_setup_socket(service, model_ops, "ipv4", ip_str, &port);
51 /****************************************************************************
52 Open the socket communication.
53 ****************************************************************************/
54 static void ldapsrv_init(struct server_service *service,
55 const struct model_ops *model_ops)
57 struct ldapsrv_service *ldap_service;
58 struct ldapsrv_partition *part;
60 DEBUG(10,("ldapsrv_init\n"));
62 ldap_service = talloc_p(service, struct ldapsrv_service);
64 DEBUG(0,("talloc_p(service, struct ldapsrv_service) failed\n"));
67 ZERO_STRUCTP(ldap_service);
69 part = talloc_p(ldap_service, struct ldapsrv_partition);
71 DEBUG(0,("talloc_p(ldap_service, struct ldapsrv_partition) failed\n"));
74 part->base_dn = ""; /* RootDSE */
75 part->ops = ldapsrv_get_rootdse_partition_ops();
77 ldap_service->rootDSE = part;
78 DLIST_ADD_END(ldap_service->partitions, part, struct ldapsrv_partition *);
80 part = talloc_p(ldap_service, struct ldapsrv_partition);
82 DEBUG(0,("talloc_p(ldap_service, struct ldapsrv_partition) failed\n"));
85 part->base_dn = "*"; /* default partition */
86 part->ops = ldapsrv_get_sldb_partition_ops();
88 ldap_service->default_partition = part;
89 DLIST_ADD_END(ldap_service->partitions, part, struct ldapsrv_partition *);
91 service->private_data = ldap_service;
93 if (lp_interfaces() && lp_bind_interfaces_only()) {
94 int num_interfaces = iface_count();
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.
101 for(i = 0; i < num_interfaces; i++) {
102 struct ipv4_addr *ifip = iface_n_ip(i);
105 DEBUG(0,("ldapsrv_init: interface %d has NULL "
106 "IP address !\n", i));
110 add_socket(service, model_ops, ifip);
113 struct ipv4_addr ifip;
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);
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
126 void ldapsrv_consumed_from_buf(struct rw_buffer *buf,
129 memcpy(buf->data, buf->data+length, buf->length-length);
130 buf->length -= length;
133 static void peek_into_read_buf(struct rw_buffer *buf, uint8_t **out,
137 *out_length = buf->length;
140 BOOL ldapsrv_append_to_buf(struct rw_buffer *buf, uint8_t *data, size_t length)
142 buf->data = realloc(buf->data, buf->length+length);
144 if (buf->data == NULL)
147 memcpy(buf->data+buf->length, data, length);
149 buf->length += length;
153 static BOOL read_into_buf(struct socket_context *sock, struct rw_buffer *buf)
160 tmp_blob = data_blob_talloc(sock, NULL, 1024);
161 if (tmp_blob.data == NULL) {
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);
172 ret = ldapsrv_append_to_buf(buf, tmp_blob.data, tmp_blob.length);
174 talloc_free(tmp_blob.data);
179 static BOOL ldapsrv_read_buf(struct ldapsrv_connection *conn)
186 int buf_length, sasl_length;
187 struct socket_context *sock = conn->connection->socket;
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);
197 mem_ctx = talloc(conn, 0);
199 DEBUG(0,("no memory\n"));
203 tmp_blob = data_blob_talloc(mem_ctx, NULL, 1024);
204 if (tmp_blob.data == NULL) {
205 talloc_free(mem_ctx);
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);
215 tmp_blob.length = nread;
217 ret = ldapsrv_append_to_buf(&conn->sasl_in_buffer, tmp_blob.data, tmp_blob.length);
219 talloc_free(mem_ctx);
223 peek_into_read_buf(&conn->sasl_in_buffer, &buf, &buf_length);
225 if (buf_length < 4) {
227 talloc_free(mem_ctx);
231 sasl_length = RIVAL(buf, 0);
233 if (buf_length < (4 + sasl_length)) {
235 talloc_free(mem_ctx);
239 creds.data = buf + 4;
240 creds.length = gensec_sig_size(conn->gensec);
242 if (creds.length > sasl_length) {
243 /* invalid packet? */
244 talloc_free(mem_ctx);
248 tmp_blob.data = buf + (4 + creds.length);
249 tmp_blob.length = (4 + sasl_length) - (4 + creds.length);
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,
256 if (!NT_STATUS_IS_OK(status)) {
257 DEBUG(0,("gensec_unseal_packet: %s\n",nt_errstr(status)));
258 talloc_free(mem_ctx);
262 status = gensec_check_packet(conn->gensec, mem_ctx,
263 tmp_blob.data, tmp_blob.length,
264 tmp_blob.data, tmp_blob.length,
266 if (!NT_STATUS_IS_OK(status)) {
267 DEBUG(0,("gensec_check_packet: %s\n",nt_errstr(status)));
268 talloc_free(mem_ctx);
273 ret = ldapsrv_append_to_buf(&conn->in_buffer, tmp_blob.data, tmp_blob.length);
275 talloc_free(mem_ctx);
279 ldapsrv_consumed_from_buf(&conn->sasl_in_buffer, 4 + sasl_length);
281 talloc_free(mem_ctx);
285 static BOOL write_from_buf(struct socket_context *sock, struct rw_buffer *buf)
291 tmp_blob.data = buf->data;
292 tmp_blob.length = buf->length;
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)));
300 ldapsrv_consumed_from_buf(buf, sendlen);
305 static BOOL ldapsrv_write_buf(struct ldapsrv_connection *conn)
313 struct socket_context *sock = conn->connection->socket;
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);
322 mem_ctx = talloc(conn, 0);
324 DEBUG(0,("no memory\n"));
328 tmp_blob.data = conn->out_buffer.data;
329 tmp_blob.length = conn->out_buffer.length;
331 if (tmp_blob.length == 0) {
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,
340 if (!NT_STATUS_IS_OK(status)) {
341 DEBUG(0,("gensec_seal_packet: %s\n",nt_errstr(status)));
342 talloc_free(mem_ctx);
346 status = gensec_sign_packet(conn->gensec, mem_ctx,
347 tmp_blob.data, tmp_blob.length,
348 tmp_blob.data, tmp_blob.length,
350 if (!NT_STATUS_IS_OK(status)) {
351 DEBUG(0,("gensec_sign_packet: %s\n",nt_errstr(status)));
352 talloc_free(mem_ctx);
357 sasl = data_blob_talloc(mem_ctx, NULL, 4 + creds.length + tmp_blob.length);
359 DEBUG(0,("no memory\n"));
360 talloc_free(mem_ctx);
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);
368 ret = ldapsrv_append_to_buf(&conn->sasl_out_buffer, sasl.data, sasl.length);
370 talloc_free(mem_ctx);
373 ldapsrv_consumed_from_buf(&conn->out_buffer, tmp_blob.length);
375 tmp_blob.data = conn->sasl_out_buffer.data;
376 tmp_blob.length = conn->sasl_out_buffer.length;
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);
385 ldapsrv_consumed_from_buf(&conn->sasl_out_buffer, sendlen);
387 talloc_free(mem_ctx);
392 static BOOL ldap_encode_to_buf(struct ldap_message *msg, struct rw_buffer *buf)
397 if (!ldap_encode(msg, &blob))
400 res = ldapsrv_append_to_buf(buf, blob.data, blob.length);
402 data_blob_free(&blob);
406 NTSTATUS ldapsrv_do_responses(struct ldapsrv_connection *conn)
408 struct ldapsrv_call *call, *next_call = NULL;
409 struct ldapsrv_reply *reply, *next_reply = NULL;
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;
416 next_reply = reply->next;
417 DLIST_REMOVE(call->replies, reply);
418 reply->state = LDAPSRV_REPLY_STATE_SEND;
421 next_call = call->next;
422 DLIST_REMOVE(conn->calls, call);
423 call->state = LDAPSRV_CALL_STATE_COMPLETE;
430 NTSTATUS ldapsrv_flush_responses(struct ldapsrv_connection *conn)
436 called when a LDAP socket becomes readable
438 static void ldapsrv_recv(struct server_connection *conn, time_t t,
441 struct ldapsrv_connection *ldap_conn = conn->private_data;
443 int buf_length, msg_length;
446 struct ldapsrv_call *call;
449 DEBUG(10,("ldapsrv_recv\n"));
451 if (!ldapsrv_read_buf(ldap_conn)) {
452 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_read_buf() failed");
456 peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
458 while (buf_length > 0) {
459 /* LDAP Messages are always SEQUENCES */
461 if (!asn1_object_length(buf, buf_length, ASN1_SEQUENCE(0),
463 ldapsrv_terminate_connection(ldap_conn, "asn1_object_length() failed");
467 if (buf_length < msg_length) {
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
477 blob.length = msg_length;
479 if (!asn1_load(&data, blob)) {
480 ldapsrv_terminate_connection(ldap_conn, "asn1_load() failed");
484 call = talloc_p(ldap_conn, struct ldapsrv_call);
486 ldapsrv_terminate_connection(ldap_conn, "no memory");
491 call->state = LDAPSRV_CALL_STATE_NEW;
492 call->conn = ldap_conn;
493 call->request.mem_ctx = call;
495 if (!ldap_decode(&data, &call->request)) {
496 dump_data(0,buf, msg_length);
498 ldapsrv_terminate_connection(ldap_conn, "ldap_decode() failed");
504 DLIST_ADD_END(ldap_conn->calls, call,
505 struct ldapsrv_call *);
507 ldapsrv_consumed_from_buf(&ldap_conn->in_buffer, msg_length);
509 status = ldapsrv_do_call(call);
510 if (!NT_STATUS_IS_OK(status)) {
511 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_do_call() failed");
515 peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
518 status = ldapsrv_do_responses(ldap_conn);
519 if (!NT_STATUS_IS_OK(status)) {
520 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_do_responses() failed");
524 if ((ldap_conn->out_buffer.length > 0)||(ldap_conn->sasl_out_buffer.length > 0)) {
525 conn->event.fde->flags |= EVENT_FD_WRITE;
532 called when a LDAP socket becomes writable
534 static void ldapsrv_send(struct server_connection *conn, time_t t,
537 struct ldapsrv_connection *ldap_conn = conn->private_data;
539 DEBUG(10,("ldapsrv_send\n"));
541 if (!ldapsrv_write_buf(ldap_conn)) {
542 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_write_buf() failed");
546 if (ldap_conn->out_buffer.length == 0 && ldap_conn->sasl_out_buffer.length == 0) {
547 conn->event.fde->flags &= ~EVENT_FD_WRITE;
554 called when connection is idle
556 static void ldapsrv_idle(struct server_connection *conn, time_t t)
558 DEBUG(10,("ldapsrv_idle: not implemented!\n"));
562 static void ldapsrv_close(struct server_connection *conn, const char *reason)
568 initialise a server_context from a open socket and register a event handler
569 for reading from that socket
571 static void ldapsrv_accept(struct server_connection *conn)
573 struct ldapsrv_connection *ldap_conn;
575 DEBUG(10, ("ldapsrv_accept\n"));
577 ldap_conn = talloc_p(conn, struct ldapsrv_connection);
579 if (ldap_conn == NULL)
582 ZERO_STRUCTP(ldap_conn);
583 ldap_conn->connection = conn;
584 ldap_conn->service = talloc_reference(ldap_conn, conn->service->private_data);
586 conn->private_data = ldap_conn;
592 called on a fatal error that should cause this server to terminate
594 static void ldapsrv_exit(struct server_service *service, const char *reason)
596 DEBUG(10,("ldapsrv_exit\n"));
600 static const struct server_service_ops ldap_server_ops = {
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,
611 const struct server_service_ops *ldapsrv_get_ops(void)
613 return &ldap_server_ops;
616 NTSTATUS server_service_ldap_init(void)