diff options
Diffstat (limited to 'source4/nbt_server/nbt_server.c')
-rw-r--r-- | source4/nbt_server/nbt_server.c | 143 |
1 files changed, 143 insertions, 0 deletions
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; } |