[PATCH] A few more around name lookup
Volker Lendecke
Volker.Lendecke at SerNet.DE
Tue Jan 23 19:33:41 UTC 2018
Hi!
Review appreciated!
Thanks, Volker
--
Besuchen Sie die verinice.XP 2018 in Berlin,
Anwenderkonferenz für Informationssicherheit
vom 21.-23.03.2018 im Sofitel Kurfürstendamm
Info & Anmeldung hier: http://veriniceXP.org
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 3f9d67c97e3cabd309b5326ae061520cd37975c6 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 23 Jan 2018 14:39:21 +0100
Subject: [PATCH 1/3] libnmb: Add "parse_packet_talloc"
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/nmblib.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++
source3/libsmb/nmblib.h | 5 ++++
2 files changed, 76 insertions(+)
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 8feb029..c262c28 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -803,6 +803,77 @@ struct packet_struct *parse_packet(char *buf,int length,
return p;
}
+static struct packet_struct *copy_packet_talloc(
+ TALLOC_CTX *mem_ctx, const struct packet_struct *src)
+{
+ struct packet_struct *pkt;
+
+ pkt = talloc_memdup(mem_ctx, src, sizeof(struct packet_struct));
+ if (pkt == NULL) {
+ return NULL;
+ }
+ pkt->locked = false;
+ pkt->recv_fd = -1;
+ pkt->send_fd = -1;
+
+ if (src->packet_type == NMB_PACKET) {
+ const struct nmb_packet *nsrc = &src->packet.nmb;
+ struct nmb_packet *ndst = &pkt->packet.nmb;
+
+ if (nsrc->answers != NULL) {
+ ndst->answers = talloc_memdup(
+ pkt, nsrc->answers,
+ sizeof(struct res_rec) * nsrc->header.ancount);
+ if (ndst->answers == NULL) {
+ goto fail;
+ }
+ }
+ if (nsrc->nsrecs != NULL) {
+ ndst->nsrecs = talloc_memdup(
+ pkt, nsrc->nsrecs,
+ sizeof(struct res_rec) * nsrc->header.nscount);
+ if (ndst->nsrecs == NULL) {
+ goto fail;
+ }
+ }
+ if (nsrc->additional != NULL) {
+ ndst->additional = talloc_memdup(
+ pkt, nsrc->additional,
+ sizeof(struct res_rec) * nsrc->header.arcount);
+ if (ndst->nsrecs == NULL) {
+ goto fail;
+ }
+ }
+ }
+
+ return pkt;
+
+ /*
+ * DGRAM packets have no substructures
+ */
+
+fail:
+ TALLOC_FREE(pkt);
+ return NULL;
+}
+
+struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
+ char *buf,int length,
+ enum packet_type packet_type,
+ struct in_addr ip,
+ int port)
+{
+ struct packet_struct *pkt, *result;
+
+ pkt = parse_packet(buf, length, packet_type, ip, port);
+ if (pkt == NULL) {
+ return NULL;
+ }
+ result = copy_packet_talloc(mem_ctx, pkt);
+ free_packet(pkt);
+ return result;
+}
+
/*******************************************************************
Read a packet from a socket and parse it, returning a packet ready
to be used or put on the queue. This assumes a UDP socket.
diff --git a/source3/libsmb/nmblib.h b/source3/libsmb/nmblib.h
index 7e1e40c..1956ea7 100644
--- a/source3/libsmb/nmblib.h
+++ b/source3/libsmb/nmblib.h
@@ -39,6 +39,11 @@ struct packet_struct *parse_packet(char *buf,int length,
enum packet_type packet_type,
struct in_addr ip,
int port);
+struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
+ char *buf,int length,
+ enum packet_type packet_type,
+ struct in_addr ip,
+ int port);
struct packet_struct *read_packet(int fd,enum packet_type packet_type);
void make_nmb_name( struct nmb_name *n, const char *name, int type);
bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
--
1.9.1
From cf73144944f6db498c01a12de1770fee8360fcaa Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 16 Jan 2018 15:50:19 +0100
Subject: [PATCH 2/3] libnmb: Make nb_packet_read_recv return a talloc'ed pkt
This saves a few explicit destructors only doing free_packet()
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/clidgram.c | 3 +-
source3/libsmb/namequery.c | 72 ++++++++-------------------------------------
source3/libsmb/unexpected.c | 6 ++--
source3/libsmb/unexpected.h | 2 +-
4 files changed, 19 insertions(+), 64 deletions(-)
diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c
index 8f0dba3..4ae57a3 100644
--- a/source3/libsmb/clidgram.c
+++ b/source3/libsmb/clidgram.c
@@ -397,7 +397,7 @@ static void nbt_getdc_got_response(struct tevent_req *subreq)
NTSTATUS status;
bool ret;
- status = nb_packet_read_recv(subreq, &p);
+ status = nb_packet_read_recv(subreq, state, &p);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
@@ -406,7 +406,6 @@ static void nbt_getdc_got_response(struct tevent_req *subreq)
ret = parse_getdc_response(p, state, state->domain_name,
&state->nt_version, &state->dc_name,
&state->samlogon_response);
- free_packet(p);
if (!ret) {
tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 6107e8f..b616a64 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -309,7 +309,6 @@ struct sock_packet_read_state {
struct packet_struct *packet;
};
-static int sock_packet_read_state_destructor(struct sock_packet_read_state *s);
static void sock_packet_read_got_packet(struct tevent_req *subreq);
static void sock_packet_read_got_socket(struct tevent_req *subreq);
@@ -331,7 +330,6 @@ static struct tevent_req *sock_packet_read_send(
if (req == NULL) {
return NULL;
}
- talloc_set_destructor(state, sock_packet_read_state_destructor);
state->ev = ev;
state->reader = reader;
state->sock = sock;
@@ -359,15 +357,6 @@ static struct tevent_req *sock_packet_read_send(
return req;
}
-static int sock_packet_read_state_destructor(struct sock_packet_read_state *s)
-{
- if (s->packet != NULL) {
- free_packet(s->packet);
- s->packet = NULL;
- }
- return 0;
-}
-
static void sock_packet_read_got_packet(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
@@ -376,7 +365,7 @@ static void sock_packet_read_got_packet(struct tevent_req *subreq)
req, struct sock_packet_read_state);
NTSTATUS status;
- status = nb_packet_read_recv(subreq, &state->packet);
+ status = nb_packet_read_recv(subreq, state, &state->packet);
TALLOC_FREE(state->reader_req);
@@ -398,8 +387,7 @@ static void sock_packet_read_got_packet(struct tevent_req *subreq)
!state->validator(state->packet, state->private_data)) {
DEBUG(10, ("validator failed\n"));
- free_packet(state->packet);
- state->packet = NULL;
+ TALLOC_FREE(state->packet);
state->reader_req = nb_packet_read_send(state, state->ev,
state->reader);
@@ -460,8 +448,9 @@ static void sock_packet_read_got_socket(struct tevent_req *subreq)
return;
}
- state->packet = parse_packet((char *)state->buf, received, state->type,
- addr.sin.sin_addr, addr.sin.sin_port);
+ state->packet = parse_packet_talloc(
+ state, (char *)state->buf, received, state->type,
+ addr.sin.sin_addr, addr.sin.sin_port);
if (state->packet == NULL) {
DEBUG(10, ("parse_packet failed\n"));
goto retry;
@@ -483,10 +472,7 @@ static void sock_packet_read_got_socket(struct tevent_req *subreq)
return;
retry:
- if (state->packet != NULL) {
- free_packet(state->packet);
- state->packet = NULL;
- }
+ TALLOC_FREE(state->packet);
TALLOC_FREE(state->buf);
TALLOC_FREE(state->addr);
@@ -499,6 +485,7 @@ retry:
}
static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
struct packet_struct **ppacket)
{
struct sock_packet_read_state *state = tevent_req_data(
@@ -508,8 +495,7 @@ static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
if (tevent_req_is_nterror(req, &status)) {
return status;
}
- *ppacket = state->packet;
- state->packet = NULL;
+ *ppacket = talloc_move(mem_ctx, &state->packet);
return NT_STATUS_OK;
}
@@ -532,7 +518,6 @@ struct nb_trans_state {
struct packet_struct *packet;
};
-static int nb_trans_state_destructor(struct nb_trans_state *s);
static void nb_trans_got_reader(struct tevent_req *subreq);
static void nb_trans_done(struct tevent_req *subreq);
static void nb_trans_sent(struct tevent_req *subreq);
@@ -564,7 +549,6 @@ static struct tevent_req *nb_trans_send(
if (req == NULL) {
return NULL;
}
- talloc_set_destructor(state, nb_trans_state_destructor);
state->ev = ev;
state->buf = buf;
state->buflen = buflen;
@@ -604,15 +588,6 @@ static struct tevent_req *nb_trans_send(
return req;
}
-static int nb_trans_state_destructor(struct nb_trans_state *s)
-{
- if (s->packet != NULL) {
- free_packet(s->packet);
- s->packet = NULL;
- }
- return 0;
-}
-
static void nb_trans_got_reader(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
@@ -704,7 +679,7 @@ static void nb_trans_done(struct tevent_req *subreq)
req, struct nb_trans_state);
NTSTATUS status;
- status = sock_packet_read_recv(subreq, &state->packet);
+ status = sock_packet_read_recv(subreq, state, &state->packet);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
@@ -712,7 +687,7 @@ static void nb_trans_done(struct tevent_req *subreq)
tevent_req_done(req);
}
-static NTSTATUS nb_trans_recv(struct tevent_req *req,
+static NTSTATUS nb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct packet_struct **ppacket)
{
struct nb_trans_state *state = tevent_req_data(
@@ -722,8 +697,7 @@ static NTSTATUS nb_trans_recv(struct tevent_req *req,
if (tevent_req_is_nterror(req, &status)) {
return status;
}
- *ppacket = state->packet;
- state->packet = NULL;
+ *ppacket = talloc_move(mem_ctx, &state->packet);
return NT_STATUS_OK;
}
@@ -740,8 +714,6 @@ struct node_status_query_state {
struct packet_struct *packet;
};
-static int node_status_query_state_destructor(
- struct node_status_query_state *s);
static bool node_status_query_validator(struct packet_struct *p,
void *private_data);
static void node_status_query_done(struct tevent_req *subreq);
@@ -762,7 +734,6 @@ struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
if (req == NULL) {
return NULL;
}
- talloc_set_destructor(state, node_status_query_state_destructor);
if (addr->ss_family != AF_INET) {
/* Can't do node status to IPv6 */
@@ -837,16 +808,6 @@ static bool node_status_query_validator(struct packet_struct *p,
return true;
}
-static int node_status_query_state_destructor(
- struct node_status_query_state *s)
-{
- if (s->packet != NULL) {
- free_packet(s->packet);
- s->packet = NULL;
- }
- return 0;
-}
-
static void node_status_query_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
@@ -855,7 +816,7 @@ static void node_status_query_done(struct tevent_req *subreq)
req, struct node_status_query_state);
NTSTATUS status;
- status = nb_trans_recv(subreq, &state->packet);
+ status = nb_trans_recv(subreq, state, &state->packet);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
@@ -1501,7 +1462,7 @@ static void name_query_done(struct tevent_req *subreq)
NTSTATUS status;
struct packet_struct *p = NULL;
- status = nb_trans_recv(subreq, &p);
+ status = nb_trans_recv(subreq, state, &p);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
@@ -1510,13 +1471,6 @@ static void name_query_done(struct tevent_req *subreq)
tevent_req_nterror(req, state->validate_error);
return;
}
- if (p != NULL) {
- /*
- * Free the packet here, we've collected the response in the
- * validator
- */
- free_packet(p);
- }
tevent_req_done(req);
}
diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c
index 16d1f67..ac6c1cf 100644
--- a/source3/libsmb/unexpected.c
+++ b/source3/libsmb/unexpected.c
@@ -715,7 +715,7 @@ static void nb_packet_read_done(struct tevent_req *subreq)
tevent_req_done(req);
}
-NTSTATUS nb_packet_read_recv(struct tevent_req *req,
+NTSTATUS nb_packet_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct packet_struct **ppacket)
{
struct nb_packet_read_state *state = tevent_req_data(
@@ -731,7 +731,8 @@ NTSTATUS nb_packet_read_recv(struct tevent_req *req,
memcpy(&hdr, state->buf, sizeof(hdr));
- packet = parse_packet(
+ packet = parse_packet_talloc(
+ mem_ctx,
(char *)state->buf + sizeof(struct nb_packet_client_header),
state->buflen - sizeof(struct nb_packet_client_header),
state->hdr.type, state->hdr.ip, state->hdr.port);
@@ -739,6 +740,7 @@ NTSTATUS nb_packet_read_recv(struct tevent_req *req,
tevent_req_received(req);
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
+
*ppacket = packet;
tevent_req_received(req);
return NT_STATUS_OK;
diff --git a/source3/libsmb/unexpected.h b/source3/libsmb/unexpected.h
index a40a507..270976b 100644
--- a/source3/libsmb/unexpected.h
+++ b/source3/libsmb/unexpected.h
@@ -43,7 +43,7 @@ NTSTATUS nb_packet_reader_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct tevent_req *nb_packet_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct nb_packet_reader *reader);
-NTSTATUS nb_packet_read_recv(struct tevent_req *req,
+NTSTATUS nb_packet_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct packet_struct **ppacket);
#endif
--
1.9.1
From 51b5e009c87b3988a2a07346efae7a81a4ebb434 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 16 Jan 2018 16:21:08 +0100
Subject: [PATCH 3/3] libnmb: Move "read_packet" to nmbd
It's only used there
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/libsmb/nmblib.c | 35 -----------------------------------
source3/libsmb/nmblib.h | 1 -
source3/nmbd/nmbd_packets.c | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 35 insertions(+), 36 deletions(-)
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index c262c28..bac4340 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -875,41 +875,6 @@ struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
}
/*******************************************************************
- Read a packet from a socket and parse it, returning a packet ready
- to be used or put on the queue. This assumes a UDP socket.
-******************************************************************/
-
-struct packet_struct *read_packet(int fd,enum packet_type packet_type)
-{
- struct packet_struct *packet;
- struct sockaddr_storage sa;
- struct sockaddr_in *si = (struct sockaddr_in *)&sa;
- char buf[MAX_DGRAM_SIZE];
- int length;
-
- length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa);
- if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) {
- return NULL;
- }
-
- packet = parse_packet(buf,
- length,
- packet_type,
- si->sin_addr,
- ntohs(si->sin_port));
- if (!packet)
- return NULL;
-
- packet->recv_fd = fd;
- packet->send_fd = -1;
-
- DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
- length, inet_ntoa(packet->ip), packet->port ) );
-
- return(packet);
-}
-
-/*******************************************************************
Send a udp packet on a already open socket.
******************************************************************/
diff --git a/source3/libsmb/nmblib.h b/source3/libsmb/nmblib.h
index 1956ea7..a0624ed 100644
--- a/source3/libsmb/nmblib.h
+++ b/source3/libsmb/nmblib.h
@@ -44,7 +44,6 @@ struct packet_struct *parse_packet_talloc(TALLOC_CTX *mem_ctx,
enum packet_type packet_type,
struct in_addr ip,
int port);
-struct packet_struct *read_packet(int fd,enum packet_type packet_type);
void make_nmb_name( struct nmb_name *n, const char *name, int type);
bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
int build_packet(char *buf, size_t buflen, struct packet_struct *p);
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index 2b7cc82..bbcb958 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -1879,6 +1879,41 @@ static void nmbd_fd_handler(struct tevent_context *ev,
attr->triggered = true;
}
+/*******************************************************************
+ Read a packet from a socket and parse it, returning a packet ready
+ to be used or put on the queue. This assumes a UDP socket.
+******************************************************************/
+
+static struct packet_struct *read_packet(int fd,enum packet_type packet_type)
+{
+ struct packet_struct *packet;
+ struct sockaddr_storage sa;
+ struct sockaddr_in *si = (struct sockaddr_in *)&sa;
+ char buf[MAX_DGRAM_SIZE];
+ int length;
+
+ length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa);
+ if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) {
+ return NULL;
+ }
+
+ packet = parse_packet(buf,
+ length,
+ packet_type,
+ si->sin_addr,
+ ntohs(si->sin_port));
+ if (!packet)
+ return NULL;
+
+ packet->recv_fd = fd;
+ packet->send_fd = -1;
+
+ DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
+ length, inet_ntoa(packet->ip), packet->port ) );
+
+ return(packet);
+}
+
/****************************************************************************
Listens for NMB or DGRAM packets, and queues them.
return True if the socket is dead
--
1.9.1
More information about the samba-technical
mailing list