diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-20 04:07:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-20 04:07:27 +0000 |
commit | 31bdcfe4b647c8c783efa32da3c333b5f166a42d (patch) | |
tree | 2b868e2a40cde0854fa0f5466ea8990d3d38f93d /source4/nbt_server | |
parent | Adding upstream version 2:4.20.1+dfsg. (diff) | |
download | samba-31bdcfe4b647c8c783efa32da3c333b5f166a42d.tar.xz samba-31bdcfe4b647c8c783efa32da3c333b5f166a42d.zip |
Adding upstream version 2:4.20.2+dfsg.upstream/2%4.20.2+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | source4/nbt_server/dgram/request.c | 56 | ||||
-rw-r--r-- | source4/nbt_server/interfaces.c | 29 | ||||
-rw-r--r-- | source4/nbt_server/nbt_server.c | 143 | ||||
-rw-r--r-- | source4/nbt_server/nbt_server.h | 2 | ||||
-rw-r--r-- | source4/nbt_server/wins/winsdb.c | 5 | ||||
-rw-r--r-- | source4/nbt_server/wins/winsserver.c | 3 | ||||
-rw-r--r-- | source4/nbt_server/wscript_build | 2 |
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() ) |