r5102: This is a major simplification of the logic for controlling top level
authorAndrew Tridgell <tridge@samba.org>
Sun, 30 Jan 2005 00:54:57 +0000 (00:54 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:09:22 +0000 (13:09 -0500)
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)

36 files changed:
source4/build/smb_build/main.pm
source4/include/includes.h
source4/include/structs.h
source4/ldap_server/ldap_server.c
source4/ldap_server/ldap_server.h
source4/lib/messaging/messaging.c
source4/ntvfs/cifs/vfs_cifs.c
source4/ntvfs/common/brlock.c
source4/ntvfs/common/opendb.c
source4/ntvfs/ipc/vfs_ipc.c
source4/ntvfs/posix/pvfs_wait.c
source4/ntvfs/posix/vfs_posix.c
source4/passdb/secrets.c
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcerpc_server.h
source4/rpc_server/dcerpc_sock.c
source4/rpc_server/epmapper/rpc_epmapper.c
source4/smb_server/conn.c
source4/smb_server/negprot.c
source4/smb_server/request.c
source4/smb_server/service.c
source4/smb_server/sesssetup.c
source4/smb_server/smb_server.c
source4/smb_server/smb_server.h
source4/smbd/config.mk
source4/smbd/process_model.c
source4/smbd/process_model.h
source4/smbd/process_single.c
source4/smbd/process_standard.c
source4/smbd/process_thread.c
source4/smbd/rewrite.c [deleted file]
source4/smbd/server.c
source4/smbd/server.h [deleted file]
source4/smbd/service.c
source4/smbd/service.h [deleted file]
source4/torture/local/messaging.c

index 55009d14e538e868350ee4b9f2fa263b0388ddc7..3911820edb5c48a7cd43caf45976e78823d7402c 100644 (file)
@@ -54,8 +54,7 @@ sub smb_build_main($)
                "client/config.mk",
                "libcli/libsmb.mk",
                "libcli/config.mk",
-               "libcli/security/config.mk",
-               "winbind/config.mk",
+               "libcli/security/config.mk"
        );
 
        $| = 1;
index 70e06e2a584accb3b4ecb369d11a401ae02e24a6..ce24525158ef38eb6a5cdbe3fcec1180b4aff73c 100644 (file)
@@ -139,8 +139,6 @@ extern int errno;
 #include "lib/dcom/common/dcom.h"
 #include "librpc/gen_ndr/ndr_dcom.h"
 #include "smb_interfaces.h"
-#include "smbd/server.h"
-#include "smbd/service.h"
 #include "ntvfs/ntvfs.h"
 #include "cli_context.h"
 #include "nsswitch/winbind_client.h"
index 29a6589a8652833a198c9a6335783867b0aecbec..cf59296f320ec939b5a6a736788e48003a86c65f 100644 (file)
@@ -151,3 +151,8 @@ struct nbt_name_socket;
 struct nbt_name_query;
 struct nbt_name_status;
 
+
+struct messaging_context;
+struct stream_connection;
+struct model_ops;
+struct stream_server_ops;
index d5b4aaae4366f15c76ca5e412f4f4a8d2f6c47b3..96305b1b2a6967645cb2da35c9e784c6cf3f8c86 100644 (file)
 #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);
 }
