diff options
-rw-r--r-- | source4/build/smb_build/main.pm | 1 | ||||
-rw-r--r-- | source4/include/structs.h | 2 | ||||
-rw-r--r-- | source4/lib/socket/socket_ipv4.c | 2 | ||||
-rw-r--r-- | source4/lib/socket/socket_ipv6.c | 2 | ||||
-rw-r--r-- | source4/libcli/nbt/libnbt.h | 8 | ||||
-rw-r--r-- | source4/libcli/nbt/namequery.c | 4 | ||||
-rw-r--r-- | source4/libcli/nbt/nbtsocket.c | 23 | ||||
-rw-r--r-- | source4/nbt_server/config.mk | 13 | ||||
-rw-r--r-- | source4/nbt_server/interfaces.c | 88 | ||||
-rw-r--r-- | source4/nbt_server/nbt_server.c | 85 | ||||
-rw-r--r-- | source4/nbt_server/nbt_server.h | 44 | ||||
-rw-r--r-- | source4/param/loadparm.c | 5 | ||||
-rw-r--r-- | source4/smbd/config.mk | 10 | ||||
-rw-r--r-- | source4/smbd/service_stream.c | 2 |
14 files changed, 285 insertions, 4 deletions
diff --git a/source4/build/smb_build/main.pm b/source4/build/smb_build/main.pm index af4220ec7b..cd776b54b9 100644 --- a/source4/build/smb_build/main.pm +++ b/source4/build/smb_build/main.pm @@ -41,6 +41,7 @@ sub smb_build_main($) "rpc_server/config.mk", "ldap_server/config.mk", "winbind/config.mk", + "nbt_server/config.mk", "libcli/auth/gensec.mk", "libcli/auth/config.mk", "libcli/ldap/config.mk", diff --git a/source4/include/structs.h b/source4/include/structs.h index 2fe069e949..0de876ca7c 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -157,3 +157,5 @@ struct stream_connection; struct task_server; struct model_ops; struct stream_server_ops; + +struct nbt_server; diff --git a/source4/lib/socket/socket_ipv4.c b/source4/lib/socket/socket_ipv4.c index aaa5ce0fa2..09a4b4a73a 100644 --- a/source4/lib/socket/socket_ipv4.c +++ b/source4/lib/socket/socket_ipv4.c @@ -139,6 +139,8 @@ static NTSTATUS ipv4_listen(struct socket_context *sock, struct ipv4_addr ip_addr; int ret; + socket_set_option(sock, "SO_REUSEADDR=1", NULL); + ip_addr = interpret_addr2(my_address); ZERO_STRUCT(my_addr); diff --git a/source4/lib/socket/socket_ipv6.c b/source4/lib/socket/socket_ipv6.c index 1dd7fe8e9d..f5cd756259 100644 --- a/source4/lib/socket/socket_ipv6.c +++ b/source4/lib/socket/socket_ipv6.c @@ -125,6 +125,8 @@ static NTSTATUS ipv6_tcp_listen(struct socket_context *sock, struct in6_addr ip_addr; int ret; + socket_set_option(sock, "SO_REUSEADDR=1", NULL); + ip_addr = interpret_addr6(my_address); ZERO_STRUCT(my_addr); diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index a7788f791b..82069f0390 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -90,6 +90,14 @@ struct nbt_name_socket { /* how many requests are waiting for a reply */ uint16_t num_pending; + + /* what to do with incoming request packets */ + struct { + void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, + const char *, int ); + void *private; + } incoming; + }; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 05d5e55491..6f549e6241 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -52,7 +52,7 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_type = NBT_QTYPE_NETBIOS; packet->questions[0].question_class = NBT_QCLASS_IP; - req = nbt_name_request_send(nbtsock, io->in.dest_addr, NBT_NAME_SERVICE_PORT, packet, + req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, timeval_current_ofs(io->in.timeout, 0), False); if (req == NULL) goto failed; @@ -142,7 +142,7 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_type = NBT_QTYPE_STATUS; packet->questions[0].question_class = NBT_QCLASS_IP; - req = nbt_name_request_send(nbtsock, io->in.dest_addr, NBT_NAME_SERVICE_PORT, packet, + req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet, timeval_current_ofs(io->in.timeout, 0), False); if (req == NULL) goto failed; diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 1eea77d356..f1964b7158 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -51,7 +51,8 @@ static int nbt_name_request_destructor(void *ptr) if (req->nbtsock->send_queue == NULL) { req->nbtsock->fde->flags &= ~EVENT_FD_WRITE; } - if (req->nbtsock->num_pending == 0) { + if (req->nbtsock->num_pending == 0 && + req->nbtsock->incoming.handler == NULL) { req->nbtsock->fde->flags &= ~EVENT_FD_READ; } return 0; @@ -170,6 +171,9 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } if (!(packet->operation & NBT_FLAG_REPLY)) { + if (nbtsock->incoming.handler) { + nbtsock->incoming.handler(nbtsock, packet, src_addr, src_port); + } talloc_free(tmp_ctx); return; } @@ -375,3 +379,20 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) } return req->status; } + + +/* + setup a handler for incoming requests +*/ +NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, + void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, + const char *, int ), + void *private) +{ + nbtsock->incoming.handler = handler; + nbtsock->incoming.private = private; + nbtsock->fde->flags |= EVENT_FD_READ; + socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); + return NT_STATUS_OK; +} + diff --git a/source4/nbt_server/config.mk b/source4/nbt_server/config.mk new file mode 100644 index 0000000000..093cb61864 --- /dev/null +++ b/source4/nbt_server/config.mk @@ -0,0 +1,13 @@ +# NBTD server subsystem + +####################### +# Start SUBSYSTEM NBTD +[SUBSYSTEM::NBTD] +INIT_OBJ_FILES = \ + nbt_server/nbt_server.o +ADD_OBJ_FILES = \ + nbt_server/interfaces.o +REQUIRED_SUBSYSTEMS = \ + LIBCLI_NBT +# End SUBSYSTEM SMB +####################### diff --git a/source4/nbt_server/interfaces.c b/source4/nbt_server/interfaces.c new file mode 100644 index 0000000000..18893e179b --- /dev/null +++ b/source4/nbt_server/interfaces.c @@ -0,0 +1,88 @@ +/* + Unix SMB/CIFS implementation. + + NBT interface handling + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + +#include "includes.h" +#include "dlinklist.h" +#include "nbt_server/nbt_server.h" +#include "smbd/service_task.h" +#include "libcli/nbt/libnbt.h" + +/* + start listening on the given address +*/ +static NTSTATUS nbt_add_socket(struct nbt_server *nbtsrv, + const char *address, const char *bcast) +{ + struct nbt_interface *iface; + NTSTATUS status; + + iface = talloc(nbtsrv, struct nbt_interface); + NT_STATUS_HAVE_NO_MEMORY(iface); + + iface->nbtsrv = nbtsrv; + iface->bcast_address = talloc_steal(iface, bcast); + iface->ip_address = talloc_steal(iface, address); + + iface->nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx); + NT_STATUS_HAVE_NO_MEMORY(iface->ip_address); + + status = socket_listen(iface->nbtsock->sock, address, lp_nbt_port(), 0, 0); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to bind to %s:%d - %s\n", + address, lp_nbt_port(), nt_errstr(status))); + talloc_free(iface); + return status; + } + + DLIST_ADD(nbtsrv->interfaces, iface); + + return NT_STATUS_OK; +} + + +/* + setup our listening sockets on the configured network interfaces +*/ +NTSTATUS nbt_startup_interfaces(struct nbt_server *nbtsrv) +{ + int num_interfaces = iface_count(); + int i; + TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv); + NTSTATUS status; + + status = nbt_add_socket(nbtsrv, + talloc_strdup(tmp_ctx, "0.0.0.0"), + talloc_strdup(tmp_ctx, "255.255.255.255")); + NT_STATUS_NOT_OK_RETURN(status); + + for (i=0; i<num_interfaces; i++) { + const char *address = talloc_strdup(tmp_ctx, sys_inet_ntoa(*iface_n_ip(i))); + const char *bcast = talloc_strdup(tmp_ctx, sys_inet_ntoa(*iface_n_bcast(i))); + + status = nbt_add_socket(nbtsrv, address, bcast); + NT_STATUS_NOT_OK_RETURN(status); + } + + talloc_free(tmp_ctx); + + return NT_STATUS_OK; +} diff --git a/source4/nbt_server/nbt_server.c b/source4/nbt_server/nbt_server.c new file mode 100644 index 0000000000..19dabdfa51 --- /dev/null +++ b/source4/nbt_server/nbt_server.c @@ -0,0 +1,85 @@ +/* + Unix SMB/CIFS implementation. + + NBT server task + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + +#include "includes.h" +#include "events.h" +#include "libcli/nbt/libnbt.h" +#include "smbd/service_task.h" +#include "nbt_server/nbt_server.h" + + +/* + receive an incoming request +*/ +static void nbt_request_handler(struct nbt_name_socket *nbtsock, + struct nbt_name_packet *packet, + const char *src_address, int src_port) +{ + struct nbt_interface *iface = talloc_get_type(nbtsock->incoming.private, + struct nbt_interface); + DEBUG(0,("nbtd request from %s:%d\n", src_address, src_port)); + + NDR_PRINT_DEBUG(nbt_name_packet, packet); +} + + +/* + startup the nbtd task +*/ +static void nbtd_task_init(struct task_server *task) +{ + struct nbt_server *nbtsrv; + struct nbt_interface *iface; + + nbtsrv = talloc(task, struct nbt_server); + if (nbtsrv == NULL) { + task_terminate(task, "nbtd: out of memory"); + return; + } + + nbtsrv->task = task; + nbtsrv->interfaces = NULL; + + nbt_startup_interfaces(nbtsrv); + + for (iface=nbtsrv->interfaces;iface;iface=iface->next) { + nbt_set_incoming_handler(iface->nbtsock, nbt_request_handler, iface); + } +} + + +/* + initialise the nbt server + */ +static NTSTATUS nbtd_init(struct event_context *event_ctx, const struct model_ops *model_ops) +{ + return task_server_startup(event_ctx, model_ops, nbtd_task_init); +} + + +/* + register ourselves as a available server +*/ +NTSTATUS server_service_nbtd_init(void) +{ + return register_server_service("nbt", nbtd_init); +} diff --git a/source4/nbt_server/nbt_server.h b/source4/nbt_server/nbt_server.h new file mode 100644 index 0000000000..9ef510fbb2 --- /dev/null +++ b/source4/nbt_server/nbt_server.h @@ -0,0 +1,44 @@ +/* + Unix SMB/CIFS implementation. + + NBT server structures + + Copyright (C) Andrew Tridgell 2005 + + 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. +*/ + + +/* a list of network interfaces we are listening on */ +struct nbt_interface { + struct nbt_interface *next, *prev; + const char *ip_address; + const char *bcast_address; + struct nbt_name_socket *nbtsock; + struct nbt_server *nbtsrv; +}; + + +/* + top level context structure for the nbt server +*/ +struct nbt_server { + struct task_server *task; + + struct nbt_interface *interfaces; +}; + + + diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 8380fccaf7..d5a8928c3d 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -61,6 +61,7 @@ #include "system/printing.h" #include "librpc/gen_ndr/ndr_svcctl.h" #include "librpc/gen_ndr/ndr_samr.h" +#include "librpc/gen_ndr/ndr_nbt.h" #include "dlinklist.h" BOOL in_client = False; /* Not in the client by default */ @@ -233,6 +234,7 @@ typedef struct int winbind_cache_time; int iLockSpinCount; int iLockSpinTime; + int nbt_port; char *socket_options; BOOL bDNSproxy; BOOL bWINSsupport; @@ -612,6 +614,7 @@ static struct parm_struct parm_table[] = { {"Protocol Options", P_SEP, P_SEPARATOR}, {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER}, {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER}, {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER}, @@ -1044,6 +1047,7 @@ static void init_globals(void) do_parameter("use spnego", "True"); do_parameter("smb ports", SMB_PORTS); + do_parameter("nbt port", "137"); do_parameter("nt status support", "True"); } @@ -1141,6 +1145,7 @@ static const char *lp_string(const char *s) int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);} FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports) +FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port) FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset) FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset) FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset) diff --git a/source4/smbd/config.mk b/source4/smbd/config.mk index 4d5e929c79..39697205f6 100644 --- a/source4/smbd/config.mk +++ b/source4/smbd/config.mk @@ -40,6 +40,16 @@ REQUIRED_SUBSYSTEMS = \ # End MODULE server_ldap ################################################ +################################################ +# Start MODULE server_service_nbtd +[MODULE::server_service_nbtd] +INIT_FUNCTION = server_service_nbtd_init +SUBSYSTEM = SERVER_SERVICE +REQUIRED_SUBSYSTEMS = \ + NBTD +# End MODULE server_service_nbtd +################################################ + ####################### # Start SUBSYSTEM SERVICE [SUBSYSTEM::SERVER_SERVICE] diff --git a/source4/smbd/service_stream.c b/source4/smbd/service_stream.c index 0d29c9fcb8..1662e9005f 100644 --- a/source4/smbd/service_stream.c +++ b/source4/smbd/service_stream.c @@ -170,7 +170,7 @@ NTSTATUS stream_setup_socket(struct event_context *event_context, talloc_steal(stream_socket, stream_socket->sock); /* ready to listen */ - status = socket_set_option(stream_socket->sock, "SO_KEEPALIVE SO_REUSEADDR=1", NULL); + status = socket_set_option(stream_socket->sock, "SO_KEEPALIVE", NULL); NT_STATUS_NOT_OK_RETURN(status); status = socket_set_option(stream_socket->sock, lp_socket_options(), NULL); |