The branch, master has been updated via 7ea5d38 libnmb: Move "read_packet" to nmbd via 6a60970 libnmb: Make nb_packet_read_recv return a talloc'ed pkt via 45aec7d libnmb: Add "parse_packet_talloc" from c57cce1 libcli/resolve: Make functions static
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 7ea5d38a69660bf5e086ff03d18b4a4e9eb75cce Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 16 16:21:08 2018 +0100 libnmb: Move "read_packet" to nmbd It's only used there Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Wed Jan 24 05:48:19 CET 2018 on sn-devel-144 commit 6a60970306df44ff5676c98899069f867ac77d36 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 16 15:50:19 2018 +0100 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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 45aec7d3a23645998eb97a86a50345c20a8e14dc Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 23 14:39:21 2018 +0100 libnmb: Add "parse_packet_talloc" Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/libsmb/clidgram.c | 3 +- source3/libsmb/namequery.c | 72 +++++++------------------------------ source3/libsmb/nmblib.c | 88 +++++++++++++++++++++++++++++++-------------- source3/libsmb/nmblib.h | 6 +++- source3/libsmb/unexpected.c | 6 ++-- source3/libsmb/unexpected.h | 2 +- source3/nmbd/nmbd_packets.c | 35 ++++++++++++++++++ 7 files changed, 121 insertions(+), 91 deletions(-) Changeset truncated at 500 lines: 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/nmblib.c b/source3/libsmb/nmblib.c index 8feb029..bac4340 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -803,39 +803,75 @@ struct packet_struct *parse_packet(char *buf,int length, return p; } -/******************************************************************* - 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) +static struct packet_struct *copy_packet_talloc( + TALLOC_CTX *mem_ctx, const struct packet_struct *src) { - 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) { + 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; + } + } + } - packet = parse_packet(buf, - length, - packet_type, - si->sin_addr, - ntohs(si->sin_port)); - if (!packet) - return NULL; + return pkt; - packet->recv_fd = fd; - packet->send_fd = -1; + /* + * DGRAM packets have no substructures + */ + +fail: + TALLOC_FREE(pkt); + return NULL; +} - DEBUG(5,("Received a packet of len %d from (%s) port %d\n", - length, inet_ntoa(packet->ip), packet->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 *pkt, *result; - return(packet); + 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; } /******************************************************************* diff --git a/source3/libsmb/nmblib.h b/source3/libsmb/nmblib.h index 7e1e40c..a0624ed 100644 --- a/source3/libsmb/nmblib.h +++ b/source3/libsmb/nmblib.h @@ -39,7 +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 *read_packet(int fd,enum packet_type packet_type); +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); 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/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 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 -- Samba Shared Repository