--oC1+HKm2/end4ao3
Content-Type: multipart/mixed; boundary="TB36FDmn/VVEgNH/"
Content-Disposition: inline


--TB36FDmn/VVEgNH/
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sun, Sep 12, 2004 at 05:09:28PM +1000, Andrew Bartlett wrote:
> The next step will be to generate the PAC (as I know how to handle
> that), and to wait for an LDAP server to become viable.


As this was mentioned, find a bogus prototype attached.

Volker

--TB36FDmn/VVEgNH/
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ldap-server-20040908.diff"
Content-Transfer-Encoding: quoted-printable

diff -urN SAMBA_4_0/source/configure.in source/configure.in
--- SAMBA_4_0/source/configure.in 2004-08-20 08:52:31.000000000 +0200
+++ source/configure.in 2004-09-08 12:13:24.000000000 +0200
@@ -27,6 +27,7 @@
SMB_INCLUDE_M4(libnet/config.m4)
SMB_INCLUDE_M4(smbd/process_model.m4)
SMB_INCLUDE_M4(smb_server/config.m4)
+SMB_INCLUDE_M4(ldap_server/config.m4)
SMB_INCLUDE_M4(auth/config.m4)
SMB_INCLUDE_M4(ntvfs/config.m4)
SMB_INCLUDE_M4(rpc_server/config.m4)
diff -urN SAMBA_4_0/source/include/includes.h source/include/includes.h
--- SAMBA_4_0/source/include/includes.h 2004-09-08 00:02:44.000000000 +0200
+++ source/include/includes.h 2004-09-08 12:22:04.000000000 +0200
@@ -664,6 +664,7 @@
#include "request.h"
#include "signing.h"
#include "smb_server/smb_server.h"
+#include "ldap_server/ldap_server.h"
#include "ntvfs/ntvfs.h"
#include "cli_context.h"
#include "registry.h"
diff -urN SAMBA_4_0/source/ldap_server/config.m4 source/ldap_server/config.=
m4
--- SAMBA_4_0/source/ldap_server/config.m4 1970-01-01 01:00:00.000000000 +0=
100
+++ source/ldap_server/config.m4 2004-08-14 01:56:11.000000000 +0200
@@ -0,0 +1,3 @@
+dnl # LDAP server subsystem
+
+SMB_SUBSYSTEM_MK(LDAP,ldap_server/config.mk)
diff -urN SAMBA_4_0/source/ldap_server/config.mk source/ldap_server/config.=
mk
--- SAMBA_4_0/source/ldap_server/config.mk 1970-01-01 01:00:00.000000000 +0=
100
+++ source/ldap_server/config.mk 2004-09-08 14:40:05.000000000 +0200
@@ -0,0 +1,14 @@
+# LDAP server subsystem
+
+#######################
+# Start SUBSYSTEM LDAP
+[SUBSYSTEM::LDAP]
+INIT_OBJ_FILES =3D \
+ ldap_server/ldap_server.o
+ADD_OBJ_FILES =3D \
+ libcli/ldap/ldap.o \
+ libcli/ldap/ldap_ldif.o
+REQUIRED_SUBSYSTEMS =3D \
+ NTVFS
+# End SUBSYSTEM SMB
+#######################
diff -urN SAMBA_4_0/source/ldap_server/ldap_server.c source/ldap_server/lda=
p_server.c
--- SAMBA_4_0/source/ldap_server/ldap_server.c 1970-01-01 01:00:00.00000000=
0 +0100
+++ source/ldap_server/ldap_server.c 2004-09-08 17:04:06.000000000 +0200
@@ -0,0 +1,445 @@
+/*=20
+ Unix SMB/CIFS implementation.
+ process incoming packets - main loop
+ Copyright (C) Andrew Tridgell 1992-2003
+ Copyright (C) James J Myers 2003
+ =20
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ =20
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ =20
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*
+ called on a fatal error that should cause this server to terminate
+*/
+static void ldapsrv_exit(struct server_service *service, const char *reaso=
n)
+{
+ DEBUG(1,("ldapsrv_exit\n"));
+ return;
+}
+
+/*
+ add a socket address to the list of events, one event per port
+*/
+static void add_socket(struct server_service *service,=20
+ const struct model_ops *model_ops,
+ struct socket_context *socket_ctx,=20
+ struct in_addr *ifip)
+{
+ uint16_t port =3D 389;
+
+ service_setup_socket(service, model_ops, socket_ctx, ifip, &port);
+}
+
+/************************************************** ***********************=
***
+ Open the socket communication.
+************************************************* *************************=
**/
+static void ldapsrv_init(struct server_service *service,
+ const struct model_ops *model_ops)
+{=09
+ DEBUG(1,("ldapsrv_init\n"));
+
+ if (lp_interfaces() && lp_bind_interfaces_only()) {
+ int num_interfaces =3D iface_count();
+ int i;
+
+ /* We have been given an interfaces line, and been=20
+ told to only bind to those interfaces. Create a
+ socket per interface and bind to only these.
+ */
+ for(i =3D 0; i < num_interfaces; i++) {
+ struct in_addr *ifip =3D iface_n_ip(i);
+
+ if (ifip =3D=3D NULL) {
+ DEBUG(0,("ldapsrv_init: interface %d has NULL "
+ "IP address !\n", i));
+ continue;
+ }
+
+ add_socket(service, model_ops, NULL, ifip);
+ }
+ } else {
+ struct in_addr *ifip;
+ TALLOC_CTX *mem_ctx =3D talloc_init("ldapsrv_init");
+
+ if (!mem_ctx) {
+ smb_panic("No memory");
+ }=09
+
+ /* Just bind to lp_socket_address() (usually 0.0.0.0) */
+ ifip =3D interpret_addr2(mem_ctx, lp_socket_address());
+ add_socket(service, model_ops, NULL, ifip);
+
+ talloc_destroy(mem_ctx);
+ }
+}
+
+/* This rw-buf api is made to avoid memcpy. For now do that like mad... T=
he
+ idea is to write into a circular list of buffers where the ideal case is
+ that a read(2) holds a complete request that is then thrown away
+ completely. */
+
+static BOOL append_to_buf(struct rw_buffer *buf, uint8_t *data, size_t len=
gth)
+{
+ buf->data =3D realloc(buf->data, buf->length+length);
+
+ if (buf->data =3D=3D NULL)
+ return False;
+
+ memcpy(buf->data+buf->length, data, length);
+
+ buf->length +=3D length;
+ return True;
+}
+
+static BOOL read_into_buf(int fd, struct rw_buffer *buf)
+{
+ char tmp_buf[1024];
+ int len;
+
+ len =3D read(fd, tmp_buf, sizeof(tmp_buf));
+ if (len =3D=3D 0)
+ return False;
+
+ return append_to_buf(buf, tmp_buf, len);
+}
+
+static void peek_into_read_buf(struct rw_buffer *buf, uint8_t **out,
+ size_t *out_length)
+{
+ *out =3D buf->data;
+ *out_length =3D buf->length;
+}
+
+static void consumed_from_read_buf(struct rw_buffer *buf,
+ size_t length)
+{
+ memcpy(buf->data, buf->data+length, buf->length-length);
+ buf->length -=3D length;
+}
+
+static BOOL ldap_append_to_buf(struct ldap_message *msg, struct rw_buffer =
*buf)
+{
+ DATA_BLOB blob;
+ BOOL res;
+
+ if (!ldap_encode(msg, &blob))
+ return False;
+
+ res =3D append_to_buf(buf, blob.data, blob.length);
+
+ data_blob_free(&blob);
+ return res;
+}
+
+static void reply_unwilling(struct ldapsrv_connection *conn, int error)
+{
+ struct ldap_message *msg;
+ struct ldap_ExtendedResponse *r;
+
+ msg =3D new_ldap_message();
+
+ if (msg =3D=3D NULL) {
+ conn->disconnect =3D True;
+ return;
+ }
+
+ msg->messageid =3D 0;
+ r =3D &msg->r.ExtendedResponse;=09
+
+ /* When completely freaking out, OpenLDAP responds with an ExtResp */
+ msg->type =3D LDAP_TAG_ExtendedResponse;
+ r->response.resultcode =3D error;
+ r->response.dn =3D NULL;
+ r->response.errormessage =3D NULL;
+ r->response.referral =3D NULL;
+ r->name =3D NULL;
+ r->value.data =3D NULL;
+ r->value.length =3D 0;
+
+ ldap_append_to_buf(msg, &conn->out_buffer);
+
+ talloc_destroy(msg->mem_ctx);
+}
+
+static void ldap_reply_BindRequest(struct ldapsrv_connection *conn,=20
+ struct ldap_message *request)
+{
+ struct ldap_BindRequest *req =3D &request->r.BindRequest;
+
+ struct ldap_message *msg;
+ struct ldap_BindResponse *resp;
+
+ DEBUG(5, ("Binding as %s with pw %s\n",
+ req->dn, req->creds.password));
+
+ msg =3D new_ldap_message();
+
+ if (msg =3D=3D NULL) {
+ conn->disconnect =3D True;
+ return;
+ }
+
+ resp =3D &msg->r.BindResponse;
+
+ msg->messageid =3D request->messageid;
+ msg->type =3D LDAP_TAG_BindResponse;
+ resp->response.resultcode =3D 0;
+ resp->response.dn =3D NULL;
+ resp->response.errormessage =3D NULL;
+ resp->response.referral =3D NULL;
+ resp->SASL.secblob.data =3D NULL;
+ resp->SASL.secblob.length =3D 0;
+
+ ldap_append_to_buf(msg, &conn->out_buffer);
+ talloc_destroy(msg->mem_ctx);
+}
+
+static void ldap_reply_SearchRequest(struct ldapsrv_connection *conn,
+ struct ldap_message *request)
+{
+ struct ldap_SearchRequest *req =3D &request->r.SearchRequest;
+
+ struct ldap_message *msg;
+ struct ldap_Result *resp;
+
+ DEBUG(10, ("Search filter: %s\n", req->filter));
+
+ msg =3D new_ldap_message();
+
+ if (msg =3D=3D NULL) {
+ conn->disconnect =3D True;
+ return;
+ }
+
+ msg->messageid =3D request->messageid;
+ resp =3D &msg->r.SearchResultDone;
+
+ /* Is this a rootdse request? */
+ if ((strlen(req->basedn) =3D=3D 0) &&
+ (req->scope =3D=3D LDAP_SEARCH_SCOPE_BASE) &&
+ strequal(req->filter, "(objectclass=3D*)")) {
+ msg->type =3D LDAP_TAG_SearchResultEntry;
+ msg->r.SearchResultEntry.dn =3D "samba4-ldap";
+ msg->r.SearchResultEntry.num_attributes =3D 0;
+ msg->r.SearchResultEntry.attributes =3D NULL;
+ ldap_append_to_buf(msg, &conn->out_buffer);
+ }
+
+ msg->type =3D LDAP_TAG_SearchResultDone;
+ resp->resultcode =3D 0;
+ resp->dn =3D NULL;
+ resp->errormessage =3D NULL;
+ resp->referral =3D NULL;
+
+ ldap_append_to_buf(msg, &conn->out_buffer);
+ talloc_destroy(msg->mem_ctx);
+}
+
+void switch_ldap_message(struct ldapsrv_connection *conn,
+ struct ldap_message *msg)
+{
+ switch(msg->type) {
+ case LDAP_TAG_BindRequest:
+ ldap_reply_BindRequest(conn, msg);
+ break;
+ case LDAP_TAG_SearchRequest:
+ ldap_reply_SearchRequest(conn, msg);
+ break;
+ default:
+ reply_unwilling(conn, 2);
+ break;
+ }
+}
+
+static void ldap_queue_run(struct server_connection *conn)
+{
+ struct ldapsrv_connection *ldap_conn =3D conn->private_data;
+=09
+ while (ldap_conn->in_queue) {
+ struct ldap_message_queue *req =3D ldap_conn->in_queue;
+ DLIST_REMOVE(ldap_conn->in_queue, req);
+
+ switch_ldap_message(ldap_conn, req->msg);
+ talloc_destroy(req->msg->mem_ctx);
+ }
+
+ if (ldap_conn->out_buffer.length > 0)
+ conn->event.fde->flags |=3D EVENT_FD_WRITE;
+}
+
+/*
+ called when a LDAP socket becomes readable
+*/
+static void ldapsrv_recv(struct server_connection *conn, time_t t,
+ uint16_t flags)
+{
+ struct ldapsrv_connection *ldap_conn =3D conn->private_data;
+ uint8_t *buf;
+ int buf_length, msg_length;
+ DATA_BLOB blob;
+ ASN1_DATA data;
+ struct ldap_message *msg;
+ struct ldap_message_queue *queue_entry;
+
+ DEBUG(10,("ldapsrv_recv\n"));
+
+ if (!read_into_buf(conn->event.fde->fd, &ldap_conn->in_buffer))
+ goto disconnect;
+
+ peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
+
+ while (buf_length > 0) {
+
+ /* LDAP Messages are always SEQUENCES */
+
+ if (!asn1_object_length(buf, buf_length, ASN1_SEQUENCE(0),
+ &msg_length))
+ goto disconnect;
+
+ if (buf_length < msg_length) {
+ /* Not enough yet */
+ return;
+ }
+
+ /* We've got a complete LDAP request in the in-buffer, convert
+ * that to a ldap_message and put it into the incoming
+ * queue. */
+
+ blob.data =3D buf;
+ blob.length =3D msg_length;
+
+ if (!asn1_load(&data, blob))
+ goto disconnect;
+
+ msg =3D new_ldap_message();
+
+ if ((msg =3D=3D NULL) || !ldap_decode(&data, msg))
+ goto disconnect;
+
+ queue_entry =3D talloc_p(msg->mem_ctx, struct ldap_message_queue);
+
+ if (queue_entry =3D=3D NULL)
+ goto disconnect;
+
+ queue_entry->msg =3D msg;
+
+ DLIST_ADD_END(ldap_conn->in_queue, queue_entry,
+ struct ldap_message_queue *);
+
+ consumed_from_read_buf(&ldap_conn->in_buffer, msg_length);
+
+ peek_into_read_buf(&ldap_conn->in_buffer, &buf, &buf_length);
+ }
+
+ ldap_queue_run(conn);
+
+ if (!ldap_conn->disconnect)
+ return;
+
+ disconnect:
+
+ server_terminate_connection(conn, "done");
+ return;
+}
+=09
+/*
+ called when a LDAP socket becomes writable
+*/
+static void ldapsrv_send(struct server_connection *conn, time_t t,
+ uint16_t flags)
+{
+ struct ldapsrv_connection *ldap_conn =3D conn->private_data;
+ size_t written;
+
+ DEBUG(10,("ldapsrv_send\n"));
+
+ written =3D write(conn->event.fde->fd, ldap_conn->out_buffer.data,
+ ldap_conn->out_buffer.length);
+
+ consumed_from_read_buf(&ldap_conn->out_buffer, written);
+
+ if (ldap_conn->out_buffer.length =3D=3D 0)
+ conn->event.fde->flags &=3D ~EVENT_FD_WRITE;
+=09
+ return;
+}
+
+/*
+ called when connection is idle
+*/
+static void ldapsrv_idle(struct server_connection *conn, time_t t)
+{
+ DEBUG(10,("ldapsrv_idle: not implemented!\n"));
+ return;
+}
+
+static void ldapsrv_close(struct server_connection *conn, const char *reas=
on)
+{
+ struct ldapsrv_connection *ldap_conn =3D conn->private_data;
+
+ talloc_destroy(ldap_conn->mem_ctx);
+
+ return;
+}
+
+/*
+ initialise a server_context from a open socket and register a event hand=
ler
+ for reading from that socket
+*/
+void ldapsrv_accept(struct server_connection *conn)
+{
+ TALLOC_CTX *mem_ctx;
+ struct ldapsrv_connection *ldap_conn;
+
+ DEBUG(5, ("ldapsrv_accept\n"));
+
+ mem_ctx =3D talloc_init("ldapsrv_connection");
+
+ ldap_conn =3D talloc_p(mem_ctx, struct ldapsrv_connection);
+
+ if (ldap_conn =3D=3D NULL)
+ return;
+
+ ZERO_STRUCTP(ldap_conn);
+
+ ldap_conn->mem_ctx =3D mem_ctx;
+
+ conn->private_data =3D ldap_conn;
+
+=09
+ return;
+}
+
+static const struct server_service_ops ldap_server_ops =3D {
+ .name =3D "ldap",
+ .service_init =3D ldapsrv_init,
+ .accept_connection =3D ldapsrv_accept,
+ .recv_handler =3D ldapsrv_recv,
+ .send_handler =3D ldapsrv_send,
+ .idle_handler =3D ldapsrv_idle,
+ .close_connection =3D ldapsrv_close,
+ .service_exit =3D ldapsrv_exit,=09
+};
+
+const struct server_service_ops *ldapsrv_get_ops(void)
+{
+ return &ldap_server_ops;
+}
+
+NTSTATUS server_service_ldap_init(void)
+{
+ return NT_STATUS_OK;=09
+}
diff -urN SAMBA_4_0/source/ldap_server/ldap_server.h source/ldap_server/lda=
p_server.h
--- SAMBA_4_0/source/ldap_server/ldap_server.h 1970-01-01 01:00:00.00000000=
0 +0100
+++ source/ldap_server/ldap_server.h 2004-08-14 01:56:11.000000000 +0200
@@ -0,0 +1,41 @@
+/*=20
+ Unix SMB/CIFS implementation.
+ process incoming packets - main loop
+ Copyright (C) Andrew Tridgell 1992-2003
+ Copyright (C) James J Myers 2003
+ =20
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ =20
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ =20
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+struct ldap_message_queue {
+ struct ldap_message_queue *prev, *next;
+ struct ldap_message *msg;
+};
+
+struct rw_buffer {
+ uint8_t *data;
+ size_t ofs, length;
+};
+
+struct ldapsrv_connection {
+ TALLOC_CTX *mem_ctx;
+
+ BOOL disconnect; /* Someone decided it's over */
+=09
+ struct rw_buffer in_buffer;
+ struct rw_buffer out_buffer;
+ struct ldap_message_queue *in_queue;
+ struct ldap_message_queue *out_queue;
+};
diff -urN SAMBA_4_0/source/smbd/config.m4 source/smbd/config.m4
--- SAMBA_4_0/source/smbd/config.m4 2004-07-13 23:04:56.000000000 +0200
+++ source/smbd/config.m4 2004-09-08 12:13:24.000000000 +0200
@@ -3,6 +3,7 @@
SMB_MODULE_MK(server_service_auth,SERVER_SERVICE,S TATIC,smbd/config.mk)
SMB_MODULE_MK(server_service_smb,SERVER_SERVICE,ST ATIC,smbd/config.mk)
SMB_MODULE_MK(server_service_rpc,SERVER_SERVICE,ST ATIC,smbd/config.mk)
+SMB_MODULE_MK(server_service_ldap,SERVER_SERVICE, STATIC,smbd/config.mk)
=20
SMB_SUBSYSTEM_MK(SERVER_SERVICE,smbd/config.mk)
SMB_SUBSYSTEM_MK(SERVER,smbd/config.mk)
diff -urN SAMBA_4_0/source/smbd/config.mk source/smbd/config.mk
--- SAMBA_4_0/source/smbd/config.mk 2004-07-13 23:04:56.000000000 +0200
+++ source/smbd/config.mk 2004-09-08 12:13:24.000000000 +0200
@@ -24,6 +24,14 @@
# End MODULE server_rpc
################################################
=20
+################################################
+# Start MODULE server_service_ldap
+[MODULE::server_service_ldap]
+REQUIRED_SUBSYSTEMS =3D \
+ LDAP
+# End MODULE server_ldap
+################################################
+
#######################
# Start SUBSYSTEM SERVICE
[SUBSYSTEM::SERVER_SERVICE]
diff -urN SAMBA_4_0/source/smbd/service.c source/smbd/service.c
--- SAMBA_4_0/source/smbd/service.c 2004-07-15 12:16:40.000000000 +0200
+++ source/smbd/service.c 2004-09-08 12:13:24.000000000 +0200
@@ -292,6 +292,9 @@
if (strcmp("rpc",name)=3D=3D0) {
return dcesrv_get_ops();
}
+ if (strcmp("ldap",name)=3D=3D0) {
+ return ldapsrv_get_ops();
+ }
return NULL;
}
=20

--TB36FDmn/VVEgNH/--

--oC1+HKm2/end4ao3
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2-rc1-SuSE (GNU/Linux)

iD8DBQFBRAnOduqO64/tJS8RAmFnAJ9hAH235gSj/dwtrxQ7liNOPzE74QCfU782
W4J/eJ42NUUXtLgAyJgy/XA=
=AhfM
-----END PGP SIGNATURE-----

--oC1+HKm2/end4ao3--