summaryrefslogtreecommitdiffstats
path: root/source4/nbt_server
diff options
context:
space:
mode:
Diffstat (limited to 'source4/nbt_server')
-rw-r--r--source4/nbt_server/dgram/request.c56
-rw-r--r--source4/nbt_server/interfaces.c29
-rw-r--r--source4/nbt_server/nbt_server.c143
-rw-r--r--source4/nbt_server/nbt_server.h2
-rw-r--r--source4/nbt_server/wins/winsdb.c5
-rw-r--r--source4/nbt_server/wins/winsserver.c3
-rw-r--r--source4/nbt_server/wscript_build2
7 files changed, 234 insertions, 6 deletions
diff --git a/source4/nbt_server/dgram/request.c b/source4/nbt_server/dgram/request.c
index ea2b6e8..7614514 100644
--- a/source4/nbt_server/dgram/request.c
+++ b/source4/nbt_server/dgram/request.c
@@ -27,6 +27,11 @@
#include "nbt_server/dgram/proto.h"
#include "librpc/gen_ndr/ndr_nbt.h"
#include "param/param.h"
+#include "lib/util/util_str_escape.h"
+#include "lib/util/util_net.h"
+#include "../source3/include/fstring.h"
+#include "../source3/libsmb/nmblib.h"
+#include "../source3/libsmb/unexpected.h"
/*
a list of mailslots that we have static handlers for
@@ -51,8 +56,55 @@ void dgram_request_handler(struct nbt_dgram_socket *dgmsock,
struct nbt_dgram_packet *packet,
struct socket_address *src)
{
- DEBUG(0,("General datagram request from %s:%d\n", src->addr, src->port));
- NDR_PRINT_DEBUG(nbt_dgram_packet, packet);
+ struct nbtd_interface *iface =
+ talloc_get_type_abort(dgmsock->incoming.private_data,
+ struct nbtd_interface);
+ struct nbtd_server *nbtsrv = iface->nbtsrv;
+ const char *mailslot_name = NULL;
+ struct packet_struct *pstruct = NULL;
+ DATA_BLOB blob = { .length = 0, };
+ enum ndr_err_code ndr_err;
+
+ mailslot_name = dgram_mailslot_name(packet);
+ if (mailslot_name != NULL) {
+ DBG_DEBUG("Unexpected mailslot[%s] datagram request from %s:%d\n",
+ log_escape(packet, mailslot_name),
+ src->addr, src->port);
+ } else {
+ DBG_DEBUG("Unexpected general datagram request from %s:%d\n",
+ src->addr, src->port);
+ }
+
+ if (CHECK_DEBUGLVL(DBGLVL_DEBUG)) {
+ NDR_PRINT_DEBUG(nbt_dgram_packet, packet);
+ }
+
+ /*
+ * For now we only pass DGRAM_DIRECT_UNIQUE
+ * messages via nb_packet_dispatch() to
+ * nbtsrv->unexpected_server
+ */
+ if (packet->msg_type != DGRAM_DIRECT_UNIQUE) {
+ return;
+ }
+
+ ndr_err = ndr_push_struct_blob(&blob, packet, packet,
+ (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DBG_ERR("ndr_push_nbt_dgram_packet - %s\n",
+ ndr_errstr(ndr_err));
+ return;
+ }
+
+ pstruct = parse_packet((char *)blob.data,
+ blob.length,
+ DGRAM_PACKET,
+ interpret_addr2(src->addr),
+ src->port);
+ if (pstruct != NULL) {
+ nb_packet_dispatch(nbtsrv->unexpected_server, pstruct);
+ free_packet(pstruct);
+ }
}
diff --git a/source4/nbt_server/interfaces.c b/source4/nbt_server/interfaces.c
index b946a1d..0888c1b 100644
--- a/source4/nbt_server/interfaces.c
+++ b/source4/nbt_server/interfaces.c
@@ -31,6 +31,9 @@
#include "param/param.h"
#include "lib/util/util_net.h"
#include "lib/util/idtree.h"
+#include "../source3/include/fstring.h"
+#include "../source3/libsmb/nmblib.h"
+#include "../source3/libsmb/unexpected.h"
/*
receive an incoming request and dispatch it to the right place
@@ -115,7 +118,33 @@ static void nbtd_unexpected_handler(struct nbt_name_socket *nbtsock,
}
if (!req) {
+ struct packet_struct *pstruct = NULL;
+ DATA_BLOB blob = { .length = 0, };
+ enum ndr_err_code ndr_err;
+
+ /*
+ * Here we have NBT_FLAG_REPLY
+ */
DEBUG(10,("unexpected from src[%s] unable to redirected\n", src->addr));
+
+ ndr_err = ndr_push_struct_blob(&blob, packet, packet,
+ (ndr_push_flags_fn_t)ndr_push_nbt_name_packet);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DBG_ERR("ndr_push_nbt_name_packet - %s\n",
+ ndr_errstr(ndr_err));
+ return;
+ }
+
+ pstruct = parse_packet((char *)blob.data,
+ blob.length,
+ NMB_PACKET,
+ interpret_addr2(src->addr),
+ src->port);
+ if (pstruct != NULL) {
+ nb_packet_dispatch(nbtsrv->unexpected_server, pstruct);
+ free_packet(pstruct);
+ }
+
return;
}
diff --git a/source4/nbt_server/nbt_server.c b/source4/nbt_server/nbt_server.c
index 6d28bbd..c3f9fac 100644
--- a/source4/nbt_server/nbt_server.c
+++ b/source4/nbt_server/nbt_server.c
@@ -29,9 +29,113 @@
#include "auth/auth.h"
#include "dsdb/samdb/samdb.h"
#include "param/param.h"
+#include "dynconfig/dynconfig.h"
+#include "lib/util/pidfile.h"
+#include "lib/util/util_net.h"
+#include "lib/socket/socket.h"
+#include "../source3/include/fstring.h"
+#include "../source3/libsmb/nmblib.h"
+#include "../source3/libsmb/unexpected.h"
+#include "../source3/lib/util_procid.h"
NTSTATUS server_service_nbtd_init(TALLOC_CTX *);
+static void nbtd_server_msg_send_packet(struct imessaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id src,
+ size_t num_fds,
+ int *fds,
+ DATA_BLOB *data)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct nbtd_server *nbtsrv =
+ talloc_get_type_abort(private_data,
+ struct nbtd_server);
+ struct packet_struct *p = (struct packet_struct *)data->data;
+ struct sockaddr_storage ss;
+ struct socket_address *dst = NULL;
+ struct nbtd_interface *iface = NULL;
+ char buf[1024] = { 0, };
+ DATA_BLOB blob = { .length = 0, };
+
+ DBG_DEBUG("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src));
+
+ if (data->length != sizeof(struct packet_struct)) {
+ DBG_WARNING("Discarding invalid packet length from %u\n",
+ (unsigned int)procid_to_pid(&src));
+ TALLOC_FREE(frame);
+ return;
+ }
+
+ if ((p->packet_type != NMB_PACKET) &&
+ (p->packet_type != DGRAM_PACKET)) {
+ DBG_WARNING("Discarding invalid packet type from %u: %d\n",
+ (unsigned int)procid_to_pid(&src), p->packet_type);
+ TALLOC_FREE(frame);
+ return;
+ }
+
+ if (p->packet_type == DGRAM_PACKET) {
+ p->port = 138;
+ }
+
+ in_addr_to_sockaddr_storage(&ss, p->ip);
+ dst = socket_address_from_sockaddr_storage(frame, &ss, p->port);
+ if (dst == NULL) {
+ TALLOC_FREE(frame);
+ return;
+ }
+ if (p->port == 0) {
+ DBG_WARNING("Discarding packet with missing port for addr[%s] "
+ "from %u\n",
+ dst->addr, (unsigned int)procid_to_pid(&src));
+ TALLOC_FREE(frame);
+ return;
+ }
+
+ iface = nbtd_find_request_iface(nbtsrv, dst->addr, true);
+ if (iface == NULL) {
+ DBG_WARNING("Could not find iface for packet to addr[%s] "
+ "from %u\n",
+ dst->addr, (unsigned int)procid_to_pid(&src));
+ TALLOC_FREE(frame);
+ return;
+ }
+
+ p->recv_fd = -1;
+ p->send_fd = -1;
+
+ if (p->packet_type == DGRAM_PACKET) {
+ p->packet.dgram.header.source_ip.s_addr = interpret_addr(iface->ip_address);
+ p->packet.dgram.header.source_port = 138;
+ }
+
+ blob.length = build_packet(buf, sizeof(buf), p);
+ if (blob.length == 0) {
+ TALLOC_FREE(frame);
+ return;
+ }
+ blob.data = (uint8_t *)buf;
+
+ if (p->packet_type == DGRAM_PACKET) {
+ nbt_dgram_send_raw(iface->dgmsock, dst, blob);
+ } else {
+ nbt_name_send_raw(iface->nbtsock, dst, blob);
+ }
+
+ TALLOC_FREE(frame);
+}
+
+static int nbtd_server_destructor(struct nbtd_server *nbtsrv)
+{
+ struct task_server *task = nbtsrv->task;
+
+ pidfile_unlink(lpcfg_pid_directory(task->lp_ctx), "nmbd");
+
+ return 0;
+}
+
/*
startup the nbtd task
*/
@@ -40,6 +144,8 @@ static NTSTATUS nbtd_task_init(struct task_server *task)
struct nbtd_server *nbtsrv;
NTSTATUS status;
struct interface *ifaces;
+ const char *nmbd_socket_dir = NULL;
+ int unexpected_clients;
load_interface_list(task, task->lp_ctx, &ifaces);
@@ -66,6 +172,8 @@ static NTSTATUS nbtd_task_init(struct task_server *task)
nbtsrv->bcast_interface = NULL;
nbtsrv->wins_interface = NULL;
+ talloc_set_destructor(nbtsrv, nbtd_server_destructor);
+
/* start listening on the configured network interfaces */
status = nbtd_startup_interfaces(nbtsrv, task->lp_ctx, ifaces);
if (!NT_STATUS_IS_OK(status)) {
@@ -73,6 +181,30 @@ static NTSTATUS nbtd_task_init(struct task_server *task)
return status;
}
+ nmbd_socket_dir = lpcfg_parm_string(task->lp_ctx,
+ NULL,
+ "nmbd",
+ "socket dir");
+ if (nmbd_socket_dir == NULL) {
+ nmbd_socket_dir = get_dyn_NMBDSOCKETDIR();
+ }
+
+ unexpected_clients = lpcfg_parm_int(task->lp_ctx,
+ NULL,
+ "nmbd",
+ "unexpected_clients",
+ 200);
+
+ status = nb_packet_server_create(nbtsrv,
+ nbtsrv->task->event_ctx,
+ nmbd_socket_dir,
+ unexpected_clients,
+ &nbtsrv->unexpected_server);
+ if (!NT_STATUS_IS_OK(status)) {
+ task_server_terminate(task, "nbtd failed to start unexpected_server", true);
+ return status;
+ }
+
nbtsrv->sam_ctx = samdb_connect(nbtsrv,
task->event_ctx,
task->lp_ctx,
@@ -93,11 +225,22 @@ static NTSTATUS nbtd_task_init(struct task_server *task)
nbtd_register_irpc(nbtsrv);
+ status = imessaging_register(task->msg_ctx,
+ nbtsrv,
+ MSG_SEND_PACKET,
+ nbtd_server_msg_send_packet);
+ if (!NT_STATUS_IS_OK(status)) {
+ task_server_terminate(task, "nbtd failed imessaging_register(MSG_SEND_PACKET)", true);
+ return status;
+ }
+
/* start the process of registering our names on all interfaces */
nbtd_register_names(nbtsrv);
irpc_add_name(task->msg_ctx, "nbt_server");
+ pidfile_create(lpcfg_pid_directory(task->lp_ctx), "nmbd");
+
return NT_STATUS_OK;
}
diff --git a/source4/nbt_server/nbt_server.h b/source4/nbt_server/nbt_server.h
index c80e5bf..cbad3e9 100644
--- a/source4/nbt_server/nbt_server.h
+++ b/source4/nbt_server/nbt_server.h
@@ -78,6 +78,8 @@ struct nbtd_server {
struct nbtd_statistics stats;
struct ldb_context *sam_ctx;
+
+ struct nb_packet_server *unexpected_server;
};
diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c
index 2a05e96..7df40c3 100644
--- a/source4/nbt_server/wins/winsdb.c
+++ b/source4/nbt_server/wins/winsdb.c
@@ -32,6 +32,7 @@
#include "lib/socket/netif.h"
#include "param/param.h"
#include "lib/util/smb_strtox.h"
+#include "lib/util/tsort.h"
#undef strcasecmp
@@ -349,7 +350,7 @@ static int winsdb_addr_sort_list (struct winsdb_addr **p1, struct winsdb_addr **
* then the replica addresses with the newest to the oldest address
*/
if (a2->expire_time != a1->expire_time) {
- return a2->expire_time - a1->expire_time;
+ return NUMERIC_CMP(a2->expire_time, a1->expire_time);
}
if (strcmp(a2->wins_owner, h->local_owner) == 0) {
@@ -360,7 +361,7 @@ static int winsdb_addr_sort_list (struct winsdb_addr **p1, struct winsdb_addr **
a1_owned = true;
}
- return a2_owned - a1_owned;
+ return NUMERIC_CMP(a2_owned, a1_owned);
}
struct winsdb_addr **winsdb_addr_list_add(struct winsdb_handle *h, const struct winsdb_record *rec,
diff --git a/source4/nbt_server/wins/winsserver.c b/source4/nbt_server/wins/winsserver.c
index a9f3ecd..6679961 100644
--- a/source4/nbt_server/wins/winsserver.c
+++ b/source4/nbt_server/wins/winsserver.c
@@ -36,6 +36,7 @@
#include "param/param.h"
#include "libcli/resolve/resolve.h"
#include "lib/util/util_net.h"
+#include "lib/util/tsort.h"
/*
work out the ttl we will use given a client requested ttl
@@ -653,7 +654,7 @@ static int nbtd_wins_randomize1Clist_sort(void *p1,/* (const char **) */
match_bits1 = ipv4_match_bits(interpret_addr2(a1), interpret_addr2(src->addr));
match_bits2 = ipv4_match_bits(interpret_addr2(a2), interpret_addr2(src->addr));
- return match_bits2 - match_bits1;
+ return NUMERIC_CMP(match_bits2, match_bits1);
}
static void nbtd_wins_randomize1Clist(struct loadparm_context *lp_ctx,
diff --git a/source4/nbt_server/wscript_build b/source4/nbt_server/wscript_build
index 9d0c24a..ce436e8 100644
--- a/source4/nbt_server/wscript_build
+++ b/source4/nbt_server/wscript_build
@@ -38,7 +38,7 @@ bld.SAMBA_SUBSYSTEM('NBTD_DGRAM',
bld.SAMBA_SUBSYSTEM('NBT_SERVER',
source='interfaces.c register.c query.c nodestatus.c defense.c packet.c irpc.c',
autoproto='nbt_server_proto.h',
- deps='cli-nbt NBTD_WINS NBTD_DGRAM service',
+ deps='cli-nbt NBTD_WINS NBTD_DGRAM service LIBNMB',
enabled=bld.AD_DC_BUILD_IS_ENABLED()
)