index 6d4824bc9d86ffd75b66f28a5dcb8134f027a2a0..39052a76719001129bd64761de36ba6d420d3b6a 100644 (file)
@@ -57,7 +57,7 @@ struct ldapsrv_call {
 struct ldapsrv_service;
 
 struct ldapsrv_connection {
-       struct server_connection *connection;
+       struct stream_connection *connection;
 
        struct gensec_security *gensec;
        struct auth_session_info *session_info;
index e2e8161111d9e1bf93113138484dd8e3fd6ba37a..09d30027b0a75bb3402f566e719ad60a04866db3 100644 (file)
@@ -33,7 +33,7 @@
 #define MESSAGING_BACKOFF 250000
 
 struct messaging_context {
-       servid_t server_id;
+       uint32_t server_id;
        struct socket_context *sock;
        char *path;
        struct dispatch_fn *dispatch;
@@ -51,7 +51,7 @@ struct dispatch_fn {
        uint32_t msg_type;
        void *private;
        void (*fn)(struct messaging_context *msg, void *private, 
-                  uint32_t msg_type, servid_t server_id, DATA_BLOB *data);
+                  uint32_t msg_type, uint32_t server_id, DATA_BLOB *data);
 };
 
 /* an individual message */
@@ -64,8 +64,8 @@ struct messaging_rec {
        struct {
                uint32_t version;
                uint32_t msg_type;
-               servid_t from;
-               servid_t to;
+               uint32_t from;
+               uint32_t to;
                uint32_t length;
        } header;
 
@@ -78,7 +78,7 @@ struct messaging_rec {
  A useful function for testing the message system.
 */
 static void ping_message(struct messaging_context *msg, void *private, 
-                        uint32_t msg_type, servid_t src, DATA_BLOB *data)
+                        uint32_t msg_type, uint32_t src, DATA_BLOB *data)
 {
        DEBUG(1,("INFO: Received PING message from server %u [%.*s]\n",
                 (uint_t)src, data->length, data->data?(const char *)data->data:""));
@@ -88,7 +88,7 @@ static void ping_message(struct messaging_context *msg, void *private,
 /* 
    return the path to a messaging socket
 */
-static char *messaging_path(TALLOC_CTX *mem_ctx, servid_t server_id)
+static char *messaging_path(TALLOC_CTX *mem_ctx, uint32_t server_id)
 {
        char *name = talloc_asprintf(mem_ctx, "messaging/msg.%u", (unsigned)server_id);
        char *ret;
@@ -228,7 +228,7 @@ static void messaging_listen_handler(struct event_context *ev, struct fd_event *
 */
 void messaging_register(struct messaging_context *msg, void *private,
                        uint32_t msg_type, 
-                       void (*fn)(struct messaging_context *, void *, uint32_t, servid_t, DATA_BLOB *))
+                       void (*fn)(struct messaging_context *, void *, uint32_t, uint32_t, DATA_BLOB *))
 {
        struct dispatch_fn *d;
 
@@ -365,7 +365,7 @@ static void messaging_backoff_handler(struct event_context *ev, struct timed_eve
 /*
   Send a message to a particular server
 */
-NTSTATUS messaging_send(struct messaging_context *msg, servid_t server, uint32_t msg_type, DATA_BLOB *data)
+NTSTATUS messaging_send(struct messaging_context *msg, uint32_t server, uint32_t msg_type, DATA_BLOB *data)
 {
        struct messaging_rec *rec;
        NTSTATUS status;
@@ -429,7 +429,7 @@ NTSTATUS messaging_send(struct messaging_context *msg, servid_t server, uint32_t
 /*
   Send a message to a particular server, with the message containing a single pointer
 */
-NTSTATUS messaging_send_ptr(struct messaging_context *msg, servid_t server, 
+NTSTATUS messaging_send_ptr(struct messaging_context *msg, uint32_t server, 
                            uint32_t msg_type, void *ptr)
 {
        DATA_BLOB blob;
@@ -454,7 +454,7 @@ static int messaging_destructor(void *ptr)
 /*
   create the listening socket and setup the dispatcher
 */
-struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, servid_t server_id, struct event_context *ev)
+struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, uint32_t server_id, struct event_context *ev)
 {
        struct messaging_context *msg;
        NTSTATUS status;
@@ -496,7 +496,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, servid_t server_id
        fde.flags       = EVENT_FD_READ;
        fde.handler     = messaging_listen_handler;
 
-       msg->event.ev   = talloc_reference(msg,ev);
+       msg->event.ev   = talloc_reference(msg, ev);
        msg->event.fde  = event_add_fd(ev, &fde, msg);
 
        talloc_set_destructor(msg, messaging_destructor);
index 7ac687dd460f625f93c3532eb016acf107195d12..13b11d8ba2e2641a60217ac7f18056617fa5a7dd 100644 (file)
@@ -30,6 +30,7 @@
 #include "libcli/raw/libcliraw.h"
 #include "libcli/composite/composite.h"
 #include "smb_server/smb_server.h"
+#include "smbd/service_stream.h"
 
 /* this is stored in ntvfs_private */
 struct cvfs_private {
@@ -48,22 +49,6 @@ struct async_info {
 
 #define SETUP_PID private->tree->session->pid = SVAL(req->in.hdr, HDR_PID)
 
-/*
-  an idle function to cope with messages from the smbd client while 
-  waiting for a reply from the server
-  this function won't be needed once all of the cifs backend
-  and the core of smbd is converted to use async calls
-*/
-static void idle_func(struct smbcli_transport *transport, void *p_private)
-{
-       struct cvfs_private *private = p_private;
-       int fd = socket_get_fd(private->tcon->smb_conn->connection->socket);
-
-       if (socket_pending(fd)) {
-               smbd_process_async(private->tcon->smb_conn);
-       }
-}
-
 /*
   a handler for oplock break events from the server - these need to be passed
   along to the client
@@ -158,7 +143,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs,
        
        /* we need to receive oplock break requests from the server */
        smbcli_oplock_handler(private->transport, oplock_handler, private);
-       smbcli_transport_idle_handler(private->transport, idle_func, 50000, private);
 
        private->transport->socket->event.fde->handler = cifs_socket_handler;
        private->transport->socket->event.fde->private = private;
index f51e3d0694a026878e773d8bdc085299d0759263..d521dc80d33a187e371212593007cc7a43890df8 100644 (file)
@@ -41,7 +41,7 @@
   lock is the same as another lock
 */
 struct lock_context {
-       servid_t server;
+       uint32_t server;
        uint16_t smbpid;
        uint16_t tid;
 };
@@ -60,7 +60,7 @@ struct lock_struct {
 
 struct brl_context {
        struct tdb_wrap *w;
-       servid_t server;
+       uint32_t server;
        uint16_t tid;
        struct messaging_context *messaging_ctx;
        struct lock_struct last_lock;
@@ -72,7 +72,7 @@ struct brl_context {
   talloc_free(). We need the messaging_ctx to allow for
   pending lock notifications.
 */
-struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, 
+struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, uint16_t tid, 
                             struct messaging_context *messaging_ctx)
 {
        char *path;
index 0aa257073d36304549e3996cdb677aff8f4bf52d..3c206528dd3f0b0f79e77827539529e1356898ab 100644 (file)
@@ -44,7 +44,7 @@
 
 struct odb_context {
        struct tdb_wrap *w;
-       servid_t server;
+       uint32_t server;
        struct messaging_context *messaging_ctx;
 };
 
@@ -53,7 +53,7 @@ struct odb_context {
    following form
 */
 struct odb_entry {
-       servid_t server;
+       uint32_t server;
        void     *file_handle;
        uint32_t stream_id;
        uint32_t share_access;
@@ -78,7 +78,7 @@ struct odb_lock {
   talloc_free(). We need the messaging_ctx to allow for pending open
   notifications.
 */
-struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, 
+struct odb_context *odb_init(TALLOC_CTX *mem_ctx, uint32_t server, 
                             struct messaging_context *messaging_ctx)
 {
        char *path;
index 402d1ead64cff7a7783d260cb997b82ba6a12fe2..04a1a06db35c3b0e16b1a4b3311f779afc35423f 100644 (file)
@@ -180,7 +180,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
        struct dcerpc_binding ep_description;
        struct ipc_private *private = ntvfs->private_data;
        int fnum;
-       struct server_connection *srv_conn;
+       struct stream_connection *srv_conn = req->smb_conn->connection;
 
        if (!req->session || !req->session->session_info) {
                return NT_STATUS_ACCESS_DENIED;
@@ -211,11 +211,6 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
        ep_description.transport = NCACN_NP;
        ep_description.endpoint = p->pipe_name;
 
-       /* TOTO: pass in full server_connection in here */
-       srv_conn = talloc_zero(p, struct server_connection);
-       NT_STATUS_HAVE_NO_MEMORY(srv_conn);
-       srv_conn->event.ctx     = talloc_reference(srv_conn, req->smb_conn->connection->event.ctx);
-
        /* The session info is refcount-increased in the 
         * dcesrv_endpoint_search_connect() function
         */
index c8d696f0fc5867f3ade80eeb06b1cc0a743609f9..276b1d4e9a5280844a7c20c46a181ca1e3718588 100644 (file)
@@ -24,6 +24,7 @@
 #include "events.h"
 #include "dlinklist.h"
 #include "vfs_posix.h"
+#include "smbd/service_stream.h"
 
 /* the context for a single wait instance */
 struct pvfs_wait {
@@ -56,7 +57,7 @@ NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs,
   receive a completion message for a wait
 */
 static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uint32_t msg_type, 
-                              servid_t src, DATA_BLOB *data)
+                              uint32_t src, DATA_BLOB *data)
 {
        struct pvfs_wait *pwait = private;
        struct smbsrv_request *req;
@@ -133,7 +134,7 @@ static int pvfs_wait_destructor(void *ptr)
 
        pwait->private = private;
        pwait->handler = fn;
-       pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging.ctx;
+       pwait->msg_ctx = pvfs->tcon->smb_conn->connection->msg_ctx;
        pwait->ev = req->tcon->smb_conn->connection->event.ctx;
        pwait->msg_type = msg_type;
        pwait->req = talloc_reference(pwait, req);
index 314f9736a367c37a0f8fe2e3f393ee5306a6b7c5..0ed878c1f0238a904968e74ec5d3d3dc541ad9ee 100644 (file)
@@ -27,6 +27,7 @@
 #include "includes.h"
 #include "vfs_posix.h"
 #include "librpc/gen_ndr/ndr_security.h"
+#include "smbd/service_stream.h"
 
 
 /*
@@ -130,16 +131,16 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs,
        ntvfs->private_data = pvfs;
 
        pvfs->brl_context = brl_init(pvfs, 
-                                    pvfs->tcon->smb_conn->connection->connection.id,  
+                                    pvfs->tcon->smb_conn->connection->server_id,  
                                     pvfs->tcon->service,
-                                    pvfs->tcon->smb_conn->connection->messaging.ctx);
+                                    pvfs->tcon->smb_conn->connection->msg_ctx);
        if (pvfs->brl_context == NULL) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
        pvfs->odb_context = odb_init(pvfs, 
-                                    pvfs->tcon->smb_conn->connection->connection.id,  
-                                    pvfs->tcon->smb_conn->connection->messaging.ctx);
+                                    pvfs->tcon->smb_conn->connection->server_id,  
+                                    pvfs->tcon->smb_conn->connection->msg_ctx);
        if (pvfs->odb_context == NULL) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
index 7045cf6af7da8f802257c17e6eaedb3541818e5c..14e5642ae2d9953462da4cd8709a148a0120f8a8 100644 (file)
@@ -64,7 +64,7 @@ BOOL secrets_init(void)
        pstrcpy(fname, lp_private_dir());
        pstrcat(fname,"/secrets.tdb");
 
-       tdb = tdb_wrap_open(NULL, fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+       tdb = tdb_wrap_open(talloc_autofree_context(), fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
 
        if (!tdb) {
                DEBUG(0,("Failed to open %s\n", fname));
index 575c073e468573e02557c878c61a0c5996a6b0aa..c21ab3d88378889498c7cfc4f1870b394177954d 100644 (file)
@@ -28,6 +28,7 @@
 #include "dlinklist.h"
 #include "rpc_server/dcerpc_server.h"
 #include "events.h"
+#include "smbd/service_stream.h"
 
 /*
   see if two endpoints match
@@ -299,7 +300,7 @@ static int dcesrv_endpoint_destructor(void *ptr)
 NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
                                 TALLOC_CTX *mem_ctx,
                                 const struct dcesrv_endpoint *ep,
-                                struct server_connection *srv_conn,
+                                struct stream_connection *srv_conn,
                                 struct dcesrv_connection **_p)
 {
        struct dcesrv_connection *p;
@@ -333,7 +334,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx,
                                        TALLOC_CTX *mem_ctx,
                                        const struct dcerpc_binding *ep_description,
                                        struct auth_session_info *session_info,
-                                       struct server_connection *srv_conn,
+                                       struct stream_connection *srv_conn,
                                        struct dcesrv_connection **dce_conn_p)
 {
        NTSTATUS status;
@@ -1204,7 +1205,7 @@ static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_s
 }
 
 /*
-  initialise the dcerpc server context
+  initialise the dcerpc server context for ncacn_np based services
 */
 NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx)
 {
@@ -1218,45 +1219,6 @@ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_d
        return NT_STATUS_OK;
 }
 
-static void dcesrv_init(struct server_service *service)
-{
-       NTSTATUS status;
-       struct dcesrv_context *dce_ctx;
-
-       DEBUG(1,("dcesrv_init\n"));
-
-       status = dcesrv_init_context(service,
-                                    lp_dcerpc_endpoint_servers(),
-                                    DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
-                                    &dce_ctx);
-       if (!NT_STATUS_IS_OK(status)) {
-               return;
-       }
-
-       service->service.private_data = dce_ctx;
-
-       dcesrv_sock_init(service);
-
-       return; 
-}
-
-static void dcesrv_accept(struct server_connection *srv_conn)
-{
-       dcesrv_sock_accept(srv_conn);
-}
-
-static void dcesrv_recv(struct server_connection *srv_conn, 
-                       struct timeval t, uint16_t flags)
-{
-       dcesrv_sock_recv(srv_conn, t, flags);
-}
-
-static void dcesrv_send(struct server_connection *srv_conn, 
-                       struct timeval t, uint16_t flags)
-{
-       dcesrv_sock_send(srv_conn, t, flags);
-}
-
 /* the list of currently registered DCERPC endpoint servers.
  */
 static struct ep_server {
@@ -1338,32 +1300,25 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void)
        return &critical_sizes;
 }
 
-static const struct server_stream_ops dcesrv_stream_ops = {
-       .name                   = "rpc",
-       .socket_init            = NULL,
-       .accept_connection      = dcesrv_accept,
-       .recv_handler           = dcesrv_recv,
-       .send_handler           = dcesrv_send,
-       .idle_handler           = NULL,
-       .close_connection       = NULL
-};
-
-const struct server_stream_ops *dcesrv_get_stream_ops(void)
+/*
+  initialise the dcerpc server context for socket based services
+*/
+static NTSTATUS dcesrv_init(struct event_context *event_context, const struct model_ops *model_ops)
 {
-       return &dcesrv_stream_ops;
-}
+       NTSTATUS status;
+       struct dcesrv_context *dce_ctx;
 
-static const struct server_service_ops dcesrv_ops = {
-       .name                   = "rpc",
-       .service_init           = dcesrv_init,
-};
+       status = dcesrv_init_context(event_context,
+                                    lp_dcerpc_endpoint_servers(),
+                                    DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
+                                    &dce_ctx);
+       NT_STATUS_NOT_OK_RETURN(status);
 
-const struct server_service_ops *dcesrv_get_ops(void)
-{
-       return &dcesrv_ops;
+       return dcesrv_sock_init(dce_ctx, event_context, model_ops);
 }
 
+
 NTSTATUS server_service_rpc_init(void)
 {
-       return NT_STATUS_OK;    
+       return register_server_service("rpc", dcesrv_init);
 }
index 2738cee0403314efef4021127a26793716c613af..317ebdd2ec1fdfb61ffaa94448047662d54791f8 100644 (file)
@@ -174,7 +174,7 @@ struct dcesrv_connection {
        /* the current authentication state */
        struct dcesrv_auth auth_state;
 
-       struct server_connection *srv_conn;
+       struct stream_connection *srv_conn;
 
        /* the transport level session key */
        DATA_BLOB transport_session_key;
index 222f513bb9722e7f3e6ce56cb776fbf4a38004a9..ef5e7c269aa4f07ea5ba0f7e996186465a028271 100644 (file)
@@ -25,6 +25,7 @@
 #include "includes.h"
 #include "events.h"
 #include "rpc_server/dcerpc_server.h"
+#include "smbd/service_stream.h"
 
 struct dcesrv_socket_context {
        const struct dcesrv_endpoint *endpoint;
@@ -50,42 +51,129 @@ static ssize_t dcerpc_write_fn(void *private, DATA_BLOB *out)
 
 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
 {
-       server_terminate_connection(dce_conn->srv_conn, reason);
+       stream_terminate_connection(dce_conn->srv_conn, reason);
 }
 
-static void add_socket_rpc_unix(struct server_service *service, struct dcesrv_endpoint *e)
+
+void dcesrv_sock_accept(struct stream_connection *srv_conn)
 {
-       struct dcesrv_context *dce_ctx = service->service.private_data;
-       struct server_stream_socket *stream_socket;
-       struct dcesrv_socket_context *dcesrv_sock;
-       uint16_t port = 1;
+       NTSTATUS status;
+       struct dcesrv_socket_context *dcesrv_sock = 
+               talloc_get_type(srv_conn->private, struct dcesrv_socket_context);
+       struct dcesrv_connection *dcesrv_conn = NULL;
+
+       status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
+                                        srv_conn,
+                                        dcesrv_sock->endpoint,
+                                        srv_conn,
+                                        &dcesrv_conn);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
+                       nt_errstr(status)));
+               return;
+       }
+
+       srv_conn->private = dcesrv_conn;
+
+       return; 
+}
+
+void dcesrv_sock_recv(struct stream_connection *conn, struct timeval t, uint16_t flags)
+{
+       NTSTATUS status;
+       struct dcesrv_connection *dce_conn = talloc_get_type(conn->private, struct dcesrv_connection);
+       DATA_BLOB tmp_blob;
+       size_t nread;
+
+       tmp_blob = data_blob_talloc(conn->socket, NULL, 0x1000);
+       if (tmp_blob.data == NULL) {
+               dcesrv_terminate_connection(dce_conn, "out of memory");
+               return;
+       }
+
+       status = socket_recv(conn->socket, tmp_blob.data, tmp_blob.length, &nread, 0);
+       if (NT_STATUS_IS_ERR(status)) {
+               dcesrv_terminate_connection(dce_conn, nt_errstr(status));
+               return;
+       }
+       if (nread == 0) {
+               talloc_free(tmp_blob.data);
+               return;
+       }
+
+       tmp_blob.length = nread;
+
+       status = dcesrv_input(dce_conn, &tmp_blob);
+       talloc_free(tmp_blob.data);
 
-       stream_socket = service_setup_stream_socket(service, dcesrv_get_stream_ops(), "unix", e->ep_description.endpoint, &port);
-       if (!stream_socket) {
-               DEBUG(0,("service_setup_stream_socket(path=%s) failed\n",e->ep_description.endpoint));
+       if (!NT_STATUS_IS_OK(status)) {
+               dcesrv_terminate_connection(dce_conn, nt_errstr(status));
                return;
        }
 
-       dcesrv_sock = talloc(stream_socket, struct dcesrv_socket_context);
-       if (!dcesrv_sock) {
-               DEBUG(0,("talloc(stream_socket, struct dcesrv_socket_context) failed\n"));
+       if (dce_conn->call_list && dce_conn->call_list->replies) {
+               conn->event.fde->flags |= EVENT_FD_WRITE;
+       }
+}
+
+void dcesrv_sock_send(struct stream_connection *conn, struct timeval t, uint16_t flags)
+{
+       struct dcesrv_connection *dce_conn = talloc_get_type(conn->private, struct dcesrv_connection);
+       NTSTATUS status;
+
+       status = dcesrv_output(dce_conn, conn->socket, dcerpc_write_fn);
+       if (!NT_STATUS_IS_OK(status)) {
+               dcesrv_terminate_connection(dce_conn, "eof on socket");
                return;
        }
 
+       if (!dce_conn->call_list || !dce_conn->call_list->replies) {
+               conn->event.fde->flags &= ~EVENT_FD_WRITE;
+       }
+}
+
+
+static const struct stream_server_ops dcesrv_stream_ops = {
+       .name                   = "rpc",
+       .accept_connection      = dcesrv_sock_accept,
+       .recv_handler           = dcesrv_sock_recv,
+       .send_handler           = dcesrv_sock_send,
+};
+
+
+
+static NTSTATUS add_socket_rpc_unix(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
+                                   struct event_context *event_ctx, const struct model_ops *model_ops)
+{
+       struct dcesrv_socket_context *dcesrv_sock;
+       uint16_t port = 1;
+       NTSTATUS status;
+
+       dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context);
+       NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
+
        /* remember the endpoint of this socket */
        dcesrv_sock->endpoint           = e;
-       dcesrv_sock->dcesrv_ctx         = dce_ctx;
+       dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
+
+       status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, 
+                                    "unix", e->ep_description.endpoint, &port, 
+                                    dcesrv_sock);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
+                        e->ep_description.endpoint, nt_errstr(status)));
+       }
 
-       stream_socket->stream.private_data = dcesrv_sock;
+       return status;
 }
 
-static void add_socket_rpc_ncalrpc(struct server_service *service, struct dcesrv_endpoint *e)
+static NTSTATUS add_socket_rpc_ncalrpc(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
+                                      struct event_context *event_ctx, const struct model_ops *model_ops)
 {
-       struct dcesrv_context *dce_ctx = service->service.private_data;
-       struct server_stream_socket *stream_socket;
        struct dcesrv_socket_context *dcesrv_sock;
        uint16_t port = 1;
        char *full_path;
+       NTSTATUS status;
 
        if (!e->ep_description.endpoint) {
                /* No identifier specified: use DEFAULT. 
@@ -96,101 +184,88 @@ static void add_socket_rpc_ncalrpc(struct server_service *service, struct dcesrv
 
        full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(), e->ep_description.endpoint);
 
-       stream_socket = service_setup_stream_socket(service, dcesrv_get_stream_ops(), "unix", full_path, &port);
-       if (!stream_socket) {
-               DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed\n",e->ep_description.endpoint, full_path));
-               return;
-       }
-
-       dcesrv_sock = talloc(stream_socket, struct dcesrv_socket_context);
-       if (!dcesrv_sock) {
-               DEBUG(0,("talloc(stream_socket, struct dcesrv_socket_context) failed\n"));
-               return;
-       }
+       dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context);
+       NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
 
        /* remember the endpoint of this socket */
        dcesrv_sock->endpoint           = e;
        dcesrv_sock->dcesrv_ctx         = dce_ctx;
 
-       stream_socket->stream.private_data = dcesrv_sock;
-
-       return;
+       status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, 
+                                    "unix", full_path, &port, dcesrv_sock);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
+                        e->ep_description.endpoint, full_path, nt_errstr(status)));
+       }
+       return status;
 }
 
 /*
   add a socket address to the list of events, one event per dcerpc endpoint
 */
-static void add_socket_rpc_tcp_iface(struct server_service *service, 
-                                    struct dcesrv_endpoint *e,
-                                    struct ipv4_addr *ifip)
+static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
+                                        struct event_context *event_ctx, const struct model_ops *model_ops,
+                                        const char *address)
 {
-       struct dcesrv_context *dce_ctx = service->service.private_data;
-       struct server_stream_socket *stream_socket;
        struct dcesrv_socket_context *dcesrv_sock;
        uint16_t port = 0;
-       char *ip_str = talloc_strdup(service, sys_inet_ntoa(*ifip));
+       NTSTATUS status;
                        
-       if (e->ep_description.endpoint) 
+       if (e->ep_description.endpoint) {
                port = atoi(e->ep_description.endpoint);
-
-       stream_socket = service_setup_stream_socket(service, dcesrv_get_stream_ops(), "ipv4", ip_str, &port);
-       if (!stream_socket) {
-               DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed\n", ip_str, port));
-               return;
-       }
-
-       if (e->ep_description.endpoint == NULL) {
-               e->ep_description.endpoint = talloc_asprintf(dce_ctx, "%d", port);
        }
 
-       dcesrv_sock = talloc(stream_socket, struct dcesrv_socket_context);
-       if (!dcesrv_sock) {
-               DEBUG(0,("talloc(stream_socket, struct dcesrv_socket_context) failed\n"));
-               return;
-       }
+       dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context);
+       NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
 
        /* remember the endpoint of this socket */
        dcesrv_sock->endpoint           = e;
        dcesrv_sock->dcesrv_ctx         = dce_ctx;
 
-       stream_socket->stream.private_data = dcesrv_sock;
+       status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops, 
+                                    "ipv4", address, &port, dcesrv_sock);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 
+                        address, port, nt_errstr(status)));
+       }
 
-       talloc_free(ip_str);
+       if (e->ep_description.endpoint == NULL) {
+               e->ep_description.endpoint = talloc_asprintf(dce_ctx, "%d", port);
+       }
 
-       return;
+       return status;
 }
 
-static void add_socket_rpc_tcp(struct server_service *service, struct dcesrv_endpoint *e)
+static NTSTATUS add_socket_rpc_tcp(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
+                                  struct event_context *event_ctx, const struct model_ops *model_ops)
 {
+       NTSTATUS status;
+
        /* Add TCP/IP sockets */
        if (lp_interfaces() && lp_bind_interfaces_only()) {
                int num_interfaces = iface_count();
                int i;
                for(i = 0; i < num_interfaces; i++) {
-                       struct ipv4_addr *ifip = iface_n_ip(i);
-                       if (ifip == NULL) {
-                               continue;
-                       }
-                       add_socket_rpc_tcp_iface(service, e, ifip);
+                       const char *address = sys_inet_ntoa(*iface_n_ip(i));
+                       status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
+                       NT_STATUS_NOT_OK_RETURN(status);
                }
        } else {
-               struct ipv4_addr ifip;
-               ifip = interpret_addr2(lp_socket_address());
-               add_socket_rpc_tcp_iface(service, e, &ifip);
+               status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, lp_socket_address());
+               NT_STATUS_NOT_OK_RETURN(status);
        }
 
-       return;
+       return NT_STATUS_OK;
 }
 
 /****************************************************************************
  Open the listening sockets for RPC over NCACN_IP_TCP/NCALRPC/NCACN_UNIX_STREAM
 ****************************************************************************/
-void dcesrv_sock_init(struct server_service *service)
+NTSTATUS dcesrv_sock_init(struct dcesrv_context *dce_ctx, 
+                         struct event_context *event_ctx, const struct model_ops *model_ops)
 {
-       struct dcesrv_context *dce_ctx = service->service.private_data;
        struct dcesrv_endpoint *e;
-
-       DEBUG(1,("dcesrv_sock_init\n"));
+       NTSTATUS status;
 
        /* Make sure the directory for NCALRPC exists */
        if (!directory_exist(lp_ncalrpc_dir(), NULL)) {
@@ -200,15 +275,18 @@ void dcesrv_sock_init(struct server_service *service)
        for (e=dce_ctx->endpoint_list;e;e=e->next) {
                switch (e->ep_description.transport) {
                case NCACN_UNIX_STREAM:
-                       add_socket_rpc_unix(service, e);
+                       status = add_socket_rpc_unix(dce_ctx, e, event_ctx, model_ops);
+                       NT_STATUS_NOT_OK_RETURN(status);
                        break;
                
                case NCALRPC:
-                       add_socket_rpc_ncalrpc(service, e);
+                       status = add_socket_rpc_ncalrpc(dce_ctx, e, event_ctx, model_ops);
+                       NT_STATUS_NOT_OK_RETURN(status);
                        break;
 
                case NCACN_IP_TCP:
-                       add_socket_rpc_tcp(service, e);
+                       status = add_socket_rpc_tcp(dce_ctx, e, event_ctx, model_ops);
+                       NT_STATUS_NOT_OK_RETURN(status);
                        break;
 
                default:
@@ -216,89 +294,6 @@ void dcesrv_sock_init(struct server_service *service)
                }
        }
 
-       return; 
+       return NT_STATUS_OK;    
 }
 
-void dcesrv_sock_accept(struct server_connection *srv_conn)
-{
-       NTSTATUS status;
-       struct dcesrv_socket_context *dcesrv_sock = srv_conn->stream_socket->stream.private_data;
-       struct dcesrv_connection *dcesrv_conn = NULL;
-
-       DEBUG(5,("dcesrv_sock_accept\n"));
-
-       status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
-                                        dcesrv_sock,
-                                        dcesrv_sock->endpoint,
-                                        srv_conn,
-                                        &dcesrv_conn);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n", 
-                       nt_errstr(status)));
-               return;
-       }
-
-       srv_conn->connection.private_data = dcesrv_conn;
-
-       return; 
-}
-
-void dcesrv_sock_recv(struct server_connection *conn, struct timeval t, uint16_t flags)
-{
-       NTSTATUS status;
-       struct dcesrv_connection *dce_conn = conn->connection.private_data;
-       DATA_BLOB tmp_blob;
-       size_t nread;
-
-       tmp_blob = data_blob_talloc(conn->socket, NULL, 0x1000);
-       if (tmp_blob.data == NULL) {
-               dcesrv_terminate_connection(dce_conn, "out of memory");
-               return;
-       }
-
-       status = socket_recv(conn->socket, tmp_blob.data, tmp_blob.length, &nread, 0);
-       if (NT_STATUS_IS_ERR(status)) {
-               dcesrv_terminate_connection(dce_conn, nt_errstr(status));
-               return;
-       }
-       if (nread == 0) {
-               talloc_free(tmp_blob.data);
-               return;
-       }
-
-       tmp_blob.length = nread;
-
-       status = dcesrv_input(dce_conn, &tmp_blob);
-       talloc_free(tmp_blob.data);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               dcesrv_terminate_connection(dce_conn, nt_errstr(status));
-               return;
-       }
-
-       if (dce_conn->call_list && dce_conn->call_list->replies) {
-               conn->event.fde->flags |= EVENT_FD_WRITE;
-       }
-
-       return; 
-}
-
-void dcesrv_sock_send(struct server_connection *conn, struct timeval t, uint16_t flags)
-{
-       struct dcesrv_connection *dce_conn = conn->connection.private_data;
-       NTSTATUS status;
-
-       DEBUG(10,("dcesrv_sock_send\n"));
-
-       status = dcesrv_output(dce_conn, conn->socket, dcerpc_write_fn);
-       if (!NT_STATUS_IS_OK(status)) {
-               dcesrv_terminate_connection(dce_conn, "eof on socket");
-               return;
-       }
-
-       if (!dce_conn->call_list || !dce_conn->call_list->replies) {
-               conn->event.fde->flags &= ~EVENT_FD_WRITE;
-       }
-
-       return;
-}
index 797dcc624e322afb0230c35781a0b9e3920072d5..eb9598b6be37f56b1e5969fe84e8a5bb24d24192 100644 (file)
@@ -217,10 +217,11 @@ static error_status_t epm_Map(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
        transport = dcerpc_transport_by_tower(&r->in.map_tower->tower);
 
        if (transport == -1) {
-               DEBUG(1, ("Client requested unknown transport with levels: "));
+               DEBUG(2, ("Client requested unknown transport with levels: "));
                for (i = 2; i < r->in.map_tower->tower.num_floors; i++) {
-                       DEBUG(1, ("%d, ", r->in.map_tower->tower.floors[i].lhs.protocol));
+                       DEBUG(2, ("%d, ", r->in.map_tower->tower.floors[i].lhs.protocol));
                }
+               DEBUG(2, ("\n"));
                goto failed;
        }
 
index 427add0aa23f3405a4cba85ea9ddd43ef9544215..45c5376e25ffade4a8424f02f1bec15d40085a5e 100644 (file)
@@ -23,6 +23,7 @@
 #include "system/filesys.h"
 #include "dlinklist.h"
 #include "smb_server/smb_server.h"
+#include "smbd/service_stream.h"
 
 
 /****************************************************************************
index 4af8fed53b177df9ba7582f80f4cee1a07cd900f..8223f66dc7d854b43eb8e76fbf9d7d939d2fbbe7 100644 (file)
@@ -21,6 +21,7 @@
 #include "includes.h"
 #include "auth/auth.h"
 #include "smb_server/smb_server.h"
+#include "smbd/service_stream.h"
 
 
 /* initialise the auth_context for this server and return the cryptkey */
@@ -144,7 +145,7 @@ static void reply_lanman1(struct smbsrv_request *req, uint16_t choice)
        SSVAL(req->out.vwv, VWV(3), lp_maxmux());
        SSVAL(req->out.vwv, VWV(4), 1);
        SSVAL(req->out.vwv, VWV(5), raw); 
-       SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->connection.id);
+       SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id);
        srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t);
        SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60);
        SIVAL(req->out.vwv, VWV(11), 0); /* reserved */
