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,
39 struct server_socket *srv_sock;
41 char *ip_str = talloc_strdup(service, inet_ntoa(*ifip));
43 srv_sock = service_setup_socket(service, model_ops, ip_str, &port);
46 srv_sock = service_setup_socket(service, model_ops, 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 in_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 in_addr *ifip;
115 /* Just bind to lp_socket_address() (usually 0.0.0.0) */
116 ifip = interpret_addr2(service, lp_socket_address());
117 add_socket(service, model_ops, ifip);
119 talloc_destroy(ifip);
123 /* This rw-buf api is made to avoid memcpy. For now do that like mad... The
124 idea is to write into a circular list of buffers where the ideal case is
125 that a read(2) holds a complete request that is then thrown away
128 void ldapsrv_consumed_from_buf(struct rw_buffer *buf,
131 memcpy(buf->data, buf->data+length, buf->length-length);
132 buf->length -= length;
135 static void peek_into_read_buf(struct rw_buffer *buf, uint8_t **out,
139 *out_length = buf->length;
142 BOOL ldapsrv_append_to_buf(struct rw_buffer *buf, uint8_t *data, size_t length)
144 buf->data = realloc(buf->data, buf->length+length);
146 if (buf->data == NULL)
149 memcpy(buf->data+buf->length, data, length);
151 buf->length += length;
155 static BOOL read_into_buf(struct socket_context *sock, struct rw_buffer *buf)
161 status = socket_recv(sock, sock, &tmp_blob, 1024, 0);
162 if (!NT_STATUS_IS_OK(status)) {
163 DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
167 ret = ldapsrv_append_to_buf(buf, tmp_blob.data, tmp_blob.length);
169 talloc_free(tmp_blob.data);
174 static BOOL ldapsrv_read_buf(struct ldapsrv_connection *conn)
181 int buf_length, sasl_length;
182 struct socket_context *sock = conn->connection->socket;
185 if (!conn->gensec || !conn->session_info ||
186 !(gensec_have_feature(conn->gensec, GENSEC_WANT_SIGN) &&
187 gensec_have_feature(conn->gensec, GENSEC_WANT_SEAL))) {
188 return read_into_buf(sock, &conn->in_buffer);
191 mem_ctx = talloc(conn, 0);
193 DEBUG(0,("no memory\n"));
197 status = socket_recv(sock, mem_ctx, &tmp_blob, 1024, 0);
198 if (!NT_STATUS_IS_OK(status)) {
199 DEBUG(10,("socket_recv: %s\n",nt_errstr(status)));
200 talloc_free(mem_ctx);
204 ret = ldapsrv_append_to_buf(&conn->sasl_in_buffer, tmp_blob.data, tmp_blob.length);
206 talloc_free(mem_ctx);
210 peek_into_read_buf(&conn->sasl_in_buffer, &buf, &buf_length);
212 if (buf_length < 4) {
214 talloc_free(mem_ctx);
218 sasl_length = RIVAL(buf, 0);
220 if (buf_length < (4 + sasl_length)) {
222 talloc_free(mem_ctx);
226 creds.data = buf + 4;
227 creds.length = gensec_sig_size(conn->gensec);
229 if (creds.length > sasl_length) {
230 /* invalid packet? */
231 talloc_free(mem_ctx);
235 tmp_blob.data = buf + (4 + creds.length);
236 tmp_blob.length = (4 + sasl_length) - (4 + creds.length);
238 if (gensec_have_feature(conn->gensec, GENSEC_WANT_SEAL)) {
239 status = gensec_unseal_packet(conn->gensec, mem_ctx,
240 tmp_blob.data, tmp_blob.length,
241 tmp_blob.data, tmp_blob.length,
243 if (!NT_STATUS_IS_OK(status)) {
244 DEBUG(0,("gensec_unseal_packet: %s\n",nt_errstr(status)));
245 talloc_free(mem_ctx);
249 status = gensec_check_packet(conn->gensec, mem_ctx,
250 tmp_blob.data, tmp_blob.length,
251 tmp_blob.data, tmp_blob.length,
253 if (!NT_STATUS_IS_OK(status)) {
254 DEBUG(0,("gensec_check_packet: %s\n",nt_errstr(status)));
255 talloc_free(mem_ctx);
260 ret = ldapsrv_append_to_buf(&conn->in_buffer, tmp_blob.data, tmp_blob.length);
262 talloc_free(mem_ctx);
266 ldapsrv_consumed_from_buf(&conn->sasl_in_buffer, 4 + sasl_length);
268 talloc_free(mem_ctx);
272 static BOOL write_from_buf(struct socket_context *sock, struct rw_buffer *buf)
278 tmp_blob.data = buf->data;
279 tmp_blob.length = buf->length;
281 status = socket_send(sock, sock, &tmp_blob, &sendlen, 0);
282 if (!NT_STATUS_IS_OK(status)) {
283 DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
287 ldapsrv_consumed_from_buf(buf, sendlen);
292 static BOOL ldapsrv_write_buf(struct ldapsrv_connection *conn)
300 struct socket_context *sock = conn->connection->socket;
303 if (!conn->gensec || !conn->session_info ||
304 !(gensec_have_feature(conn->gensec, GENSEC_WANT_SIGN) &&
305 gensec_have_feature(conn->gensec, GENSEC_WANT_SEAL))) {
306 return write_from_buf(sock, &conn->out_buffer);
309 mem_ctx = talloc(conn, 0);
311 DEBUG(0,("no memory\n"));
315 tmp_blob.data = conn->out_buffer.data;
316 tmp_blob.length = conn->out_buffer.length;
318 if (tmp_blob.length == 0) {
322 if (gensec_have_feature(conn->gensec, GENSEC_WANT_SEAL)) {
323 status = gensec_seal_packet(conn->gensec, mem_ctx,
324 tmp_blob.data, tmp_blob.length,
325 tmp_blob.data, tmp_blob.length,
327 if (!NT_STATUS_IS_OK(status)) {
328 DEBUG(0,("gensec_seal_packet: %s\n",nt_errstr(status)));
329 talloc_free(mem_ctx);
333 status = gensec_sign_packet(conn->gensec, mem_ctx,
334 tmp_blob.data, tmp_blob.length,
335 tmp_blob.data, tmp_blob.length,
337 if (!NT_STATUS_IS_OK(status)) {
338 DEBUG(0,("gensec_sign_packet: %s\n",nt_errstr(status)));
339 talloc_free(mem_ctx);
344 sasl = data_blob_talloc(mem_ctx, NULL, 4 + creds.length + tmp_blob.length);
346 DEBUG(0,("no memory\n"));
347 talloc_free(mem_ctx);
351 RSIVAL(sasl.data, 0, creds.length + tmp_blob.length);
352 memcpy(sasl.data + 4, creds.data, creds.length);
353 memcpy(sasl.data + 4 + creds.length, tmp_blob.data, tmp_blob.length);
355 ret = ldapsrv_append_to_buf(&conn->sasl_out_buffer, sasl.data, sasl.length);
357 talloc_free(mem_ctx);
360 ldapsrv_consumed_from_buf(&conn->out_buffer, tmp_blob.length);
362 tmp_blob.data = conn->sasl_out_buffer.data;
363 tmp_blob.length = conn->sasl_out_buffer.length;
365 status = socket_send(sock, mem_ctx, &tmp_blob, &sendlen, 0);
366 if (!NT_STATUS_IS_OK(status)) {
367 DEBUG(10,("socket_send() %s\n",nt_errstr(status)));
368 talloc_free(mem_ctx);
372 ldapsrv_consumed_from_buf(&conn->sasl_out_buffer, sendlen);
374 talloc_free(mem_ctx);
379 static BOOL ldap_encode_to_buf(struct ldap_message *msg, struct rw_buffer *buf)
384 if (!ldap_encode(msg, &blob))
387 res = ldapsrv_append_to_buf(buf, blob.data, blob.length);
389 data_blob_free(&blob);
393 NTSTATUS ldapsrv_do_responses(struct ldapsrv_connection *conn)
395 struct ldapsrv_call *call, *next_call = NULL;
396 struct ldapsrv_reply *reply, *next_reply = NULL;
398 for (call=conn->calls; call; call=next_call) {
399 for (reply=call->replies; reply; reply=next_reply) {
400 if (!ldap_encode_to_buf(&reply->msg, &conn->out_buffer)) {
401 return NT_STATUS_FOOBAR;
403 next_reply = reply->next;
404 DLIST_REMOVE(call->replies, reply);
405 reply->state = LDAPSRV_REPLY_STATE_SEND;
408 next_call = call->next;
409 DLIST_REMOVE(conn->calls, call);
410 call->state = LDAPSRV_CALL_STATE_COMPLETE;
417 NTSTATUS ldapsrv_flush_responses(struct ldapsrv_connection *conn)
423 called when a LDAP socket becomes readable
425 static void ldapsrv_recv(struct server_connection *conn, time_t t,
428 struct ldapsrv_connection *ldap_conn = conn->private_data;
430 int buf_length, msg_length;
433 struct ldapsrv_call *call;
436 DEBUG(10,("ldapsrv_recv\n"));
438 if (!ldapsrv_read_buf(ldap_conn)) {
439 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_read_buf() failed");
443 peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
445 while (buf_length > 0) {
446 /* LDAP Messages are always SEQUENCES */
448 if (!asn1_object_length(buf, buf_length, ASN1_SEQUENCE(0),
450 ldapsrv_terminate_connection(ldap_conn, "asn1_object_length() failed");
454 if (buf_length < msg_length) {
459 /* We've got a complete LDAP request in the in-buffer, convert
460 * that to a ldap_message and put it into the incoming
464 blob.length = msg_length;
466 if (!asn1_load(&data, blob)) {
467 ldapsrv_terminate_connection(ldap_conn, "asn1_load() failed");
471 call = talloc_p(ldap_conn, struct ldapsrv_call);
473 ldapsrv_terminate_connection(ldap_conn, "no memory");
478 call->state = LDAPSRV_CALL_STATE_NEW;
479 call->conn = ldap_conn;
480 call->request.mem_ctx = call;
482 if (!ldap_decode(&data, &call->request)) {
483 dump_data(0,buf, msg_length);
485 ldapsrv_terminate_connection(ldap_conn, "ldap_decode() failed");
491 DLIST_ADD_END(ldap_conn->calls, call,
492 struct ldapsrv_call *);
494 ldapsrv_consumed_from_buf(&ldap_conn->in_buffer, msg_length);
496 status = ldapsrv_do_call(call);
497 if (!NT_STATUS_IS_OK(status)) {
498 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_do_call() failed");
502 peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
505 status = ldapsrv_do_responses(ldap_conn);
506 if (!NT_STATUS_IS_OK(status)) {
507 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_do_responses() failed");
511 if ((ldap_conn->out_buffer.length > 0)||(ldap_conn->sasl_out_buffer.length > 0)) {
512 conn->event.fde->flags |= EVENT_FD_WRITE;
519 called when a LDAP socket becomes writable
521 static void ldapsrv_send(struct server_connection *conn, time_t t,
524 struct ldapsrv_connection *ldap_conn = conn->private_data;
526 DEBUG(10,("ldapsrv_send\n"));
528 if (!ldapsrv_write_buf(ldap_conn)) {
529 ldapsrv_terminate_connection(ldap_conn, "ldapsrv_write_buf() failed");
533 if (ldap_conn->out_buffer.length == 0 && ldap_conn->sasl_out_buffer.length == 0) {
534 conn->event.fde->flags &= ~EVENT_FD_WRITE;
541 called when connection is idle
543 static void ldapsrv_idle(struct server_connection *conn, time_t t)
545 DEBUG(10,("ldapsrv_idle: not implemented!\n"));
549 static void ldapsrv_close(struct server_connection *conn, const char *reason)
555 initialise a server_context from a open socket and register a event handler
556 for reading from that socket
558 static void ldapsrv_accept(struct server_connection *conn)
560 struct ldapsrv_connection *ldap_conn;
562 DEBUG(10, ("ldapsrv_accept\n"));
564 ldap_conn = talloc_p(conn, struct ldapsrv_connection);
566 if (ldap_conn == NULL)
569 ZERO_STRUCTP(ldap_conn);
570 ldap_conn->connection = conn;
571 ldap_conn->service = talloc_reference(ldap_conn, conn->service->private_data);
573 conn->private_data = ldap_conn;
579 called on a fatal error that should cause this server to terminate
581 static void ldapsrv_exit(struct server_service *service, const char *reason)
583 DEBUG(10,("ldapsrv_exit\n"));
587 static const struct server_service_ops ldap_server_ops = {
589 .service_init = ldapsrv_init,
590 .accept_connection = ldapsrv_accept,
591 .recv_handler = ldapsrv_recv,
592 .send_handler = ldapsrv_send,
593 .idle_handler = ldapsrv_idle,
594 .close_connection = ldapsrv_close,
595 .service_exit = ldapsrv_exit,
598 const struct server_service_ops *ldapsrv_get_ops(void)
600 return &ldap_server_ops;
603 NTSTATUS server_service_ldap_init(void)