From 55d4d36993293fee914a009f1d8f05810e347f2b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Jan 2005 00:54:57 +0000 Subject: r5102: This is a major simplification of the logic for controlling top level servers in smbd. The old code still contained a fairly bit of legacy from the time when smbd was only handling SMB connection. The new code gets rid of all of the smb_server specific code in smbd/, and creates a much simpler infrastructures for new server code. Major changes include: - simplified the process model code a lot. - got rid of the top level server and service structures completely. The top level context is now the event_context. This got rid of service.h and server.h completely (they were the most confusing parts of the old code) - added service_stream.[ch] for the helper functions that are specific to stream type services (services that handle streams, and use a logically separate process per connection) - got rid of the builtin idle_handler code in the service logic, as none of the servers were using it, and it can easily be handled by a server in future by adding its own timed_event to the event context. - fixed some major memory leaks in the rpc server code. - added registration of servers, rather than hard coding our list of possible servers. This allows for servers as modules in the future. - temporarily disabled the winbind code until I add the helper functions for that type of server - added error checking on service startup. If a configured server fails to startup then smbd doesn't startup. - cleaned up the command line handling in smbd, removing unused options (This used to be commit cf6a46c3cbde7b1eb1b86bd3882b953a2de3a42e) --- source4/ldap_server/ldap_server.c | 205 ++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 121 deletions(-) (limited to 'source4/ldap_server/ldap_server.c') diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index d5b4aaae43..96305b1b2a 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -25,107 +25,14 @@ #include "dlinklist.h" #include "asn_1.h" #include "ldap_server/ldap_server.h" +#include "smbd/service_stream.h" /* close the socket and shutdown a server_context */ static void ldapsrv_terminate_connection(struct ldapsrv_connection *ldap_conn, const char *reason) { - server_terminate_connection(ldap_conn->connection, reason); -} - -static const struct server_stream_ops *ldapsrv_get_stream_ops(void); - -/* - add a socket address to the list of events, one event per port -*/ -static void add_socket(struct server_service *service, - struct ipv4_addr *ifip) -{ - struct server_stream_socket *stream_socket; - uint16_t port = 389; - char *ip_str = talloc_strdup(service, sys_inet_ntoa(*ifip)); - - stream_socket = service_setup_stream_socket(service, ldapsrv_get_stream_ops(), "ipv4", ip_str, &port); - - port = 3268; - stream_socket = service_setup_stream_socket(service, ldapsrv_get_stream_ops(), "ipv4", ip_str, &port); - - talloc_free(ip_str); -} - -/**************************************************************************** - Open the socket communication. -****************************************************************************/ -static void ldapsrv_init(struct server_service *service) -{ - struct ldapsrv_service *ldap_service; - struct ldapsrv_partition *rootDSE_part; - struct ldapsrv_partition *part; - - DEBUG(10,("ldapsrv_init\n")); - - ldap_service = talloc(service, struct ldapsrv_service); - if (!ldap_service) { - DEBUG(0,("talloc(service, struct ldapsrv_service) failed\n")); - return; - } - ZERO_STRUCTP(ldap_service); - - rootDSE_part = talloc(ldap_service, struct ldapsrv_partition); - if (!rootDSE_part) { - DEBUG(0,("talloc(ldap_service, struct ldapsrv_partition) failed\n")); - return; - } - rootDSE_part->base_dn = ""; /* RootDSE */ - rootDSE_part->ops = ldapsrv_get_rootdse_partition_ops(); - - ldap_service->rootDSE = rootDSE_part; - DLIST_ADD_END(ldap_service->partitions, rootDSE_part, struct ldapsrv_partition *); - - part = talloc(ldap_service, struct ldapsrv_partition); - if (!ldap_service) { - DEBUG(0,("talloc(ldap_service, struct ldapsrv_partition) failed\n")); - return; - } - part->base_dn = "*"; /* default partition */ - if (lp_parm_bool(-1, "ldapsrv", "hacked", False)) { - part->ops = ldapsrv_get_hldb_partition_ops(); - } else { - part->ops = ldapsrv_get_sldb_partition_ops(); - } - - ldap_service->default_partition = part; - DLIST_ADD_END(ldap_service->partitions, part, struct ldapsrv_partition *); - - service->service.private_data = ldap_service; - - if (lp_interfaces() && lp_bind_interfaces_only()) { - int num_interfaces = iface_count(); - int i; - - /* We have been given an interfaces line, and been - told to only bind to those interfaces. Create a - socket per interface and bind to only these. - */ - for(i = 0; i < num_interfaces; i++) { - struct ipv4_addr *ifip = iface_n_ip(i); - - if (ifip == NULL) { - DEBUG(0,("ldapsrv_init: interface %d has NULL " - "IP address !\n", i)); - continue; - } - - add_socket(service, ifip); - } - } else { - struct ipv4_addr ifip; - - /* Just bind to lp_socket_address() (usually 0.0.0.0) */ - ifip = interpret_addr2(lp_socket_address()); - add_socket(service, &ifip); - } + stream_terminate_connection(ldap_conn->connection, reason); } /* This rw-buf api is made to avoid memcpy. For now do that like mad... The @@ -421,10 +328,10 @@ NTSTATUS ldapsrv_flush_responses(struct ldapsrv_connection *conn) /* called when a LDAP socket becomes readable */ -static void ldapsrv_recv(struct server_connection *conn, struct timeval t, +static void ldapsrv_recv(struct stream_connection *conn, struct timeval t, uint16_t flags) { - struct ldapsrv_connection *ldap_conn = conn->connection.private_data; + struct ldapsrv_connection *ldap_conn = talloc_get_type(conn->private, struct ldapsrv_connection); uint8_t *buf; size_t buf_length, msg_length; DATA_BLOB blob; @@ -517,10 +424,10 @@ static void ldapsrv_recv(struct server_connection *conn, struct timeval t, /* called when a LDAP socket becomes writable */ -static void ldapsrv_send(struct server_connection *conn, struct timeval t, +static void ldapsrv_send(struct stream_connection *conn, struct timeval t, uint16_t flags) { - struct ldapsrv_connection *ldap_conn = conn->connection.private_data; + struct ldapsrv_connection *ldap_conn = talloc_get_type(conn->private, struct ldapsrv_connection); DEBUG(10,("ldapsrv_send\n")); @@ -540,52 +447,108 @@ static void ldapsrv_send(struct server_connection *conn, struct timeval t, initialise a server_context from a open socket and register a event handler for reading from that socket */ -static void ldapsrv_accept(struct server_connection *conn) +static void ldapsrv_accept(struct stream_connection *conn) { struct ldapsrv_connection *ldap_conn; DEBUG(10, ("ldapsrv_accept\n")); - ldap_conn = talloc(conn, struct ldapsrv_connection); + ldap_conn = talloc_zero(conn, struct ldapsrv_connection); if (ldap_conn == NULL) return; - ZERO_STRUCTP(ldap_conn); ldap_conn->connection = conn; - ldap_conn->service = talloc_reference(ldap_conn, conn->stream_socket->service->service.private_data); - - conn->connection.private_data = ldap_conn; - - return; + ldap_conn->service = talloc_get_type(conn->private, struct ldapsrv_service); + conn->private = ldap_conn; } -static const struct server_stream_ops ldap_stream_ops = { +static const struct stream_server_ops ldap_stream_ops = { .name = "ldap", - .socket_init = NULL, .accept_connection = ldapsrv_accept, .recv_handler = ldapsrv_recv, .send_handler = ldapsrv_send, - .idle_handler = NULL, - .close_connection = NULL }; -static const struct server_stream_ops *ldapsrv_get_stream_ops(void) +/* + add a socket address to the list of events, one event per port +*/ +static NTSTATUS add_socket(struct event_context *event_context, const struct model_ops *model_ops, + const char *address, struct ldapsrv_service *ldap_service) { - return &ldap_stream_ops; + uint16_t port = 389; + NTSTATUS status; + + status = stream_setup_socket(event_context, model_ops, &ldap_stream_ops, + "ipv4", address, &port, ldap_service); + NT_STATUS_NOT_OK_RETURN(status); + + port = 3268; + + return stream_setup_socket(event_context, model_ops, &ldap_stream_ops, + "ipv4", address, &port, ldap_service); } -static const struct server_service_ops ldap_server_ops = { - .name = "ldap", - .service_init = ldapsrv_init -}; +/* + open the ldap server sockets +*/ +static NTSTATUS ldapsrv_init(struct event_context *event_context, const struct model_ops *model_ops) +{ + struct ldapsrv_service *ldap_service; + struct ldapsrv_partition *rootDSE_part; + struct ldapsrv_partition *part; + NTSTATUS status; -const struct server_service_ops *ldapsrv_get_ops(void) -{ - return &ldap_server_ops; + DEBUG(10,("ldapsrv_init\n")); + + ldap_service = talloc_zero(event_context, struct ldapsrv_service); + NT_STATUS_HAVE_NO_MEMORY(ldap_service); + + rootDSE_part = talloc(ldap_service, struct ldapsrv_partition); + NT_STATUS_HAVE_NO_MEMORY(rootDSE_part); + + rootDSE_part->base_dn = ""; /* RootDSE */ + rootDSE_part->ops = ldapsrv_get_rootdse_partition_ops(); + + ldap_service->rootDSE = rootDSE_part; + DLIST_ADD_END(ldap_service->partitions, rootDSE_part, struct ldapsrv_partition *); + + part = talloc(ldap_service, struct ldapsrv_partition); + NT_STATUS_HAVE_NO_MEMORY(part); + + part->base_dn = "*"; /* default partition */ + if (lp_parm_bool(-1, "ldapsrv", "hacked", False)) { + part->ops = ldapsrv_get_hldb_partition_ops(); + } else { + part->ops = ldapsrv_get_sldb_partition_ops(); + } + + ldap_service->default_partition = part; + DLIST_ADD_END(ldap_service->partitions, part, struct ldapsrv_partition *); + + if (lp_interfaces() && lp_bind_interfaces_only()) { + int num_interfaces = iface_count(); + int i; + + /* We have been given an interfaces line, and been + told to only bind to those interfaces. Create a + socket per interface and bind to only these. + */ + for(i = 0; i < num_interfaces; i++) { + const char *address = sys_inet_ntoa(*iface_n_ip(i)); + status = add_socket(event_context, model_ops, address, ldap_service); + NT_STATUS_NOT_OK_RETURN(status); + } + } else { + status = add_socket(event_context, model_ops, lp_socket_address(), ldap_service); + NT_STATUS_NOT_OK_RETURN(status); + } + + return NT_STATUS_OK; } + NTSTATUS server_service_ldap_init(void) { - return NT_STATUS_OK; + return register_server_service("ldap", ldapsrv_init); } -- cgit