@@ -198,7 +199,7 @@ static void reply_lanman2(struct smbsrv_request *req, uint16_t choice)
        SSVAL(req->out.vwv, VWV(3), lp_maxmux());
        SSVAL(req->out.vwv, VWV(4), 1);
        SSVAL(req->out.vwv, VWV(5), raw); 
-       SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->connection.id);
+       SIVAL(req->out.vwv, VWV(6), req->smb_conn->connection->server_id);
        srv_push_dos_date(req->smb_conn, req->out.vwv, VWV(8), t);
        SSVAL(req->out.vwv, VWV(10), req->smb_conn->negotiate.zone_offset/60);
        SIVAL(req->out.vwv, VWV(11), 0);
@@ -310,7 +311,7 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
        SSVAL(req->out.vwv+1, VWV(2), 1); /* num vcs */
        SIVAL(req->out.vwv+1, VWV(3), req->smb_conn->negotiate.max_recv);
        SIVAL(req->out.vwv+1, VWV(5), 0x10000); /* raw size. full 64k */
-       SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->connection.id); /* session key */
+       SIVAL(req->out.vwv+1, VWV(7), req->smb_conn->connection->server_id); /* session key */
        SIVAL(req->out.vwv+1, VWV(9), capabilities);
        push_nttime(req->out.vwv+1, VWV(11), nttime);
        SSVALS(req->out.vwv+1,VWV(15), req->smb_conn->negotiate.zone_offset/60);
