#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
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);
+ }
}
#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
}
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;
}
#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
*/
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);
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)) {
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,
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;
}