summaryrefslogtreecommitdiff
path: root/source4/smb_server
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-01-30 00:54:57 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:09:22 -0500
commit55d4d36993293fee914a009f1d8f05810e347f2b (patch)
tree587a9bafd1c8df901aad8766acb0fe9ef4c3d8c0 /source4/smb_server
parent5540449f1cd9d9a6efab59f2bf47be4e1487ffc2 (diff)
downloadsamba-55d4d36993293fee914a009f1d8f05810e347f2b.tar.gz
samba-55d4d36993293fee914a009f1d8f05810e347f2b.tar.bz2
samba-55d4d36993293fee914a009f1d8f05810e347f2b.zip
r5102: This is a major simplification of the logic for controlling top level
servers in smbd. The old code still contained a fairly bit of legacy from the time when smbd was only handling SMB connection. The new code gets rid of all of the smb_server specific code in smbd/, and creates a much simpler infrastructures for new server code. Major changes include: - simplified the process model code a lot. - got rid of the top level server and service structures completely. The top level context is now the event_context. This got rid of service.h and server.h completely (they were the most confusing parts of the old code) - added service_stream.[ch] for the helper functions that are specific to stream type services (services that handle streams, and use a logically separate process per connection) - got rid of the builtin idle_handler code in the service logic, as none of the servers were using it, and it can easily be handled by a server in future by adding its own timed_event to the event context. - fixed some major memory leaks in the rpc server code. - added registration of servers, rather than hard coding our list of possible servers. This allows for servers as modules in the future. - temporarily disabled the winbind code until I add the helper functions for that type of server - added error checking on service startup. If a configured server fails to startup then smbd doesn't startup. - cleaned up the command line handling in smbd, removing unused options (This used to be commit cf6a46c3cbde7b1eb1b86bd3882b953a2de3a42e)
Diffstat (limited to 'source4/smb_server')
-rw-r--r--source4/smb_server/conn.c1
-rw-r--r--source4/smb_server/negprot.c8
-rw-r--r--source4/smb_server/request.c1
-rw-r--r--source4/smb_server/service.c1
-rw-r--r--source4/smb_server/sesssetup.c1
-rw-r--r--source4/smb_server/smb_server.c165
-rw-r--r--source4/smb_server/smb_server.h2
7 files changed, 68 insertions, 111 deletions
diff --git a/source4/smb_server/conn.c b/source4/smb_server/conn.c
index 427add0aa2..45c5376e25 100644
--- a/source4/smb_server/conn.c
+++ b/source4/smb_server/conn.c
@@ -23,6 +23,7 @@
#include "system/filesys.h"
#include "dlinklist.h"
#include "smb_server/smb_server.h"
+#include "smbd/service_stream.h"
/****************************************************************************
diff --git a/source4/smb_server/negprot.c b/source4/smb_server/negprot.c
index 4af8fed53b..8223f66dc7 100644
--- a/source4/smb_server/negprot.c
+++ b/source4/smb_server/negprot.c
@@ -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 {
diff --git a/source4/smb_server/request.c b/source4/smb_server/request.c
index c2aca04661..26988bf205 100644
--- a/source4/smb_server/request.c
+++ b/source4/smb_server/request.c
@@ -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 */
diff --git a/source4/smb_server/service.c b/source4/smb_server/service.c
index d4386ca77b..180deaf8c5 100644
--- a/source4/smb_server/service.c
+++ b/source4/smb_server/service.c
@@ -20,6 +20,7 @@
#include "includes.h"
#include "smb_server/smb_server.h"
+#include "smbd/service_stream.h"
diff --git a/source4/smb_server/sesssetup.c b/source4/smb_server/sesssetup.c
index eb6c8b9647..dc3a60874a 100644
--- a/source4/smb_server/sesssetup.c
+++ b/source4/smb_server/sesssetup.c
@@ -25,6 +25,7 @@
#include "version.h"
#include "auth/auth.h"
#include "smb_server/smb_server.h"
+#include "smbd/service_stream.h"
/*
diff --git a/source4/smb_server/smb_server.c b/source4/smb_server/smb_server.c
index 394923635d..1537bf6a47 100644
--- a/source4/smb_server/smb_server.c
+++ b/source4/smb_server/smb_server.c
@@ -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);
}
diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h
index 2b1ca87cb9..02070f2b13 100644
--- a/source4/smb_server/smb_server.h
+++ b/source4/smb_server/smb_server.h
@@ -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;