@@ -443,7 +444,6 @@ void reply_negprot(struct smbsrv_request *req)
   
        if(choice != -1) {
                sub_set_remote_proto(supported_protocols[protocol].short_name);
-               reload_services(req->smb_conn, True);
                supported_protocols[protocol].proto_reply_fn(req, choice);
                DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
        } else {
index c2aca046616027e792dcf7e11cbe7be49095eab7..26988bf20567c9ffe40f364ffa979418214a55cf 100644 (file)
@@ -26,6 +26,7 @@
 #include "events.h"
 #include "dlinklist.h"
 #include "smb_server/smb_server.h"
+#include "smbd/service_stream.h"
 
 
 /* we over allocate the data buffer to prevent too many realloc calls */
index d4386ca77b7fef9d66ac5b2a5e4e776657d95903..180deaf8c53b125174270b1dc177b6bdaafaad1a 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "includes.h"
 #include "smb_server/smb_server.h"
+#include "smbd/service_stream.h"
 
 
 
index eb6c8b96470b690268223f5912497ebe01c21cf0..dc3a60874a0817d6b831016934be9ccea9795a3b 100644 (file)
@@ -25,6 +25,7 @@
 #include "version.h"
 #include "auth/auth.h"
 #include "smb_server/smb_server.h"
+#include "smbd/service_stream.h"
 
 
 /*
index 394923635d5c66aa9728b17018b52b28b922bb2d..1537bf6a4763f38df08f9e516487015cebe2a67f 100644 (file)
@@ -24,6 +24,7 @@
 #include "events.h"
 #include "system/time.h"
 #include "dlinklist.h"
+#include "smbd/service_stream.h"
 #include "smb_server/smb_server.h"
 
 
@@ -506,7 +507,7 @@ static void switch_message(int type, struct smbsrv_request *req)
                session_tag = req->session->vuid;
        }
 
-       DEBUG(3,("switch message %s (task_id %d)\n",smb_fn_name(type), req->smb_conn->connection->connection.id));
+       DEBUG(3,("switch message %s (task_id %d)\n",smb_fn_name(type), req->smb_conn->connection->server_id));
 
        /* does this protocol need a valid tree connection? */
        if ((flags & AS_USER) && !req->tcon) {
@@ -646,69 +647,15 @@ error:
 */
 void smbsrv_terminate_connection(struct smbsrv_connection *smb_conn, const char *reason)
 {
-       server_terminate_connection(smb_conn->connection, reason);
-}
-
-static const struct server_stream_ops *smbsrv_stream_ops(void);
-
-/*
-  add a socket address to the list of events, one event per port
-*/
-static void smb_add_socket(struct server_service *service,
-                          struct ipv4_addr *ifip)
-{
-       const char **ports = lp_smb_ports();
-       int i;
-       char *ip_str = talloc_strdup(service, sys_inet_ntoa(*ifip));
-
-       for (i=0;ports[i];i++) {
-               uint16_t port = atoi(ports[i]);
-               if (port == 0) continue;
-               service_setup_stream_socket(service, smbsrv_stream_ops(), "ipv4", ip_str, &port);
-       }
-
-       talloc_free(ip_str);
-}
-
-/****************************************************************************
- Open the socket communication.
-****************************************************************************/
-static void smbsrv_init(struct server_service *service)
-{      
-       DEBUG(1,("smbsrv_init\n"));
-
-       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,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
-                               continue;
-                       }
-
-                       smb_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());
-               smb_add_socket(service, &ifip);
-       }
+       stream_terminate_connection(smb_conn->connection, reason);
 }
 
 /*
   called when a SMB socket becomes readable
 */
