summaryrefslogtreecommitdiff
path: root/source4/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source4/smbd')
-rw-r--r--source4/smbd/process.c11
-rw-r--r--source4/smbd/process_single.c24
-rw-r--r--source4/smbd/process_standard.c41
-rw-r--r--source4/smbd/process_thread.c44
-rw-r--r--source4/smbd/rewrite.c3
-rw-r--r--source4/smbd/server.c70
6 files changed, 150 insertions, 43 deletions
diff --git a/source4/smbd/process.c b/source4/smbd/process.c
index db145d0a26..b5138ac971 100644
--- a/source4/smbd/process.c
+++ b/source4/smbd/process.c
@@ -670,8 +670,8 @@ void server_terminate(struct server_context *smb)
/*
called when a SMB socket becomes readable
*/
-static void smbd_read_handler(struct event_context *ev, struct fd_event *fde,
- time_t t, uint16 flags)
+void smbd_read_handler(struct event_context *ev, struct fd_event *fde,
+ time_t t, uint16 flags)
{
struct request_context *req;
struct server_context *smb = fde->private;
@@ -713,7 +713,8 @@ void smbd_process_async(struct server_context *smb)
initialise a server_context from a open socket and register a event handler
for reading from that socket
*/
-void init_smbsession(struct event_context *ev, struct model_ops *model_ops, int fd)
+void init_smbsession(struct event_context *ev, struct model_ops *model_ops, int fd,
+ void (*read_handler)(struct event_context *, struct fd_event *, time_t, uint16))
{
struct server_context *smb;
TALLOC_CTX *mem_ctx;
@@ -757,14 +758,14 @@ void init_smbsession(struct event_context *ev, struct model_ops *model_ops, int
/* setup a event handler for this socket. We are initially
only interested in reading from the socket */
fde.fd = fd;
- fde.handler = smbd_read_handler;
+ fde.handler = read_handler;
fde.private = smb;
fde.flags = EVENT_FD_READ;
event_add_fd(ev, &fde);
/* setup the DCERPC server subsystem */
- dcesrv_init(smb);
+ dcesrv_init(&smb->dcesrv);
}
diff --git a/source4/smbd/process_single.c b/source4/smbd/process_single.c
index e6bb9b6c9c..a19577b3cf 100644
--- a/source4/smbd/process_single.c
+++ b/source4/smbd/process_single.c
@@ -49,11 +49,32 @@ static void accept_connection(struct event_context *ev, struct fd_event *fde, ti
/* create a smb server context and add it to out event
handling */
- init_smbsession(ev, model_ops, accepted_fd);
+ init_smbsession(ev, model_ops, accepted_fd, smbd_read_handler);
/* return to event handling */
}
+
+/*
+ called when a rpc listening socket becomes readable
+*/
+static void accept_rpc_connection(struct event_context *ev, struct fd_event *fde, time_t t, uint16 flags)
+{
+ int accepted_fd;
+ struct sockaddr addr;
+ socklen_t in_addrlen = sizeof(addr);
+
+ /* accept an incoming connection. */
+ accepted_fd = accept(fde->fd,&addr,&in_addrlen);
+ if (accepted_fd == -1) {
+ DEBUG(0,("accept_connection_single: accept: %s\n",
+ strerror(errno)));
+ return;
+ }
+
+ init_rpc_session(ev, fde->private, accepted_fd);
+}
+
/* called when a SMB connection goes down */
static void terminate_connection(struct server_context *server, const char *reason)
{
@@ -77,6 +98,7 @@ void process_model_single_init(void)
/* fill in all the operations */
ops.model_startup = model_startup;
ops.accept_connection = accept_connection;
+ ops.accept_rpc_connection = accept_rpc_connection;
ops.terminate_connection = terminate_connection;
ops.exit_server = NULL;
ops.get_id = get_id;
diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c
index f12784bc79..507c179a26 100644
--- a/source4/smbd/process_standard.c
+++ b/source4/smbd/process_standard.c
@@ -59,7 +59,8 @@ static void accept_connection(struct event_context *ev, struct fd_event *fde, ti
/* Child code ... */
/* close all the listening sockets */
- event_remove_fd_all_handler(ev, accept_connection);
+ event_remove_fd_all_handler(ev, model_ops->accept_connection);
+ event_remove_fd_all_handler(ev, model_ops->accept_rpc_connection);
/* tdb needs special fork handling */
if (tdb_reopen_all() == -1) {
@@ -72,11 +73,46 @@ static void accept_connection(struct event_context *ev, struct fd_event *fde, ti
/* initialize new process */
smbd_process_init();
- init_smbsession(ev, model_ops, accepted_fd);
+ init_smbsession(ev, model_ops, accepted_fd, smbd_read_handler);
/* return to the event loop */
}
+/*
+ called when a rpc listening socket becomes readable
+*/
+static void accept_rpc_connection(struct event_context *ev, struct fd_event *fde, time_t t, uint16 flags)
+{
+ int accepted_fd;
+ struct sockaddr addr;
+ socklen_t in_addrlen = sizeof(addr);
+ pid_t pid;
+
+ accepted_fd = accept(fde->fd,&addr,&in_addrlen);
+ if (accepted_fd == -1) {
+ DEBUG(0,("accept_connection_standard: accept: %s\n",
+ strerror(errno)));
+ return;
+ }
+
+ pid = fork();
+
+ if (pid != 0) {
+ /* parent or error code ... */
+ close(accepted_fd);
+ /* go back to the event loop */
+ return;
+ }
+
+ /* Child code ... */
+
+ /* close all the listening sockets */
+ event_remove_fd_all_handler(ev, accept_connection);
+ event_remove_fd_all_handler(ev, accept_rpc_connection);
+
+ init_rpc_session(ev, fde->private, accepted_fd);
+}
+
/* called when a SMB connection goes down */
static void terminate_connection(struct server_context *server, const char *reason)
{
@@ -102,6 +138,7 @@ void process_model_standard_init(void)
/* fill in all the operations */
ops.model_startup = model_startup;
ops.accept_connection = accept_connection;
+ ops.accept_rpc_connection = accept_rpc_connection;
ops.terminate_connection = terminate_connection;
ops.get_id = get_id;
diff --git a/source4/smbd/process_thread.c b/source4/smbd/process_thread.c
index 9c312e0d1f..634e826395 100644
--- a/source4/smbd/process_thread.c
+++ b/source4/smbd/process_thread.c
@@ -45,7 +45,8 @@ static int get_id(struct request_context *req)
/*
called when a listening socket becomes readable
*/
-static void accept_connection(struct event_context *ev, struct fd_event *fde, time_t t, uint16 flags)
+static void accept_connection(struct event_context *ev, struct fd_event *fde,
+ time_t t, uint16 flags)
{
int accepted_fd, rc;
struct sockaddr addr;
@@ -71,7 +72,45 @@ static void accept_connection(struct event_context *ev, struct fd_event *fde, ti
*/
ev = event_context_init();
MUTEX_LOCK_BY_ID(MUTEX_SMBD);
- init_smbsession(ev, model_ops, accepted_fd);
+ init_smbsession(ev, model_ops, accepted_fd, smbd_read_handler);
+ MUTEX_UNLOCK_BY_ID(MUTEX_SMBD);
+
+ pthread_attr_init(&thread_attr);
+ pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
+ rc = pthread_create(&thread_id, &thread_attr, &connection_thread, ev);
+ 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, accepted_fd));
+ } else {
+ DEBUG(0,("accept_connection_thread: thread create failed for fd=%d, rc=%d\n", accepted_fd, rc));
+ }
+}
+
+
+/*
+ called when a rpc listening socket becomes readable
+*/
+static void accept_rpc_connection(struct event_context *ev, struct fd_event *fde, time_t t, uint16 flags)
+{
+ int accepted_fd, rc;
+ struct sockaddr addr;
+ socklen_t in_addrlen = sizeof(addr);
+ pthread_t thread_id;
+ pthread_attr_t thread_attr;
+
+ /* accept an incoming connection */
+ accepted_fd = accept(fde->fd,&addr,&in_addrlen);
+
+ if (accepted_fd == -1) {
+ DEBUG(0,("accept_connection_thread: accept: %s\n",
+ strerror(errno)));
+ return;
+ }
+
+ ev = event_context_init();
+ MUTEX_LOCK_BY_ID(MUTEX_SMBD);
+ init_rpcsession(ev, fde->private, accepted_fd);
MUTEX_UNLOCK_BY_ID(MUTEX_SMBD);
pthread_attr_init(&thread_attr);
@@ -416,6 +455,7 @@ void process_model_thread_init(void)
/* fill in all the operations */
ops.model_startup = model_startup;
ops.accept_connection = accept_connection;
+ ops.accept_rpc_connection = accept_rpc_connection;
ops.terminate_connection = terminate_connection;
ops.exit_server = NULL;
ops.get_id = get_id;
diff --git a/source4/smbd/rewrite.c b/source4/smbd/rewrite.c
index 18ff62e9dc..5e30db1192 100644
--- a/source4/smbd/rewrite.c
+++ b/source4/smbd/rewrite.c
@@ -25,9 +25,6 @@ void load_printers(void)
void file_init(void)
{}
-void init_rpc_pipe_hnd(void)
-{}
-
BOOL init_oplocks(void)
{ return True; }
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index 65ead2f4ce..35e50602fa 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -34,48 +34,56 @@ void exit_server(struct server_context *smb, const char *reason)
/*
+ setup a single listener of any type
+ */
+static void setup_listen(struct event_context *events,
+ struct model_ops *model_ops,
+ void (*accept_handler)(struct event_context *,struct fd_event *,time_t,uint16),
+ struct in_addr *ifip, unsigned port)
+{
+ struct fd_event fde;
+ fde.fd = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
+ if (fde.fd == -1) {
+ DEBUG(0,("Failed to open socket on %s:%u - %s\n",
+ inet_ntoa(*ifip), port, strerror(errno)));
+ return;
+ }
+
+ /* ready to listen */
+ set_socket_options(fde.fd, "SO_KEEPALIVE");
+ set_socket_options(fde.fd, lp_socket_options());
+
+ if (listen(fde.fd, SMBD_LISTEN_BACKLOG) == -1) {
+ DEBUG(0,("Failed to listen on %s:%d - %s\n",
+ inet_ntoa(*ifip), port, strerror(errno)));
+ close(fde.fd);
+ return;
+ }
+
+ /* we are only interested in read events on the listen socket */
+ fde.flags = EVENT_FD_READ;
+ fde.private = model_ops;
+ fde.handler = accept_handler;
+
+ event_add_fd(events, &fde);
+}
+
+/*
add a socket address to the list of events, one event per port
*/
static void add_socket(struct event_context *events,
struct model_ops *model_ops,
struct in_addr *ifip)
{
- char *ports = lp_smb_ports();
char *ptr, *tok;
const char *delim = ", ";
- for (tok=strtok_r(ports, delim, &ptr);
+ for (tok=strtok_r(lp_smb_ports(), delim, &ptr);
tok;
tok=strtok_r(NULL, delim, &ptr)) {
unsigned port = atoi(tok);
- struct fd_event fde;
-
if (port == 0) continue;
-
- fde.fd = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
- if (fde.fd == -1) {
- DEBUG(0,("Failed to open socket on %s:%u - %s\n",
- inet_ntoa(*ifip), port, strerror(errno)));
- continue;
- }
-
- /* ready to listen */
- set_socket_options(fde.fd, "SO_KEEPALIVE");
- set_socket_options(fde.fd, lp_socket_options());
-
- if (listen(fde.fd, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("Failed to listen on %s:%d - %s\n",
- inet_ntoa(*ifip), port, strerror(errno)));
- close(fde.fd);
- continue;
- }
-
- /* we are only interested in read events on the listen socket */
- fde.flags = EVENT_FD_READ;
- fde.private = model_ops;
- fde.handler = model_ops->accept_connection;
-
- event_add_fd(events, &fde);
+ setup_listen(events, model_ops, model_ops->accept_connection, ifip, port);
}
}
@@ -170,7 +178,6 @@ static BOOL init_structs(void)
{
init_names();
file_init();
- init_rpc_pipe_hnd();
secrets_init();
/* we want to re-seed early to prevent time delays causing
@@ -202,6 +209,9 @@ static void setup_process_model(struct event_context *events,
/* now setup the listening sockets, adding
event handlers to the events structure */
open_sockets_smbd(events, ops);
+
+ /* setup any sockets we need to listen on for RPC over TCP */
+ open_sockets_rpc(events, ops);
}
/****************************************************************************