mirror of
https://github.com/samba-team/samba.git
synced 2025-02-14 01:57:53 +03:00
- change the iface_n_*() functions to return a "const char *" instead of a "struct ipv4_addr" I think that in general we should move towards "const char *" for all IP addresses, as this makes IPv6 much easier, and is also easier to debug. Andrew, when you get a chance, could you fix some of the auth code to use strings for IPs ? - return a NTSTATUS error on bad name queries and node status instead of using rcode. This makes the calling code simpler. - added low level name release code in libcli/nbt/ - use a real IP in the register and wins nbt torture tests, as w2k3 WINS server silently rejects some operations that don't come from the IP being used (eg. it says "yes" to a release, but does not in fact release the name)
130 lines
4.0 KiB
C
130 lines
4.0 KiB
C
/*
|
|
Unix SMB/CIFS implementation.
|
|
|
|
send out a name release request
|
|
|
|
Copyright (C) Andrew Tridgell 2005
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include "includes.h"
|
|
#include "libcli/nbt/libnbt.h"
|
|
|
|
/*
|
|
send a nbt name release request
|
|
*/
|
|
struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock,
|
|
struct nbt_name_release *io)
|
|
{
|
|
struct nbt_name_request *req;
|
|
struct nbt_name_packet *packet;
|
|
|
|
packet = talloc_zero(nbtsock, struct nbt_name_packet);
|
|
if (packet == NULL) return NULL;
|
|
|
|
packet->qdcount = 1;
|
|
packet->arcount = 1;
|
|
packet->operation = NBT_OPCODE_RELEASE;
|
|
if (io->in.broadcast) {
|
|
packet->operation |= NBT_FLAG_BROADCAST;
|
|
}
|
|
|
|
packet->questions = talloc_array(packet, struct nbt_name_question, 1);
|
|
if (packet->questions == NULL) goto failed;
|
|
|
|
packet->questions[0].name = io->in.name;
|
|
packet->questions[0].question_type = NBT_QTYPE_NETBIOS;
|
|
packet->questions[0].question_class = NBT_QCLASS_IP;
|
|
|
|
packet->additional = talloc_array(packet, struct nbt_res_rec, 1);
|
|
if (packet->additional == NULL) goto failed;
|
|
|
|
packet->additional[0].name = io->in.name;
|
|
packet->additional[0].rr_type = NBT_QTYPE_NETBIOS;
|
|
packet->additional[0].rr_class = NBT_QCLASS_IP;
|
|
packet->additional[0].ttl = 0;
|
|
packet->additional[0].rdata.netbios.length = 6;
|
|
packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional,
|
|
struct nbt_rdata_address, 1);
|
|
if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed;
|
|
packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags;
|
|
packet->additional[0].rdata.netbios.addresses[0].ipaddr =
|
|
talloc_strdup(packet->additional, io->in.address);
|
|
|
|
req = nbt_name_request_send(nbtsock, io->in.dest_addr, lp_nbt_port(), packet,
|
|
io->in.timeout, io->in.retries, False);
|
|
if (req == NULL) goto failed;
|
|
|
|
talloc_free(packet);
|
|
return req;
|
|
|
|
failed:
|
|
talloc_free(packet);
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
wait for a release reply
|
|
*/
|
|
NTSTATUS nbt_name_release_recv(struct nbt_name_request *req,
|
|
TALLOC_CTX *mem_ctx, struct nbt_name_release *io)
|
|
{
|
|
NTSTATUS status;
|
|
struct nbt_name_packet *packet;
|
|
|
|
status = nbt_name_request_recv(req);
|
|
if (!NT_STATUS_IS_OK(status) ||
|
|
req->num_replies == 0) {
|
|
talloc_free(req);
|
|
return status;
|
|
}
|
|
|
|
packet = req->replies[0].packet;
|
|
io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].reply_addr);
|
|
|
|
if (packet->ancount != 1 ||
|
|
packet->answers[0].rr_type != NBT_QTYPE_NETBIOS ||
|
|
packet->answers[0].rr_class != NBT_QCLASS_IP) {
|
|
talloc_free(req);
|
|
return NT_STATUS_INVALID_NETWORK_RESPONSE;
|
|
}
|
|
|
|
io->out.rcode = packet->operation & NBT_RCODE;
|
|
io->out.name = packet->answers[0].name;
|
|
if (packet->answers[0].rdata.netbios.length < 6) {
|
|
talloc_free(req);
|
|
return NT_STATUS_INVALID_NETWORK_RESPONSE;
|
|
}
|
|
io->out.reply_addr = talloc_steal(mem_ctx,
|
|
packet->answers[0].rdata.netbios.addresses[0].ipaddr);
|
|
talloc_steal(mem_ctx, io->out.name.name);
|
|
talloc_steal(mem_ctx, io->out.name.scope);
|
|
|
|
talloc_free(req);
|
|
|
|
return NT_STATUS_OK;
|
|
}
|
|
|
|
/*
|
|
synchronous name release request
|
|
*/
|
|
NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock,
|
|
TALLOC_CTX *mem_ctx, struct nbt_name_release *io)
|
|
{
|
|
struct nbt_name_request *req = nbt_name_release_send(nbtsock, io);
|
|
return nbt_name_release_recv(req, mem_ctx, io);
|
|
}
|