-static void smbsrv_recv(struct server_connection *conn, struct timeval t, uint16_t flags)
+static void smbsrv_recv(struct stream_connection *conn, struct timeval t, uint16_t flags)
 {
-       struct smbsrv_connection *smb_conn = conn->connection.private_data;
+       struct smbsrv_connection *smb_conn = talloc_get_type(conn->private, struct smbsrv_connection);
        NTSTATUS status;
 
        DEBUG(10,("smbsrv_recv\n"));
@@ -727,9 +674,9 @@ static void smbsrv_recv(struct server_connection *conn, struct timeval t, uint16
 /*
   called when a SMB socket becomes writable
 */
-static void smbsrv_send(struct server_connection *conn, struct timeval t, uint16_t flags)
+static void smbsrv_send(struct stream_connection *conn, struct timeval t, uint16_t flags)
 {
-       struct smbsrv_connection *smb_conn = conn->connection.private_data;
+       struct smbsrv_connection *smb_conn = talloc_get_type(conn->private, struct smbsrv_connection);
 
        while (smb_conn->pending_send) {
                struct smbsrv_request *req = smb_conn->pending_send;
@@ -767,39 +714,11 @@ static void smbsrv_send(struct server_connection *conn, struct timeval t, uint16
        }
 }
 
-static void smbsrv_close(struct server_connection *conn, const char *reason)
-{
-       struct smbsrv_connection *smb_conn = conn->connection.private_data;
-
-       DEBUG(5,("smbsrv_close: %s\n",reason));
-
-       talloc_free(smb_conn);
-
-       return;
-}
-
-/*
-  process a message from an SMB socket while still processing a
-  previous message this is used by backends who need to ensure that
-  new messages from clients are still processed while they are
-  performing long operations
-*/
-void smbd_process_async(struct smbsrv_connection *smb_conn)
-{
-       NTSTATUS status;
-       
-       status = receive_smb_request(smb_conn, timeval_current());
-       if (NT_STATUS_IS_ERR(status)) {
-               smbsrv_terminate_connection(smb_conn, nt_errstr(status));
-       }
-}
-
-
 /*
   initialise a server_context from a open socket and register a event handler
   for reading from that socket
 */
-static void smbsrv_accept(struct server_connection *conn)
+static void smbsrv_accept(struct stream_connection *conn)
 {
        struct smbsrv_connection *smb_conn;
 
@@ -825,37 +744,71 @@ static void smbsrv_accept(struct server_connection *conn)
 
        smb_conn->connection = conn;
 
-       conn->connection.private_data = smb_conn;
-
-       return;
+       conn->private = smb_conn;
 }
 
-static const struct server_stream_ops smb_stream_ops = {
+
+static const struct stream_server_ops smb_stream_ops = {
        .name                   = "smb",
-       .socket_init            = NULL,
        .accept_connection      = smbsrv_accept,
        .recv_handler           = smbsrv_recv,
        .send_handler           = smbsrv_send,
-       .idle_handler           = NULL,
-       .close_connection       = smbsrv_close
 };
 
-static const struct server_stream_ops *smbsrv_stream_ops(void)
+/*
+  setup a listening socket on all the SMB ports for a particular address
+*/
+static NTSTATUS smb_add_socket(struct event_context *event_context,
+                              const struct model_ops *model_ops,
+                              const char *address)
 {
-       return &smb_stream_ops;
+       const char **ports = lp_smb_ports();
+       int i;
+       NTSTATUS status;
+
+       for (i=0;ports[i];i++) {
+               uint16_t port = atoi(ports[i]);
+               if (port == 0) continue;
+               status = stream_setup_socket(event_context, model_ops, &smb_stream_ops, 
+                                            "ipv4", address, &port, NULL);
+               NT_STATUS_NOT_OK_RETURN(status);
+       }
+
+       return NT_STATUS_OK;
 }
 
-static const struct server_service_ops smb_server_ops = {
-       .name                   = "smb",
-       .service_init           = smbsrv_init,  
-};
+/*
+  called on startup of the smb server service It's job is to start
+  listening on all configured SMB server sockets
+*/
+static NTSTATUS smbsrv_init(struct event_context *event_context, const struct model_ops *model_ops)
+{      
+       NTSTATUS status;
 
-const struct server_service_ops *smbsrv_get_ops(void)
-{
-       return &smb_server_ops;
+       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 = smb_add_socket(event_context, model_ops, address);
+                       NT_STATUS_NOT_OK_RETURN(status);
+               }
+       } else {
+               /* Just bind to lp_socket_address() (usually 0.0.0.0) */
+               status = smb_add_socket(event_context, model_ops, lp_socket_address());
+               NT_STATUS_NOT_OK_RETURN(status);
+       }
+
+       return NT_STATUS_OK;
 }
 
+/* called at smbd startup - register ourselves as a server service */
 NTSTATUS server_service_smb_init(void)
 {
-       return NT_STATUS_OK;    
+       return register_server_service("smb", smbsrv_init);
 }
index 2b1ca87cb9faf99602c9a4d49b0ef97c242ec1f7..02070f2b130eaba99bf8a2b65f64fe27438d23e7 100644 (file)
@@ -232,7 +232,7 @@ struct smbsrv_connection {
 
        struct smb_signing_context signing;
        
-       struct server_connection *connection;
+       struct stream_connection *connection;
 
        /* this holds a partially received request */
        struct smbsrv_request *partial_req;
index cd2fb4ab725bcba5fe4539e50c820b64b26c787b..07847b7fc8d548a4949cd24b21d01526eb729f55 100644 (file)
@@ -44,7 +44,8 @@ REQUIRED_SUBSYSTEMS = \
 # Start SUBSYSTEM SERVICE
 [SUBSYSTEM::SERVER_SERVICE]
 INIT_OBJ_FILES = \
-               smbd/service.o
+               smbd/service.o \
+               smbd/service_stream.o
 REQUIRED_SUBSYSTEMS = \
                MESSAGING
 # End SUBSYSTEM SERVER
@@ -54,8 +55,7 @@ REQUIRED_SUBSYSTEMS = \
 # Start BINARY smbd
 [BINARY::smbd]
 OBJ_FILES = \
-               smbd/server.o \
-               smbd/rewrite.o
+               smbd/server.o
 REQUIRED_SUBSYSTEMS = \
                PROCESS_MODEL \
                SERVER_SERVICE \
index f2abfd0a497f42b6acce12fe095aeab250226bcc..16a0075d2d5c4cf114b69d85b5dde10660d9e237 100644 (file)
 #include "includes.h"
 #include "events.h"
 #include "smb_server/smb_server.h"
-#include "smbd/process_model.h"
 
 /*
   setup the events for the chosen process model
 */
-const struct model_ops *process_model_startup(struct server_context *srv_ctx, const char *model)
+const struct model_ops *process_model_startup(struct event_context *ev, const char *model)
 {
        const struct model_ops *ops;
 
@@ -37,7 +36,7 @@ const struct model_ops *process_model_startup(struct server_context *srv_ctx, co
                exit(-1);
        }
 
-       ops->model_init(srv_ctx);
+       ops->model_init(ev);
 
        return ops;
 }
@@ -107,7 +106,6 @@ const struct process_model_critical_sizes *process_model_version(void)
        static const struct process_model_critical_sizes critical_sizes = {
                PROCESS_MODEL_VERSION,
                sizeof(struct model_ops),
-               sizeof(struct smbsrv_connection),
                sizeof(struct event_context),
                sizeof(struct fd_event)
        };
index fb9bdfd44b97f10843c66087da1d16291110deef..943538d7b2163c7e95454291ee581583e9f2443d 100644 (file)
@@ -1,7 +1,9 @@
 /* 
    Unix SMB/CIFS implementation.
-   process model manager - main loop
-   Copyright (C) Andrew Tridgell 1992-2003
+
+   process model manager - structures
+
+   Copyright (C) Andrew Tridgell 1992-2005
    Copyright (C) James J Myers 2003 <myersjj@samba.org>
    Copyright (C) Stefan (metze) Metzmacher 2004-2005
    
@@ -20,9 +22,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#ifndef SAMBA_PROCESS_MODEL_H
-#define SAMBA_PROCESS_MODEL_H
-
 /* modules can use the following to determine if the interface has changed
  * please increment the version number after each interface change
  * with a comment and maybe update struct process_model_critical_sizes.
@@ -37,32 +36,22 @@ struct model_ops {
        const char *name;
 
        /* called at startup when the model is selected */
-       void (*model_init)(struct server_context *srv_ctx);
-       /* called at th eend of the main server process */
-       void (*model_exit)(struct server_context *srv_ctx, const char *reason);
-
+       void (*model_init)(struct event_context *);
 
        /* function to accept new connection */
-       void (*accept_connection)(struct event_context *, struct fd_event *, 
-                                 struct timeval t, uint16_t);
-       /* function to terminate a connection */
-       void (*terminate_connection)(struct server_connection *srv_conn, 
-                                    const char *reason);
-
+       void (*accept_connection)(struct event_context *, struct socket_context *, 
+                                 void (*)(struct event_context *, struct socket_context *, 
+                                          uint32_t , void *), 
+                                 void *);
 
-       /* function to create a new task event_context */
-       void (*create_task)(struct server_task *task);
-       /* function to exit this task */
-       void (*terminate_task)(struct server_task *task, const char *reason);
+       /* function to terminate a connection */
+       void (*terminate_connection)(struct event_context *, const char *reason);
 };
 
 /* this structure is used by modules to determine the size of some critical types */
 struct process_model_critical_sizes {
        int interface_version;
        int sizeof_model_ops;
-       int sizeof_server_context;
        int sizeof_event_context;
        int sizeof_fd_event;
 };
-
-#endif /* SAMBA_PROCESS_MODEL_H */
index 6a00ad237fd5bcb4c278e4bf6e25d2cef78b5d96..d6217d87125a78e0fd7d91ef62a70e9315ccc5e6 100644 (file)
@@ -1,6 +1,8 @@
 /* 
    Unix SMB/CIFS implementation.
+
    process model: process (1 process handles all client connections)
+
    Copyright (C) Andrew Tridgell 2003
    Copyright (C) James J Myers 2003 <myersjj@samba.org>
    Copyright (C) Stefan (metze) Metzmacher 2004
 #include "events.h"
 #include "dlinklist.h"
 #include "smb_server/smb_server.h"
-#include "process_model.h"
 
 
 /*
   called when the process model is selected
 */
-static void single_model_init(struct server_context *server)
-{
-}
-
-static void single_model_exit(struct server_context *server, const char *reason)
+static void single_model_init(struct event_context *ev)
 {
-       DEBUG(1,("single_exit_server: reason[%s]\n",reason));
-       talloc_free(server);
-       exit(0);
 }
 
 /*
-  called when a listening socket becomes readable
+  called when a listening socket becomes readable
 */
-static void single_accept_connection(struct event_context *ev, struct fd_event *srv_fde, 
-                                    struct timeval t, uint16_t flags)
+static void single_accept_connection(struct event_context *ev, 
+                                    struct socket_context *sock,
+                                    void (*new_conn)(struct event_context *, struct socket_context *, 
+                                                     uint32_t , void *), 
+                                    void *private)
 {
        NTSTATUS status;
-       struct socket_context *sock;
-       struct server_stream_socket *stream_socket = srv_fde->private;
-       struct server_connection *conn;
+       struct socket_context *sock2;
 
        /* accept an incoming connection. */
-       status = socket_accept(stream_socket->socket, &sock);
+       status = socket_accept(sock, &sock2);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("accept_connection_single: accept: %s\n",
-                        nt_errstr(status)));
-               return;
-       }
-
-       conn = server_setup_connection(ev, stream_socket, sock, t, socket_get_fd(sock));
-       if (!conn) {
-               DEBUG(10,("server_setup_connection failed\n"));
+               DEBUG(0,("accept_connection_single: accept: %s\n", nt_errstr(status)));
                return;
        }
 
-       talloc_steal(conn, sock);
+       talloc_steal(private, sock);
 
-       /* return to event handling */
-       return;
+       new_conn(ev, sock2, socket_get_fd(sock), private);
 }
 
 
-
-/* called when a SMB connection goes down */
-static void single_terminate_connection(struct server_connection *conn, const char *reason) 
+/* called when a connection goes down */
+static void single_terminate_connection(struct event_context *ev, const char *reason) 
 {
-       DEBUG(2,("single_terminate_connection: reason[%s]\n",reason));
-
-       if (conn) {
-               talloc_free(conn);
-       }
-}
-
-/*
-  called to create a new event context for a new task
-*/
-static void single_create_task(struct server_task *task)
-{
-       task->task.id   = (uint32_t)task;
-       task->event.ctx = task->service->server->event.ctx;
-
-       /* setup to receive internal messages on this connection */
-       task->messaging.ctx = messaging_init(task, task->task.id, task->event.ctx);
-       if (!task->messaging.ctx) {
-               server_terminate_task(task, "messaging_init() failed");
-               return;
-       }
-
-       task->task.ops->task_init(task);
-       return;
-}
-
-/*
-  called to exit from a server_task
-*/
-static void single_terminate_task(struct server_task *task, const char *reason)
-{
-       DEBUG(1,("single_exit_server: reason[%s]\n",reason));
-       talloc_free(task);
-       return;
 }
 
 static const struct model_ops single_ops = {
        .name                   = "single",
-
        .model_init             = single_model_init,
-       .model_exit             = single_model_exit,
-
        .accept_connection      = single_accept_connection,
        .terminate_connection   = single_terminate_connection,
-
-       .create_task            = single_create_task,
-       .terminate_task         = single_terminate_task
 };
 
 /*
-  initialise the single process model, registering ourselves with the process model subsystem
+  initialise the single process model, registering ourselves with the
+  process model subsystem
  */
 NTSTATUS process_model_single_init(void)
 {
-       NTSTATUS ret;
-
-       /* register ourselves with the PROCESS_MODEL subsystem. */
-       ret = register_process_model(&single_ops);
-       if (!NT_STATUS_IS_OK(ret)) {
-               DEBUG(0,("Failed to register process_model 'single'!\n"));
-               return ret;
-       }
-
-       return ret;
+       return register_process_model(&single_ops);
 }
index b0f7cf1a11133b283936806efcbd849c2e0dffac..ee73cfadcf176fd084ef2ab6572a3459cc18f08c 100644 (file)
@@ -1,7 +1,9 @@
 /* 
    Unix SMB/CIFS implementation.
+
    process model: standard (1 process per client connection)
-   Copyright (C) Andrew Tridgell 1992-2003
+
+   Copyright (C) Andrew Tridgell 1992-2005
    Copyright (C) James J Myers 2003 <myersjj@samba.org>
    Copyright (C) Stefan (metze) Metzmacher 2004
    
 #include "events.h"
 #include "dlinklist.h"
 #include "smb_server/smb_server.h"
-#include "process_model.h"
 
 /*
   called when the process model is selected
 */
-static void standard_model_init(struct server_context *server)
+static void standard_model_init(struct event_context *ev)
 {
        signal(SIGCHLD, SIG_IGN);
 }
 
-static void standard_model_exit(struct server_context *server, const char *reason)
-{
-       DEBUG(1,("standard_model_exit: reason[%s]\n",reason));
-       talloc_free(server);
-       exit(0);
-}
-
 /*
-  called when a listening socket becomes readable
+  called when a listening socket becomes readable
 */
-static void standard_accept_connection(struct event_context *ev, struct fd_event *srv_fde,
-                                      struct timeval t, uint16_t flags)
+static void standard_accept_connection(struct event_context *ev, 
+                                      struct socket_context *sock, 
+                                      void (*new_conn)(struct event_context *, struct socket_context *, 
+                                                       uint32_t , void *), 
+                                      void *private)
 {
        NTSTATUS status;
-       struct socket_context *sock;
-       struct server_stream_socket *stream_socket = srv_fde->private;
-       struct server_connection *conn;
+       struct socket_context *sock2;
        pid_t pid;
+       struct event_context *ev2;
 
        /* accept an incoming connection. */
-       status = socket_accept(stream_socket->socket, &sock);
+       status = socket_accept(sock, &sock2);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("standard_accept_connection: accept: %s\n",
                         nt_errstr(status)));
@@ -65,20 +61,28 @@ static void standard_accept_connection(struct event_context *ev, struct fd_event
 
        if (pid != 0) {
                /* parent or error code ... */
-
-               socket_destroy(sock);
+               talloc_free(sock2);
                /* go back to the event loop */
                return;
        }
 
-       /* Child code ... */
+       /* This is now the child code. We need a completely new event_context to work with */
+       ev2 = event_context_init(NULL);
 
-       /* close all the listening sockets */
-       event_remove_fd_all_handler(ev, server_accept_handler);
+       /* the service has given us a private pointer that
+          encapsulates the context it needs for this new connection -
+          everything else will be freed */
+       talloc_steal(ev2, private);
+       talloc_steal(private, sock2);
+
+       /* this will free all the listening sockets and all state that
+          is not associated with this new connection */
+       talloc_free(sock);
+       talloc_free(ev);
 
        /* we don't care if the dup fails, as its only a select()
           speed optimisation */
-       socket_dup(sock);
+       socket_dup(sock2);
                        
        /* tdb needs special fork handling */
        if (tdb_reopen_all() == -1) {
@@ -86,31 +90,26 @@ static void standard_accept_connection(struct event_context *ev, struct fd_event
        }
 
        /* Ensure that the forked children do not expose identical random streams */
-
        set_need_random_reseed();
 
-       conn = server_setup_connection(ev, stream_socket, sock, t, getpid());
-       if (!conn) {
-               DEBUG(0,("server_setup_connection(ev, server_socket, sock, t) failed\n"));
-               exit(1);
-               return;
-       }
+       /* setup this new connection */
+       new_conn(ev2, sock2, getpid(), private);
 
-       talloc_steal(conn, sock);
+       /* we can't return to the top level here, as that event context is gone,
+          so we now process events in the new event context until there are no
+          more to process */      
+       event_loop_wait(ev2);
 
-       /* return to the event loop */
+       talloc_free(ev2);
+       exit(0);
 }
 
 
-/* called when a SMB connection goes down */
-static void standard_terminate_connection(struct server_connection *conn, const char *reason) 
+/* called when a connection goes down */
+static void standard_terminate_connection(struct event_context *ev, const char *reason) 
 {
        DEBUG(2,("standard_terminate_connection: reason[%s]\n",reason));
 
-       if (conn) {
-               talloc_free(conn->stream_socket->service->server);
-       }
-
        /* this init_iconv() has the effect of freeing the iconv context memory,
           which makes leak checking easier */
        init_iconv();
@@ -118,87 +117,18 @@ static void standard_terminate_connection(struct server_connection *conn, const
        /* the secrets db should really hang off the connection structure */
        secrets_shutdown();
 
-       /* terminate this process */
-       exit(0);
-}
-
-/*
-  called to create a new event context for a new task
-*/
-static void standard_create_task(struct server_task *task)
-{
-       pid_t pid;
-
-       pid = fork();
-
-       if (pid != 0) {
-               /* parent or error code ... */
-               talloc_free(task);
-               /* go back to the event loop */
-               return;
-       }
-
-       /* Child code ... */
-
-       /* close all the listening sockets */
-       event_remove_fd_all_handler(task->service->server->event.ctx, server_accept_handler);
-
-       /* tdb needs special fork handling */
-       if (tdb_reopen_all() == -1) {
-               DEBUG(0,("standard_accept_connection: tdb_reopen_all failed.\n"));
-       }
-
-       /* Ensure that the forked children do not expose identical random streams */
-
-       set_need_random_reseed();
-
-       task->task.id   = (uint32)getpid();
-       task->event.ctx = task->service->server->event.ctx;
-
-       /* setup to receive internal messages on this connection */
-       task->messaging.ctx = messaging_init(task, task->task.id, task->event.ctx);
-       if (!task->messaging.ctx) {
-               server_terminate_task(task, "messaging_init() failed");
-               return;
-       }
-
-       task->task.ops->task_init(task);
-
-       server_terminate_task(task, "exit");
-       return;
-}
-
-/*
-  called to destroy a new event context for a new task
-*/
-static void standard_terminate_task(struct server_task *task, const char *reason)
-{
-       DEBUG(2,("standard_terminate_task: reason[%s]\n",reason));
-
-       talloc_free(task);
-
-       /* this init_iconv() has the effect of freeing the iconv context memory,
-          which makes leak checking easier */
-       init_iconv();
-
-       /* the secrets db should really hang off the connection structure */
-       secrets_shutdown();
+       talloc_free(ev);
 
        /* terminate this process */
        exit(0);
 }
 
+
 static const struct model_ops standard_ops = {
        .name                   = "standard",
-
        .model_init             = standard_model_init,
-       .model_exit             = standard_model_exit,
-
        .accept_connection      = standard_accept_connection,
        .terminate_connection   = standard_terminate_connection,
-
-       .create_task            = standard_create_task,
-       .terminate_task         = standard_terminate_task
 };
 
 /*
@@ -206,14 +136,5 @@ static const struct model_ops standard_ops = {
  */
 NTSTATUS process_model_standard_init(void)
 {
-       NTSTATUS ret;
-
-       /* register ourselves with the PROCESS_MODEL subsystem. */
-       ret = register_process_model(&standard_ops);
-       if (!NT_STATUS_IS_OK(ret)) {
-               DEBUG(0,("Failed to register process_model 'standard'!\n"));
-               return ret;
-       }
-
-       return ret;
+       return register_process_model(&standard_ops);
 }
index 8d65292cfdafad363982b35957b3a9ee562afc31..6b62ca413e10957093f6f2c26a36488c81b200e3 100644 (file)
@@ -1,7 +1,9 @@
 /* 
    Unix SMB/CIFS implementation.
+
    thread model: standard (1 thread per client connection)
-   Copyright (C) Andrew Tridgell 2003
+
+   Copyright (C) Andrew Tridgell 2003-2005
    Copyright (C) James J Myers 2003 <myersjj@samba.org>
    Copyright (C) Stefan (metze) Metzmacher 2004
    
 #include "events.h"
 #include "dlinklist.h"
 #include "smb_server/smb_server.h"
-#include "process_model.h"
+
+struct new_conn_state {
+       struct event_context *ev;
+       struct socket_context *sock;
+       void (*new_conn)(struct event_context *, struct socket_context *, uint32_t , void *);
+       void *private;
+};
 
 static void *thread_connection_fn(void *thread_parm)
 {
-       struct server_connection *conn = thread_parm;
+       struct new_conn_state *new_conn = talloc_get_type(thread_parm, struct new_conn_state);
 
-       conn->connection.id = pthread_self();
+       new_conn->new_conn(new_conn->ev, new_conn->sock, pthread_self(), new_conn->private);
 
-       /* wait for action */
-       event_loop_wait(conn->event.ctx);
+       /* run this connection from here */
+       event_loop_wait(new_conn->ev);
+
+       talloc_free(new_conn);
 
-#if 0
-       pthread_cleanup_pop(1);  /* will invoke terminate_mt_connection() */
-#endif
        return NULL;
 }
 
 /*
   called when a listening socket becomes readable
 */
-static void thread_accept_connection(struct event_context *ev, struct fd_event *srv_fde, 
-                             struct timeval t, uint16_t flags)
+static void thread_accept_connection(struct event_context *ev, 
+                                    struct socket_context *sock,
+                                    void (*new_conn)(struct event_context *, struct socket_context *, 
+                                                     uint32_t , void *), 
+                                    void *private)
 {              
        NTSTATUS status;
-       struct socket_context *sock;
        int rc;
        pthread_t thread_id;
        pthread_attr_t thread_attr;
-       struct server_stream_socket *stream_socket = srv_fde->private;
-       struct server_connection *conn;
+       struct new_conn_state *state;
+       struct event_context *ev2;
 
-       /* accept an incoming connection. */
-       status = socket_accept(stream_socket->socket, &sock);
-       if (!NT_STATUS_IS_OK(status)) {
-               return;
-       }
+       ev2 = event_context_init(ev);
+       if (ev2 == NULL) return;
 
-       /* create new detached thread for this connection.  The new
-          thread gets a new event_context with a single fd_event for
-          receiving from the new socket. We set that thread running
-          with the main event loop, then return. When we return the
-          main event_context is continued.
-       */
-
-       ev = event_context_init(stream_socket);
-       if (!ev) {
-               socket_destroy(sock);
+       state = talloc(ev2, struct new_conn_state);
+       if (state == NULL) {
+               talloc_free(ev2);
                return;
        }
 
-       conn = server_setup_connection(ev, stream_socket, sock, t, -1);
-       if (!conn) {
-               event_context_destroy(ev);
-               socket_destroy(sock);
+       state->new_conn = new_conn;
+       state->private  = private;
+       state->ev       = ev2;
+
+       /* accept an incoming connection. */
+       status = socket_accept(sock, &state->sock);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(ev2);
                return;
        }
 
-       talloc_steal(conn, ev);
-       talloc_steal(conn, sock);
+       talloc_steal(state, state->sock);
 
        pthread_attr_init(&thread_attr);
        pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
-       rc = pthread_create(&thread_id, &thread_attr, thread_connection_fn, conn);
+       rc = pthread_create(&thread_id, &thread_attr, thread_connection_fn, state);
        pthread_attr_destroy(&thread_attr);
        if (rc == 0) {
                DEBUG(4,("accept_connection_thread: created thread_id=%lu for fd=%d\n", 
                        (unsigned long int)thread_id, socket_get_fd(sock)));
        } else {
                DEBUG(0,("accept_connection_thread: thread create failed for fd=%d, rc=%d\n", socket_get_fd(sock), rc));
-               event_context_destroy(ev);
-               socket_destroy(sock);
-               return;
+               talloc_free(ev2);
        }
 }
 
 /* called when a SMB connection goes down */
-static void thread_terminate_connection(struct server_connection *conn, const char *reason) 
+static void thread_terminate_connection(struct event_context *event_ctx, const char *reason) 
 {
        DEBUG(10,("thread_terminate_connection: reason[%s]\n",reason));
 
-       if (conn) {
-               talloc_free(conn);
-       }
+       talloc_free(event_ctx);
 
        /* terminate this thread */
        pthread_exit(NULL);  /* thread cleanup routine will do actual cleanup */
@@ -342,6 +340,7 @@ static void thread_log_task_id(int fd)
        write(fd, s, strlen(s));
        free(s);
 }
+
 /****************************************************************************
 catch serious errors
 ****************************************************************************/
@@ -406,7 +405,7 @@ static void thread_fault_handler(int sig)
 /*
   called when the process model is selected
 */
-static void thread_model_init(struct server_context *server)
+static void thread_model_init(struct event_context *event_context)
 {
        struct mutex_ops m_ops;
        struct debug_ops d_ops;
@@ -438,89 +437,12 @@ static void thread_model_init(struct server_context *server)
        register_debug_handlers("thread", &d_ops);      
 }
 
-static void thread_model_exit(struct server_context *server, const char *reason)
-{
-       DEBUG(1,("thread_model_exit: reason[%s]\n",reason));
-       talloc_free(server);
-       exit(0);
-}
-
-static void *thread_task_fn(void *thread_parm)
-{
-       struct server_task *task = thread_parm;
-
-       task->task.id = pthread_self();
-
-       task->event.ctx = event_context_init(task);
-       if (!task->event.ctx) {
-               server_terminate_task(task, "event_context_init() failed");
-               return NULL; 
-       }
-
-       task->messaging.ctx = messaging_init(task, task->task.id, task->event.ctx);
-       if (!task->messaging.ctx) {
-               server_terminate_task(task, "messaging_init() failed");
-               return NULL;
-       }
-
-       task->task.ops->task_init(task);
-
-       /* wait for action */
-       event_loop_wait(task->event.ctx);
-
-       server_terminate_task(task, "exit");
-#if 0
-       pthread_cleanup_pop(1);  /* will invoke terminate_mt_connection() */
-#endif
-       return NULL;
-}
-/*
-  called to create a new event context for a new task
-*/
-static void thread_create_task(struct server_task *task)
-{
-       int rc;
-       pthread_t thread_id;
-       pthread_attr_t thread_attr;
-
-       pthread_attr_init(&thread_attr);
-       pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
-       rc = pthread_create(&thread_id, &thread_attr, thread_task_fn, task);
-       pthread_attr_destroy(&thread_attr);
-       if (rc == 0) {
-               DEBUG(4,("thread_create_task: created thread_id=%lu for task='%s'\n", 
-                       (unsigned long int)thread_id, task->task.ops->name));
-       } else {
-               DEBUG(0,("thread_create_task: thread create failed for task='%s', rc=%d\n", task->task.ops->name, rc));
-               return;
-       }
-       return;
-}
-
-/*
-  called to destroy a new event context for a new task
-*/
-static void thread_terminate_task(struct server_task *task, const char *reason)
-{
-       DEBUG(2,("thread_terminate_task: reason[%s]\n",reason));
-
-       talloc_free(task);
-
-       /* terminate this thread */
-       pthread_exit(NULL);  /* thread cleanup routine will do actual cleanup */
-}
 
 static const struct model_ops thread_ops = {
        .name                   = "thread",
-
        .model_init             = thread_model_init,
-       .model_exit             = thread_model_exit,
-
        .accept_connection      = thread_accept_connection,
        .terminate_connection   = thread_terminate_connection,
-
-       .create_task            = thread_create_task,
-       .terminate_task         = thread_terminate_task
 };
 
 /*
diff --git a/source4/smbd/rewrite.c b/source4/smbd/rewrite.c
deleted file mode 100644 (file)
index 7128a0a..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "includes.h"
-#include "dynconfig.h"
-
-
-/*
- * initialize an smb process. Guaranteed to be called only once per
- * smbd instance (so it can assume it is starting from scratch, and
- * delete temporary files etc)
- */
-void smbd_process_init(void)
-{
-       /* possibly reload the services file. */
-       reload_services(NULL, True);
-
-       if (*lp_rootdir()) {
-               if (sys_chroot(lp_rootdir()) == 0)
-                       DEBUG(2,("Changed root to %s\n", lp_rootdir()));
-       }
-
-       service_cleanup_tmp_files();
-}
-
-void init_subsystems(void)
-{
-       /* Do *not* remove this, until you have removed
-        * passdb/secrets.c, and proved that Samba still builds... */
-
-       /* Setup the SECRETS subsystem */
-       if (!secrets_init()) {
-               exit(1);
-       }
-
-       smbd_init_subsystems;
-}
-
-/****************************************************************************
- Reload the services file.
-**************************************************************************/
-BOOL reload_services(struct smbsrv_connection *smb, BOOL test)
-{
-       BOOL ret;
-       
-       if (lp_loaded()) {
-               pstring fname;
-               pstrcpy(fname,lp_configfile());
-               if (file_exist(fname, NULL) &&
-                   !strcsequal(fname, dyn_CONFIGFILE)) {
-                       pstrcpy(dyn_CONFIGFILE, fname);
-                       test = False;
-               }
-       }
-
-       reopen_logs();
-
-       if (test && !lp_file_list_changed())
-               return(True);
-
-       ret = lp_load(dyn_CONFIGFILE, False, False, True);
-
-       /* perhaps the config filename is now set */
-       if (!test)
-               reload_services(smb, True);
-
-       reopen_logs();
-
-       load_interfaces();
-
-       return(ret);
-}
-
index 3c4c40fe1ca7d0e954eda9a83304ef654c39d528..57f835970ee77c34aa60384f407af38f7e80da5f 100644 (file)
@@ -1,7 +1,9 @@
 /* 
    Unix SMB/CIFS implementation.
+
    Main SMB server routines
-   Copyright (C) Andrew Tridgell               1992-1998
+
+   Copyright (C) Andrew Tridgell               1992-2005
    Copyright (C) Martin Pool                   2002
    Copyright (C) Jelmer Vernooij               2002
    Copyright (C) James J Myers                         2003 <myersjj@samba.org>
 
 #include "includes.h"
 #include "version.h"
+#include "dynconfig.h"
 #include "lib/cmdline/popt_common.h"
+#include "system/dir.h"
 
-/****************************************************************************
- main server.
-****************************************************************************/
-static int binary_smbd_main(int argc,const char *argv[])
+
+/*
+  cleanup temporary files. This is the new alternative to
+  TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
+  efficient on unix systems due to the lack of scaling of the byte
+  range locking system. So instead of putting the burden on tdb to
+  cleanup tmp files, this function deletes them. 
+*/
+static void cleanup_tmp_files(void)
 {
-       BOOL is_daemon = False;
-       BOOL interactive = False;
-       BOOL Fork = True;
-       BOOL log_stdout = False;
-       int opt;
-       poptContext pc;
-       struct server_context *server;
-       const char *model = "standard";
-       struct poptOption long_options[] = {
-       POPT_AUTOHELP
-       POPT_COMMON_SAMBA
-       {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" , NULL },
-       {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)", NULL},
-       {"foreground", 'F', POPT_ARG_VAL, &Fork, True, "Run daemon in foreground (for daemontools & etc)" , NULL },
-       {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout", NULL },
-       {"port", 'p', POPT_ARG_STRING, NULL, 0, "Listen on the specified ports", "PORTS"},
-       {"model", 'M', POPT_ARG_STRING, &model, True, "Select process model", "MODEL"},
-       POPT_COMMON_VERSION
-       POPT_TABLEEND
-       };
-       
-       pc = poptGetContext("smbd", argc, argv, long_options, 0);
-       
-       while((opt = poptGetNextOpt(pc)) != -1) {
-               switch (opt)  {
-               case 'p':
-                       lp_set_cmdline("smb ports", poptGetOptArg(pc));
-                       break;
-               }
-       }
-       poptFreeContext(pc);
+       char *path;
+       DIR *dir;
+       struct dirent *de;
+       TALLOC_CTX *mem_ctx = talloc_new(NULL);
+
+       path = smbd_tmp_path(mem_ctx, NULL);
 
-       if (interactive) {
-               Fork = False;
-               log_stdout = True;
+       dir = opendir(path);
+       if (!dir) {
+               talloc_free(mem_ctx);
+               return;
        }
 
-       if (log_stdout && Fork) {
-               DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
-               exit(1);
+       for (de=readdir(dir);de;de=readdir(dir)) {
+               char *fname = talloc_asprintf(mem_ctx, "%s/%s", path, de->d_name);
+               int ret = unlink(fname);
+               if (ret == -1 &&
+                   errno != ENOENT &&
+                   errno != EISDIR &&
+                   errno != EISDIR) {
+                       DEBUG(0,("Unabled to delete '%s' - %s\n", 
+                                fname, strerror(errno)));
+                       smb_panic("unable to cleanup tmp files");
+               }
+               talloc_free(fname);
        }
-       setup_logging(argv[0], log_stdout?DEBUG_STDOUT:DEBUG_FILE);
+       closedir(dir);
+
+       talloc_free(mem_ctx);
+}
 
+/*
+  setup signal masks
+*/
+static void setup_signals(void)
+{
        fault_setup(NULL);
        
        /* we are never interested in SIGPIPE */
@@ -93,6 +95,39 @@ static int binary_smbd_main(int argc,const char *argv[])
        BlockSignals(False, SIGHUP);
        BlockSignals(False, SIGUSR1);
        BlockSignals(False, SIGTERM);
+}
+
+
+/*
+ main server.
+*/
+static int binary_smbd_main(int argc, const char *argv[])
+{
+       BOOL interactive = False;
+       int opt;
+       poptContext pc;
+       struct event_context *event_ctx;
+       NTSTATUS status;
+       const char *model = "standard";
+       struct poptOption long_options[] = {
+               POPT_AUTOHELP
+               POPT_COMMON_SAMBA
+               {"interactive", 'i', POPT_ARG_VAL, &interactive, True, 
+                "Run interactive (not a daemon)", NULL},
+               {"model", 'M', POPT_ARG_STRING, &model, True, 
+                "Select process model", "MODEL"},
+               POPT_COMMON_VERSION
+               POPT_TABLEEND
+       };
+       
+       pc = poptGetContext("smbd", argc, argv, long_options, 0);
+       
+       while((opt = poptGetNextOpt(pc)) != -1) /* noop */ ;
+
+       poptFreeContext(pc);
+
+       setup_logging(argv[0], interactive?DEBUG_STDOUT:DEBUG_FILE);
+       setup_signals();
 
        /* we want total control over the permissions on created files,
           so set our umask to 0 */
@@ -108,49 +143,51 @@ static int binary_smbd_main(int argc,const char *argv[])
                exit(1);
        }
 
-       if (!reload_services(NULL, False))
-               return(-1);     
-
-       if (!is_daemon && !is_a_socket(0)) {
-               if (!interactive)
-                       DEBUG(0,("standard input is not a socket, assuming -D option\n"));
+       lp_load(dyn_CONFIGFILE, False, False, True);
 
-               /*
-                * Setting is_daemon here prevents us from eventually calling
-                * the open_sockets_inetd()
-                */
-
-               is_daemon = True;
-       }
+       reopen_logs();
+       load_interfaces();
 
-       if (is_daemon && !interactive) {
+       if (!interactive) {
                DEBUG(3,("Becoming a daemon.\n"));
-               become_daemon(Fork);
+               become_daemon(True);
        }
 
+       cleanup_tmp_files();
+
        if (!directory_exist(lp_lockdir(), NULL)) {
                mkdir(lp_lockdir(), 0755);
        }
 
-       if (is_daemon) {
-               pidfile_create("smbd");
+       pidfile_create("smbd");
+
+       /* Do *not* remove this, until you have removed
+        * passdb/secrets.c, and proved that Samba still builds... */
+       /* Setup the SECRETS subsystem */
+       if (!secrets_init()) {
+               exit(1);
        }
 
-       init_subsystems();
+       smbd_init_subsystems;
 
-       smbd_process_init();
+       /* the event context is the top level structure in smbd. Everything else
+          should hang off that */
+       event_ctx = event_context_init(NULL);
 
        DEBUG(0,("Using %s process model\n", model));
-       server = server_service_startup(model, lp_server_services());
-       if (!server) {
-               DEBUG(0,("Starting Services failed.\n"));
+       status = server_service_startup(event_ctx, model, lp_server_services());
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
                return 1;
        }
 
-       /* wait for events */
-       event_loop_wait(server->event.ctx);
+       /* wait for events - this is where smbd sits for most of its
+          life */
+       event_loop_wait(event_ctx);
 
-       server_service_shutdown(server, "exit");
+       /* as everything hangs off this event context, freeing it
+          should initiate a clean shutdown of all services */
+       talloc_free(event_ctx);
 
        return 0;
 }
diff --git a/source4/smbd/server.h b/source4/smbd/server.h
deleted file mode 100644 (file)
index 6021df1..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-
-   Copyright (C) Stefan (metze) Metzmacher     2004
-   
-   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.
-   
-   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.
-   
-   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.
-*/
-
-#ifndef _SERVER_H
-#define _SERVER_H
-
-struct server_service;
-struct event_context;
-
-struct server_context {
-       struct {
-               struct event_context *ctx;
-       } event;
-
-       struct {
-               const struct model_ops *ops;
-       } model;
-
-       struct server_service *service_list;
-};
-
-/* size of listen() backlog in smbd */
-#define SERVER_LISTEN_BACKLOG 10
-
-/* the range of ports to try for dcerpc over tcp endpoints */
-#define SERVER_TCP_LOW_PORT  1024
-#define SERVER_TCP_HIGH_PORT 1300
-
-/* the default idle time of a service */
-#define SERVER_DEFAULT_IDLE_TIME 300
-
-#endif /* _SERVER_H */
index 2d532b638d532630bcfdbe0da62f8ae4e8b8ded1..ab377dc29b2ea43e292ec32f3466ec9c4b9f6a01 100644 (file)
@@ -3,7 +3,7 @@
 
    SERVER SERVICE code
 
-   Copyright (C) Andrew Tridgell 2003
+   Copyright (C) Andrew Tridgell 2003-2005
    Copyright (C) Stefan (metze) Metzmacher     2004
    
    This program is free software; you can redistribute it and/or modify
 */
 
 #include "includes.h"
-#include "events.h"
-#include "system/dir.h"
 #include "dlinklist.h"
 #include "process_model.h"
 
-struct server_context *server_service_startup(const char *model, const char **server_services)
-{
-       int i;
-       struct server_context *server;
-
-       if (!server_services) {
-               DEBUG(0,("server_service_startup: no endpoint servers configured\n"));
-               return NULL;
-       }
-
-       server = talloc_zero(NULL, struct server_context);
-       if (!server) {
-               return NULL;    
-       }
-
-       server->model.ops = process_model_startup(server, model);
-       if (!server->model.ops) {
-               DEBUG(0,("process_model_startup('%s') failed\n", model));
-               return NULL;
-       }
-
-       server->event.ctx = event_context_init(server);
-       if (!server->event.ctx) {
-               DEBUG(0,("event_context_init() failed\n"));
-               return NULL;
-       }
-
-       for (i=0;server_services[i];i++) {
-               const struct server_service_ops *service_ops;
-               struct server_service *service;
-
-               service_ops = server_service_byname(server_services[i]);
-               if (!service_ops) {
-                       DEBUG(0,("process_model_startup: failed to find server service = '%s'\n", server_services[i]));
-                       return NULL;
-               }
-
-               service = talloc_zero(server, struct server_service);
-               if (!service) {
-                       return NULL;
-               }
-
-               service->service.ops    = service_ops;
-               service->server         = server;
-
-               /* TODO: service_init() should return a result */
-               service->service.ops->service_init(service);
-
-               DLIST_ADD(server->service_list, service);
-       }
-
-       return server;
-}
-
-void server_service_shutdown(struct server_context *server, const char *reason)
-{
-       server->model.ops->model_exit(server, reason);
-}
-
 /*
-  setup a listen stream socket
-  if you pass *port == 0, then a port > 1024 is used
- */
-struct server_stream_socket *service_setup_stream_socket(struct server_service *service,
-                                                        const struct server_stream_ops *stream_ops,
-                                                        const char *family,
-                                                        const char *sock_addr,
-                                                        uint16_t *port)
-{
-       NTSTATUS status;
-       struct server_stream_socket *stream_socket;
-       struct socket_context *sock;
-       struct fd_event fde;
-       int i;
-
-       status = socket_create(family, SOCKET_TYPE_STREAM, &sock, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("Failed to open socket on %s:%u - %s\n",
-                       sock_addr, *port, nt_errstr(status)));
-               return NULL;
-       }
-
-       /* ready to listen */
-       status = socket_set_option(sock, "SO_KEEPALIVE SO_REUSEADDR=1", NULL);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("socket_set_option(socket_ctx, SO_KEEPALIVE, NULL): %s\n",
-                       nt_errstr(status)));
-               socket_destroy(sock);
-               return NULL;
-       }
-       status = socket_set_option(sock, lp_socket_options(), NULL);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("socket_set_option(socket_ctx, lp_socket_options(), NULL): %s\n",
-                       nt_errstr(status)));
-               socket_destroy(sock);
-               return NULL;
-       }
-
-       /* TODO: set socket ACL's here when they're implemented */
-
-       if (*port == 0) {
-               for (i=SERVER_TCP_LOW_PORT;i<= SERVER_TCP_HIGH_PORT;i++) {
-                       status = socket_listen(sock, sock_addr, i, SERVER_LISTEN_BACKLOG, 0);
-                       if (NT_STATUS_IS_OK(status)) {
-                               *port = i;
-                               break;
-                       }
-               }
-       } else {
-               status = socket_listen(sock, sock_addr, *port, SERVER_LISTEN_BACKLOG, 0);
-       }
-
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0,("Failed to listen on %s:%u - %s\n",
-                       sock_addr, *port, nt_errstr(status)));
-               socket_destroy(sock);
-               return NULL;
-       }
-
-       stream_socket = talloc_zero(service, struct server_stream_socket);
-       if (!stream_socket) {
-               DEBUG(0,("talloc(mem_ctx, struct server_stream_socket) failed\n"));
-               socket_destroy(sock);
-               return NULL;
-       }
-
-       /* we are only interested in read events on the listen socket */
-       fde.fd          = socket_get_fd(sock);
-       fde.flags       = EVENT_FD_READ;
-       fde.private     = stream_socket;
-       fde.handler     = server_accept_handler;
-
-       stream_socket->stream.ops       = stream_ops;
-       stream_socket->service          = service;
-       stream_socket->socket           = sock;
-       stream_socket->event.ctx        = service->server->event.ctx;
-       stream_socket->event.fde        = event_add_fd(stream_socket->event.ctx, 
-                                                      &fde, stream_socket);
-       if (!stream_socket->event.fde) {
-               socket_destroy(sock);
-               return NULL;
-       }
-
-       talloc_steal(stream_socket, sock);
-
-       if (stream_socket->stream.ops->socket_init) {
-               stream_socket->stream.ops->socket_init(stream_socket);
-       }
-
-       return stream_socket;
-}
-
-/*
-  destructor that handles necessary event context changes
- */
-static int server_connection_destructor(void *ptr)
-{
-       struct server_connection *conn = ptr;
-
-       if (conn->stream_socket && 
-           conn->stream_socket->stream.ops->close_connection) {
-               /* don't remove this! the stream service needs to free it's data
-                * before we destroy the server_connection
-                */
-               conn->stream_socket->stream.ops->close_connection(conn, "shutdown");
-        }
-
-       return 0;
-}
-
-struct server_connection *server_setup_connection(struct event_context *ev, 
-                                                 struct server_stream_socket *stream_socket, 
-                                                 struct socket_context *sock, 
-                                                 struct timeval t,
-                                                 servid_t server_id)
-{
-       struct fd_event fde;
-       struct timed_event idle;
-       struct server_connection *srv_conn;
-
-       srv_conn = talloc(stream_socket, struct server_connection);
-       if (!srv_conn) {
-               DEBUG(0,("talloc(mem_ctx, struct server_connection) failed\n"));
-               return NULL;
-       }
-
-       ZERO_STRUCTP(srv_conn);
-
-       fde.private     = srv_conn;
-       fde.fd          = socket_get_fd(sock);
-       fde.flags       = EVENT_FD_READ;
-       fde.handler     = server_io_handler;
-
-       idle.private    = srv_conn;
-       idle.next_event = timeval_add(&t, SERVER_DEFAULT_IDLE_TIME, 0);
-       idle.handler    = server_idle_handler;
-
-       srv_conn->event.ctx             = ev;
-       srv_conn->event.fde             = &fde;
-       srv_conn->event.idle            = &idle;
-       srv_conn->event.idle_time       = timeval_set(SERVER_DEFAULT_IDLE_TIME, 0);
-
-       srv_conn->stream_socket         = stream_socket;
-       srv_conn->socket                = sock;
-       srv_conn->connection.id         = server_id;
-
-       /* create a server context and add it to out event
-          handling */
-       stream_socket->stream.ops->accept_connection(srv_conn);
-
-       /* accpect_connection() of the service may changed idle.next_event */
-       srv_conn->event.fde     = event_add_fd(ev, &fde, srv_conn);
-       srv_conn->event.idle    = event_add_timed(ev, &idle, srv_conn);
-
-       talloc_set_destructor(srv_conn, server_connection_destructor);
-
-       if (!socket_check_access(sock, "smbd", lp_hostsallow(-1), lp_hostsdeny(-1))) {
-               server_terminate_connection(srv_conn, "denied by access rules");
-               return NULL;
-       }
-
-       /* setup to receive internal messages on this connection */
-       srv_conn->messaging.ctx = messaging_init(srv_conn, srv_conn->connection.id, ev);
-       if (!srv_conn->messaging.ctx) {
-               server_terminate_connection(srv_conn, "messaging_init() failed");
-               return NULL;
-       }
-
-       return srv_conn;
-}
+  a linked list of registered servers
+*/
+static struct registered_server {
+       struct registered_server *next, *prev;
+       const char *service_name;
+       NTSTATUS (*service_init)(struct event_context *, const struct model_ops *);
+} *registered_servers;
 
 /*
-  close the socket and shutdown a server_context
+  register a server service. 
 */
-void server_terminate_connection(struct server_connection *srv_conn, const char *reason)
-{
-       DEBUG(2,("server_terminate_connection\n"));
-       srv_conn->stream_socket->service->server->model.ops->terminate_connection(srv_conn, reason);
-}
-
-void server_accept_handler(struct event_context *ev, struct fd_event *fde, 
-                      struct timeval t, uint16_t flags)
+NTSTATUS register_server_service(const char *name,
+                                NTSTATUS (*service_init)(struct event_context *, const struct model_ops *))
 {
-       struct server_stream_socket *stream_socket = talloc_get_type(fde->private,
-                                                                    struct server_stream_socket);
-
-       stream_socket->service->server->model.ops->accept_connection(ev, fde, t, flags);
+       struct registered_server *srv;
+       srv = talloc(talloc_autofree_context(), struct registered_server);
+       NT_STATUS_HAVE_NO_MEMORY(srv);
+       srv->service_name = name;
+       srv->service_init = service_init;
+       DLIST_ADD_END(registered_servers, srv, struct registered_server *);
+       return NT_STATUS_OK;
 }
 
-void server_io_handler(struct event_context *ev, struct fd_event *fde, 
-                      struct timeval t, uint16_t flags)
-{
-       struct server_connection *conn = talloc_get_type(fde->private, 
-                                                        struct server_connection);
-
-       conn->event.idle->next_event = timeval_sum(&t,  &conn->event.idle_time);
-
-       if (flags & EVENT_FD_WRITE) {
-               conn->stream_socket->stream.ops->send_handler(conn, t, flags);
-               return;
-       }
-
-       if (flags & EVENT_FD_READ) {
-               conn->stream_socket->stream.ops->recv_handler(conn, t, flags);
-       }
-
-}
-
-void server_idle_handler(struct event_context *ev, struct timed_event *idle, 
-                        struct timeval t)
-{
-       struct server_connection *conn = talloc_get_type(idle->private, 
-                                                        struct server_connection);
-
-       /* Not all services provide an idle handler */
-       if (conn->stream_socket->stream.ops->idle_handler) {
-               conn->event.idle->next_event = timeval_sum(&t, &conn->event.idle_time);
-               conn->stream_socket->stream.ops->idle_handler(conn, t);
-       }
-}
-
-void server_terminate_task(struct server_task *task, const char *reason)
-{
-       task->service->server->model.ops->terminate_task(task, reason);
-       return;
-}
-
-void server_run_task(struct server_service *service, const struct server_task_ops *ops)
-{
-       struct server_task *task;
-
-       task = talloc_zero(service, struct server_task);
-       if (!task) {
-               return;
-       }
-       task->service           = service;
-       task->task.ops          = ops;
-
-       service->server->model.ops->create_task(task);
-       return;
-}
 
 /*
-  return the operations structure for a named backend of the specified type
+  initialise a server service
 */
-const struct server_service_ops *server_service_byname(const char *name)
+static NTSTATUS server_service_init(const char *name,
+                                   struct event_context *event_ctx,
+                                   const struct model_ops *model_ops)
 {
-       if (strcmp("smb",name)==0) {
-               return smbsrv_get_ops();
-       }
-       if (strcmp("rpc",name)==0) {
-               return dcesrv_get_ops();
-       }
-       if (strcmp("ldap",name)==0) {
-               return ldapsrv_get_ops();
-       }
-       if (strcmp("winbind",name)==0) {
-               return winbind_get_ops();
-       }
-       if (strcmp("winbind_task",name)==0) {
-               return winbind_task_get_ops();
+       struct registered_server *srv;
+       for (srv=registered_servers; srv; srv=srv->next) {
+               if (strcasecmp(name, srv->service_name) == 0) {
+                       return srv->service_init(event_ctx, model_ops);
+               }
        }
-       return NULL;
+       return NT_STATUS_INVALID_SYSTEM_SERVICE;
 }
 
-NTSTATUS register_server_service_ops(const void *_ops)
-{
-       return NT_STATUS_NOT_IMPLEMENTED;
-}
 
 /*
-  cleanup temporary files. This is the new alternative to
-  TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
-  efficient on unix systems due to the lack of scaling of the byte
-  range locking system. So instead of putting the burden on tdb to
-  cleanup tmp files, this function deletes them. 
+  startup all of our server services
 */
-void service_cleanup_tmp_files(void)
+NTSTATUS server_service_startup(struct event_context *event_ctx, 
+                               const char *model, const char **server_services)
 {
-       char *path;
-       DIR *dir;
-       struct dirent *de;
-       TALLOC_CTX *mem_ctx = talloc_init("service_cleanup_tmp_files");
+       int i;
+       const struct model_ops *model_ops;
 
-       path = smbd_tmp_path(mem_ctx, NULL);
+       if (!server_services) {
+               DEBUG(0,("server_service_startup: no endpoint servers configured\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
 
-       dir = opendir(path);
-       if (!dir) {
-               talloc_free(mem_ctx);
-               return;
+       model_ops = process_model_startup(event_ctx, model);
+       if (!model_ops) {
+               DEBUG(0,("process_model_startup('%s') failed\n", model));
+               return NT_STATUS_INTERNAL_ERROR;
        }
 
-       for (de=readdir(dir);de;de=readdir(dir)) {
-               char *fname = talloc_asprintf(mem_ctx, "%s/%s", path, de->d_name);
-               int ret = unlink(fname);
-               if (ret == -1 &&
-                   errno != ENOENT &&
-                   errno != EISDIR &&
-                   errno != EISDIR) {
-                       DEBUG(0,("Unabled to delete '%s' - %s\n", 
-                                fname, strerror(errno)));
-                       smb_panic("unable to cleanup tmp files");
-               }
-               talloc_free(fname);
+       for (i=0;server_services[i];i++) {
+               NTSTATUS status;
+
+               status = server_service_init(server_services[i], event_ctx, model_ops);
+               NT_STATUS_NOT_OK_RETURN(status);
        }
-       closedir(dir);
 
-       talloc_free(mem_ctx);
+       return NT_STATUS_OK;
 }
diff --git a/source4/smbd/service.h b/source4/smbd/service.h
deleted file mode 100644 (file)
index d5335b1..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-
-   SERVER SERVICE code
-
-   Copyright (C) Stefan (metze) Metzmacher     2004
-   
-   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.
-   
-   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.
-   
-   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.
-*/
-
-#ifndef _SERVER_SERVICE_H
-#define _SERVER_SERVICE_H
-
-struct event_context;
-struct model_ops;
-struct server_context;
-
-struct server_connection;
-struct server_service;
-
-/* modules can use the following to determine if the interface has changed
- * please increment the version number after each interface change
- * with a comment and maybe update struct process_model_critical_sizes.
- */
-/* version 1 - initial version - metze */
-#define SERVER_SERVICE_VERSION 1
-
-struct server_service_ops {
-       /* the name of the server_service */
-       const char *name;
-
-       /* called at startup when the server_service is selected */
-       void (*service_init)(struct server_service *service);   
-};
-
-struct server_stream_socket;
-
-struct server_stream_ops {
-       /* the name of the server_service */
-       const char *name;
-
-       /* called at startup when the server_service is selected */
-       void (*socket_init)(struct server_stream_socket *socket);
-
-       /* function to accept new connection */
-       void (*accept_connection)(struct server_connection *);
-
-       void (*recv_handler)(struct server_connection *, struct timeval, uint16_t);
-
-       void (*send_handler)(struct server_connection *, struct timeval, uint16_t);
-
-       /* function to be called when the server is idle */
-       void (*idle_handler)(struct server_connection *, struct timeval);
-
-       /* function to close a connection */
-       void (*close_connection)(struct server_connection *, const char *reason);
-};
-
-struct socket_context;
-
-struct server_stream_socket {
-       struct server_stream_socket *next,*prev;
-       struct {
-               const struct server_stream_ops *ops;
-               void *private_data;
-       } stream;
-
-       struct {
-               struct event_context *ctx;
-               struct fd_event *fde;
-       } event;
-
-       struct socket_context *socket;
-
-       struct server_service *service;
-};
-
-struct server_service {
-       struct server_service *next,*prev;
-       struct {
-               const struct server_service_ops *ops;
-               void *private_data;
-       } service;
-
-       struct server_context *server;
-};
-
-/* the concept of whether two operations are on the same server
-   connection or different connections is an important one in SMB, especially
-   for locking and share modes. We will use a servid_t to distinguish different
-   connections 
-
-   this means that (for example) a unique open file is distinguished by the triple
-   of 
-      servid_t server;
-      uint16   tid;
-      uint16   fnum;
-*/
-typedef uint32_t servid_t;
-
-struct server_connection {
-       struct server_connection *next,*prev;
-       struct {
-               void *private_data;
-               servid_t id;
-       } connection;
-
-       struct {
-               struct event_context *ctx;
-               struct fd_event *fde;
-               struct timed_event *idle;
-               struct timeval idle_time;
-       } event;
-
-       struct socket_context *socket;
-
-       struct server_stream_socket *stream_socket;
-
-       struct {
-               struct messaging_context *ctx;
-       } messaging;
-};
-
-struct server_task;
-
-struct server_task_ops {
-       /* the name of the server_task */
-       const char *name;
-
-       /* called at startup when the server_task is selected */
-       void (*task_init)(struct server_task *task);
-};
-
-struct server_task {
-       struct server_task *next,*prev;
-       struct {
-               const struct server_task_ops *ops;
-               void *private_data;
-               servid_t id;
-       } task;
-
-       struct {
-               struct event_context *ctx;
-       } event;
-
-       struct {
-               struct messaging_context *ctx;
-       } messaging;
-
-       struct server_service *service;
-};
-
-#endif /* _SERVER_SERVICE_H */
index 9c6f55a6c458c13076d8494037ac75d9b6428485..bef26040067cd397ff8b49077a91c0a8d093874a 100644 (file)
@@ -25,7 +25,7 @@
 enum {MY_PING=1000, MY_PONG, MY_EXIT};
 
 static void ping_message(struct messaging_context *msg, void *private, 
-                        uint32_t msg_type, servid_t src, DATA_BLOB *data)
+                        uint32_t msg_type, uint32_t src, DATA_BLOB *data)
 {
        NTSTATUS status;
        status = messaging_send(msg, src, MY_PONG, data);
@@ -35,14 +35,14 @@ static void ping_message(struct messaging_context *msg, void *private,
 }
 
 static void pong_message(struct messaging_context *msg, void *private, 
-                        uint32_t msg_type, servid_t src, DATA_BLOB *data)
+                        uint32_t msg_type, uint32_t src, DATA_BLOB *data)
 {
        int *count = private;
        (*count)++;
 }
 
 static void exit_message(struct messaging_context *msg, void *private, 
-                        uint32_t msg_type, servid_t src, DATA_BLOB *data)
+                        uint32_t msg_type, uint32_t src, DATA_BLOB *data)
 {
        talloc_free(private);
        exit(0);