mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3: Make name_query use /tmp/.nmbd/unexpected
This commit is contained in:
parent
a32f021d66
commit
6ba4bddb61
@ -103,10 +103,9 @@ static void nss_wins_init(void)
|
||||
|
||||
static struct in_addr *lookup_byname_backend(const char *name, int *count)
|
||||
{
|
||||
int fd = -1;
|
||||
struct ip_service *address = NULL;
|
||||
struct in_addr *ret = NULL;
|
||||
int j, flags = 0;
|
||||
int j;
|
||||
|
||||
if (!initialised) {
|
||||
nss_wins_init();
|
||||
@ -131,11 +130,6 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
|
||||
return ret;
|
||||
}
|
||||
|
||||
fd = wins_lookup_open_socket_in();
|
||||
if (fd == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* uggh, we have to broadcast to each interface in turn */
|
||||
for (j=iface_count() - 1;j >= 0;j--) {
|
||||
const struct in_addr *bcast = iface_n_bcast_v4(j);
|
||||
@ -147,8 +141,8 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
|
||||
continue;
|
||||
}
|
||||
in_addr_to_sockaddr_storage(&ss, *bcast);
|
||||
status = name_query(fd, name, 0x00, True, True, &ss,
|
||||
NULL, &pss, count, &flags, NULL);
|
||||
status = name_query(name, 0x00, True, True, &ss,
|
||||
NULL, &pss, count, NULL);
|
||||
if (pss) {
|
||||
if ((ret = SMB_MALLOC_P(struct in_addr)) == NULL) {
|
||||
return NULL;
|
||||
@ -159,7 +153,6 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2718,17 +2718,20 @@ bool name_status_find(const char *q_name,
|
||||
const struct sockaddr_storage *to_ss,
|
||||
fstring name);
|
||||
int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2);
|
||||
NTSTATUS name_query(int fd,
|
||||
const char *name,
|
||||
int name_type,
|
||||
bool bcast,
|
||||
bool recurse,
|
||||
const struct sockaddr_storage *to_ss,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct sockaddr_storage **addrs,
|
||||
int *count,
|
||||
int *flags,
|
||||
bool *timed_out);
|
||||
struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
const char *name, int name_type,
|
||||
bool bcast, bool recurse,
|
||||
const struct sockaddr_storage *addr);
|
||||
NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
|
||||
struct sockaddr_storage **addrs, int *num_addrs,
|
||||
uint8_t *flags);
|
||||
NTSTATUS name_query(const char *name, int name_type,
|
||||
bool bcast, bool recurse,
|
||||
const struct sockaddr_storage *to_ss,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct sockaddr_storage **addrs,
|
||||
int *num_addrs, uint8_t *flags);
|
||||
NTSTATUS name_resolve_bcast(const char *name,
|
||||
int name_type,
|
||||
struct ip_service **return_iplist,
|
||||
|
@ -572,14 +572,12 @@ static void nb_trans_got_reader(struct tevent_req *subreq)
|
||||
}
|
||||
tevent_req_set_callback(subreq, nb_trans_done, req);
|
||||
|
||||
#if !DEBUG_UNEXPECTED
|
||||
subreq = sendto_send(state, state->ev, state->sock,
|
||||
state->buf, state->buflen, 0, state->dst_addr);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
tevent_req_set_callback(subreq, nb_trans_sent, req);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void nb_trans_sent(struct tevent_req *subreq)
|
||||
@ -755,31 +753,6 @@ struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
|
||||
nmb->question.question_type = 0x21;
|
||||
nmb->question.question_class = 0x1;
|
||||
|
||||
#if DEBUG_UNEXPECTED
|
||||
p.ip = in_addr->sin_addr;
|
||||
p.port = NMB_PORT;
|
||||
p.recv_fd = -1;
|
||||
p.send_fd = -1;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = NMB_PACKET;
|
||||
|
||||
{
|
||||
pid_t nmbd_pid = pidfile_pid("nmbd");
|
||||
|
||||
if (nmbd_pid) {
|
||||
struct messaging_context *msg_ctx = messaging_init(
|
||||
state, procid_self(), ev);
|
||||
/* Try nmbd. */
|
||||
messaging_send_buf(msg_ctx,
|
||||
pid_to_procid(nmbd_pid),
|
||||
MSG_SEND_PACKET,
|
||||
(uint8_t *)&p,
|
||||
sizeof(struct packet_struct));
|
||||
TALLOC_FREE(msg_ctx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
|
||||
&p);
|
||||
if (state->buflen == 0) {
|
||||
@ -788,7 +761,7 @@ struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
subreq = nb_trans_send(state, ev, &state->my_addr, addr, false,
|
||||
subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, false,
|
||||
state->buf, state->buflen,
|
||||
NMB_PACKET, nmb->header.name_trn_id,
|
||||
node_status_query_validator, NULL);
|
||||
@ -1200,45 +1173,67 @@ static bool prioritize_ipv4_list(struct ip_service *iplist, int count)
|
||||
*timed_out is set if we failed by timing out
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS name_query(int fd,
|
||||
const char *name,
|
||||
int name_type,
|
||||
bool bcast,
|
||||
bool recurse,
|
||||
const struct sockaddr_storage *to_ss,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct sockaddr_storage **addrs,
|
||||
int *count,
|
||||
int *flags,
|
||||
bool *timed_out)
|
||||
struct name_query_state {
|
||||
struct sockaddr_storage my_addr;
|
||||
struct sockaddr_storage addr;
|
||||
bool bcast;
|
||||
|
||||
|
||||
uint8_t buf[1024];
|
||||
ssize_t buflen;
|
||||
|
||||
NTSTATUS validate_error;
|
||||
uint8_t flags;
|
||||
|
||||
struct sockaddr_storage *addrs;
|
||||
int num_addrs;
|
||||
};
|
||||
|
||||
static bool name_query_validator(struct packet_struct *p, void *private_data);
|
||||
static void name_query_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
const char *name, int name_type,
|
||||
bool bcast, bool recurse,
|
||||
const struct sockaddr_storage *addr)
|
||||
{
|
||||
bool found=false;
|
||||
int i, retries = 3;
|
||||
int retry_time = bcast?250:2000;
|
||||
struct timespec tp;
|
||||
struct tevent_req *req, *subreq;
|
||||
struct name_query_state *state;
|
||||
struct packet_struct p;
|
||||
struct packet_struct *p2;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
struct sockaddr_storage *ss_list = NULL;
|
||||
struct sockaddr_in *in_addr;
|
||||
struct timeval timeout;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct name_query_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
state->bcast = bcast;
|
||||
|
||||
if (addr->ss_family != AF_INET) {
|
||||
/* Can't do node status to IPv6 */
|
||||
tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (lp_disable_netbios()) {
|
||||
DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
|
||||
name, name_type));
|
||||
return NT_STATUS_NOT_FOUND;
|
||||
tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (to_ss->ss_family != AF_INET) {
|
||||
return NT_STATUS_INVALID_ADDRESS;
|
||||
state->addr = *addr;
|
||||
in_addr = (struct sockaddr_in *)(void *)&state->addr;
|
||||
in_addr->sin_port = htons(NMB_PORT);
|
||||
|
||||
if (!interpret_string_addr(&state->my_addr, lp_socket_address(),
|
||||
AI_NUMERICHOST|AI_PASSIVE)) {
|
||||
zero_sockaddr(&state->my_addr);
|
||||
}
|
||||
|
||||
if (timed_out) {
|
||||
*timed_out = false;
|
||||
}
|
||||
|
||||
memset((char *)&p,'\0',sizeof(p));
|
||||
(*count) = 0;
|
||||
(*flags) = 0;
|
||||
|
||||
ZERO_STRUCT(p);
|
||||
nmb->header.name_trn_id = generate_trn_id();
|
||||
nmb->header.opcode = 0;
|
||||
nmb->header.response = false;
|
||||
@ -1258,157 +1253,231 @@ NTSTATUS name_query(int fd,
|
||||
nmb->question.question_type = 0x20;
|
||||
nmb->question.question_class = 0x1;
|
||||
|
||||
p.ip = ((struct sockaddr_in *)to_ss)->sin_addr;
|
||||
p.port = NMB_PORT;
|
||||
p.recv_fd = -1;
|
||||
p.send_fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = NMB_PACKET;
|
||||
state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
|
||||
&p);
|
||||
if (state->buflen == 0) {
|
||||
tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
|
||||
DEBUG(10, ("build_packet failed\n"));
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
clock_gettime_mono(&tp);
|
||||
subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, bcast,
|
||||
state->buf, state->buflen,
|
||||
NMB_PACKET, nmb->header.name_trn_id,
|
||||
name_query_validator, state);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
DEBUG(10, ("nb_trans_send failed\n"));
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
if (bcast) {
|
||||
timeout = timeval_current_ofs(0, 250000);
|
||||
} else {
|
||||
timeout = timeval_current_ofs(2, 0);
|
||||
}
|
||||
if (!tevent_req_set_endtime(req, ev, timeout)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_set_callback(subreq, name_query_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
if (!send_packet_request(&p))
|
||||
static bool name_query_validator(struct packet_struct *p, void *private_data)
|
||||
{
|
||||
struct name_query_state *state = talloc_get_type_abort(
|
||||
private_data, struct name_query_state);
|
||||
struct nmb_packet *nmb = &p->packet.nmb;
|
||||
struct sockaddr_storage *tmp_addrs;
|
||||
int i;
|
||||
|
||||
debug_nmb_packet(p);
|
||||
|
||||
/*
|
||||
* If we get a Negative Name Query Response from a WINS
|
||||
* server, we should report it and give up.
|
||||
*/
|
||||
if( 0 == nmb->header.opcode /* A query response */
|
||||
&& !state->bcast /* from a WINS server */
|
||||
&& nmb->header.rcode /* Error returned */
|
||||
) {
|
||||
|
||||
if( DEBUGLVL( 3 ) ) {
|
||||
/* Only executed if DEBUGLEVEL >= 3 */
|
||||
dbgtext( "Negative name query "
|
||||
"response, rcode 0x%02x: ",
|
||||
nmb->header.rcode );
|
||||
switch( nmb->header.rcode ) {
|
||||
case 0x01:
|
||||
dbgtext("Request was invalidly formatted.\n");
|
||||
break;
|
||||
case 0x02:
|
||||
dbgtext("Problem with NBNS, cannot process "
|
||||
"name.\n");
|
||||
break;
|
||||
case 0x03:
|
||||
dbgtext("The name requested does not "
|
||||
"exist.\n");
|
||||
break;
|
||||
case 0x04:
|
||||
dbgtext("Unsupported request error.\n");
|
||||
break;
|
||||
case 0x05:
|
||||
dbgtext("Query refused error.\n");
|
||||
break;
|
||||
default:
|
||||
dbgtext("Unrecognized error code.\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We accept this packet as valid, but tell the upper
|
||||
* layers that it's a negative response.
|
||||
*/
|
||||
state->validate_error = NT_STATUS_NOT_FOUND;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nmb->header.opcode != 0 ||
|
||||
nmb->header.nm_flags.bcast ||
|
||||
nmb->header.rcode ||
|
||||
!nmb->header.ancount) {
|
||||
/*
|
||||
* XXXX what do we do with this? Could be a redirect,
|
||||
* but we'll discard it for the moment.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
tmp_addrs = TALLOC_REALLOC_ARRAY(
|
||||
state, state->addrs, struct sockaddr_storage,
|
||||
state->num_addrs + nmb->answers->rdlength/6);
|
||||
if (tmp_addrs == NULL) {
|
||||
state->validate_error = NT_STATUS_NO_MEMORY;
|
||||
return true;
|
||||
}
|
||||
state->addrs = tmp_addrs;
|
||||
|
||||
DEBUG(2,("Got a positive name query response "
|
||||
"from %s ( ", inet_ntoa(p->ip)));
|
||||
|
||||
for (i=0; i<nmb->answers->rdlength/6; i++) {
|
||||
struct in_addr ip;
|
||||
putip((char *)&ip,&nmb->answers->rdata[2+i*6]);
|
||||
in_addr_to_sockaddr_storage(
|
||||
&state->addrs[state->num_addrs], ip);
|
||||
DEBUGADD(2,("%s ",inet_ntoa(ip)));
|
||||
state->num_addrs += 1;
|
||||
}
|
||||
DEBUGADD(2,(")\n"));
|
||||
|
||||
/* We add the flags back ... */
|
||||
if (nmb->header.response)
|
||||
state->flags |= NM_FLAGS_RS;
|
||||
if (nmb->header.nm_flags.authoritative)
|
||||
state->flags |= NM_FLAGS_AA;
|
||||
if (nmb->header.nm_flags.trunc)
|
||||
state->flags |= NM_FLAGS_TC;
|
||||
if (nmb->header.nm_flags.recursion_desired)
|
||||
state->flags |= NM_FLAGS_RD;
|
||||
if (nmb->header.nm_flags.recursion_available)
|
||||
state->flags |= NM_FLAGS_RA;
|
||||
if (nmb->header.nm_flags.bcast)
|
||||
state->flags |= NM_FLAGS_B;
|
||||
|
||||
if (state->bcast) {
|
||||
/*
|
||||
* We have to collect all entries coming in from
|
||||
* broadcast queries
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* WINS responses are accepted when they are received
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
static void name_query_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct name_query_state *state = tevent_req_data(
|
||||
req, struct name_query_state);
|
||||
NTSTATUS status;
|
||||
struct packet_struct *p = NULL;
|
||||
|
||||
status = nb_trans_recv(subreq, &p);
|
||||
TALLOC_FREE(subreq);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
if (!NT_STATUS_IS_OK(state->validate_error)) {
|
||||
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);
|
||||
}
|
||||
|
||||
NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
|
||||
struct sockaddr_storage **addrs, int *num_addrs,
|
||||
uint8_t *flags)
|
||||
{
|
||||
struct name_query_state *state = tevent_req_data(
|
||||
req, struct name_query_state);
|
||||
NTSTATUS status;
|
||||
|
||||
if (tevent_req_is_nterror(req, &status)
|
||||
&& !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
|
||||
return status;
|
||||
}
|
||||
if (state->num_addrs == 0) {
|
||||
return NT_STATUS_NOT_FOUND;
|
||||
|
||||
retries--;
|
||||
|
||||
while (1) {
|
||||
struct timespec tp2;
|
||||
|
||||
clock_gettime_mono(&tp2);
|
||||
if (nsec_time_diff(&tp2,&tp)/1000000 > retry_time) {
|
||||
if (!retries)
|
||||
break;
|
||||
if (!found && !send_packet_request(&p))
|
||||
return NT_STATUS_NOT_FOUND;
|
||||
clock_gettime_mono(&tp);
|
||||
retries--;
|
||||
}
|
||||
if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
debug_nmb_packet(p2);
|
||||
|
||||
/* If we get a Negative Name Query Response from a WINS
|
||||
* server, we should report it and give up.
|
||||
*/
|
||||
if( 0 == nmb2->header.opcode /* A query response */
|
||||
&& !(bcast) /* from a WINS server */
|
||||
&& nmb2->header.rcode /* Error returned */
|
||||
) {
|
||||
|
||||
if( DEBUGLVL( 3 ) ) {
|
||||
/* Only executed if DEBUGLEVEL >= 3 */
|
||||
dbgtext( "Negative name query "
|
||||
"response, rcode 0x%02x: ",
|
||||
nmb2->header.rcode );
|
||||
switch( nmb2->header.rcode ) {
|
||||
case 0x01:
|
||||
dbgtext( "Request "
|
||||
"was invalidly formatted.\n" );
|
||||
break;
|
||||
case 0x02:
|
||||
dbgtext( "Problem with NBNS, "
|
||||
"cannot process name.\n");
|
||||
break;
|
||||
case 0x03:
|
||||
dbgtext( "The name requested "
|
||||
"does not exist.\n" );
|
||||
break;
|
||||
case 0x04:
|
||||
dbgtext( "Unsupported request "
|
||||
"error.\n" );
|
||||
break;
|
||||
case 0x05:
|
||||
dbgtext( "Query refused "
|
||||
"error.\n" );
|
||||
break;
|
||||
default:
|
||||
dbgtext( "Unrecognized error "
|
||||
"code.\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
free_packet(p2);
|
||||
return NT_STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount) {
|
||||
/*
|
||||
* XXXX what do we do with this? Could be a
|
||||
* redirect, but we'll discard it for the
|
||||
* moment.
|
||||
*/
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
ss_list = TALLOC_REALLOC_ARRAY(mem_ctx, ss_list,
|
||||
struct sockaddr_storage,
|
||||
(*count) +
|
||||
nmb2->answers->rdlength/6);
|
||||
|
||||
if (!ss_list) {
|
||||
DEBUG(0,("name_query: Realloc failed.\n"));
|
||||
free_packet(p2);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
DEBUG(2,("Got a positive name query response "
|
||||
"from %s ( ",
|
||||
inet_ntoa(p2->ip)));
|
||||
|
||||
for (i=0;i<nmb2->answers->rdlength/6;i++) {
|
||||
struct in_addr ip;
|
||||
putip((char *)&ip,&nmb2->answers->rdata[2+i*6]);
|
||||
in_addr_to_sockaddr_storage(&ss_list[(*count)],
|
||||
ip);
|
||||
DEBUGADD(2,("%s ",inet_ntoa(ip)));
|
||||
(*count)++;
|
||||
}
|
||||
DEBUGADD(2,(")\n"));
|
||||
|
||||
found=true;
|
||||
retries=0;
|
||||
/* We add the flags back ... */
|
||||
if (nmb2->header.response)
|
||||
(*flags) |= NM_FLAGS_RS;
|
||||
if (nmb2->header.nm_flags.authoritative)
|
||||
(*flags) |= NM_FLAGS_AA;
|
||||
if (nmb2->header.nm_flags.trunc)
|
||||
(*flags) |= NM_FLAGS_TC;
|
||||
if (nmb2->header.nm_flags.recursion_desired)
|
||||
(*flags) |= NM_FLAGS_RD;
|
||||
if (nmb2->header.nm_flags.recursion_available)
|
||||
(*flags) |= NM_FLAGS_RA;
|
||||
if (nmb2->header.nm_flags.bcast)
|
||||
(*flags) |= NM_FLAGS_B;
|
||||
free_packet(p2);
|
||||
/*
|
||||
* If we're doing a unicast lookup we only
|
||||
* expect one reply. Don't wait the full 2
|
||||
* seconds if we got one. JRA.
|
||||
*/
|
||||
if(!bcast && found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* only set timed_out if we didn't fund what we where looking for*/
|
||||
|
||||
if ( !found && timed_out ) {
|
||||
*timed_out = true;
|
||||
*addrs = talloc_move(mem_ctx, &state->addrs);
|
||||
sort_addr_list(*addrs, state->num_addrs);
|
||||
*num_addrs = state->num_addrs;
|
||||
if (flags != NULL) {
|
||||
*flags = state->flags;
|
||||
}
|
||||
|
||||
/* sort the ip list so we choose close servers first if possible */
|
||||
sort_addr_list(ss_list, *count);
|
||||
|
||||
*addrs = ss_list;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS name_query(const char *name, int name_type,
|
||||
bool bcast, bool recurse,
|
||||
const struct sockaddr_storage *to_ss,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct sockaddr_storage **addrs,
|
||||
int *num_addrs, uint8_t *flags)
|
||||
{
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
struct tevent_context *ev;
|
||||
struct tevent_req *req;
|
||||
NTSTATUS status = NT_STATUS_NO_MEMORY;
|
||||
|
||||
ev = tevent_context_init(frame);
|
||||
if (ev == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss);
|
||||
if (req == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (!tevent_req_poll_ntstatus(req, ev, &status)) {
|
||||
goto fail;
|
||||
}
|
||||
status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags);
|
||||
fail:
|
||||
TALLOC_FREE(frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
convert an array if struct sockaddr_storage to struct ip_service
|
||||
return false on failure. Port is set to PORT_NONE;
|
||||
@ -1448,7 +1517,7 @@ NTSTATUS name_resolve_bcast(const char *name,
|
||||
struct ip_service **return_iplist,
|
||||
int *return_count)
|
||||
{
|
||||
int sock, i;
|
||||
int i;
|
||||
int num_interfaces = iface_count();
|
||||
struct sockaddr_storage *ss_list;
|
||||
struct sockaddr_storage ss;
|
||||
@ -1475,27 +1544,20 @@ NTSTATUS name_resolve_bcast(const char *name,
|
||||
zero_sockaddr(&ss);
|
||||
}
|
||||
|
||||
sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
|
||||
if (sock == -1) {
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
|
||||
set_socket_options(sock,"SO_BROADCAST");
|
||||
/*
|
||||
* Lookup the name on all the interfaces, return on
|
||||
* the first successful match.
|
||||
*/
|
||||
for( i = num_interfaces-1; i >= 0; i--) {
|
||||
const struct sockaddr_storage *pss = iface_n_bcast(i);
|
||||
int flags;
|
||||
|
||||
/* Done this way to fix compiler error on IRIX 5.x */
|
||||
if (!pss) {
|
||||
continue;
|
||||
}
|
||||
status = name_query(sock, name, name_type, true, true, pss,
|
||||
status = name_query(name, name_type, true, true, pss,
|
||||
talloc_tos(), &ss_list, return_count,
|
||||
&flags, NULL);
|
||||
NULL);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
goto success;
|
||||
}
|
||||
@ -1503,7 +1565,6 @@ NTSTATUS name_resolve_bcast(const char *name,
|
||||
|
||||
/* failed - no response */
|
||||
|
||||
close(sock);
|
||||
return status;
|
||||
|
||||
success:
|
||||
@ -1512,7 +1573,6 @@ success:
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
|
||||
TALLOC_FREE(ss_list);
|
||||
close(sock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1525,7 +1585,7 @@ NTSTATUS resolve_wins(const char *name,
|
||||
struct ip_service **return_iplist,
|
||||
int *return_count)
|
||||
{
|
||||
int sock, t, i;
|
||||
int t, i;
|
||||
char **wins_tags;
|
||||
struct sockaddr_storage src_ss, *ss_list = NULL;
|
||||
struct in_addr src_ip;
|
||||
@ -1582,8 +1642,6 @@ NTSTATUS resolve_wins(const char *name,
|
||||
for (i=0; i<srv_count; i++) {
|
||||
struct sockaddr_storage wins_ss;
|
||||
struct in_addr wins_ip;
|
||||
int flags;
|
||||
bool timed_out;
|
||||
|
||||
wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
|
||||
|
||||
@ -1601,14 +1659,8 @@ NTSTATUS resolve_wins(const char *name,
|
||||
"and tag '%s'\n",
|
||||
inet_ntoa(wins_ip), wins_tags[t]));
|
||||
|
||||
sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
|
||||
if (sock == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
|
||||
status = name_query(sock,
|
||||
name,
|
||||
status = name_query(name,
|
||||
name_type,
|
||||
false,
|
||||
true,
|
||||
@ -1616,8 +1668,7 @@ NTSTATUS resolve_wins(const char *name,
|
||||
talloc_tos(),
|
||||
&ss_list,
|
||||
return_count,
|
||||
&flags,
|
||||
&timed_out);
|
||||
NULL);
|
||||
|
||||
/* exit loop if we got a list of addresses */
|
||||
|
||||
@ -1625,9 +1676,8 @@ NTSTATUS resolve_wins(const char *name,
|
||||
goto success;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
|
||||
if (timed_out) {
|
||||
if (NT_STATUS_EQUAL(status,
|
||||
NT_STATUS_IO_TIMEOUT)) {
|
||||
/* Timed out waiting for WINS server to
|
||||
* respond.
|
||||
* Mark it dead. */
|
||||
@ -1652,7 +1702,6 @@ success:
|
||||
|
||||
TALLOC_FREE(ss_list);
|
||||
wins_srv_tags_free(wins_tags);
|
||||
close(sock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -153,7 +153,8 @@ static void do_node_status(const char *name,
|
||||
|
||||
static bool query_one(const char *lookup, unsigned int lookup_type)
|
||||
{
|
||||
int j, count, flags = 0;
|
||||
int j, count;
|
||||
uint8_t flags;
|
||||
struct sockaddr_storage *ip_list=NULL;
|
||||
NTSTATUS status = NT_STATUS_NOT_FOUND;
|
||||
|
||||
@ -161,10 +162,10 @@ static bool query_one(const char *lookup, unsigned int lookup_type)
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
print_sockaddr(addr, sizeof(addr), &bcast_addr);
|
||||
d_printf("querying %s on %s\n", lookup, addr);
|
||||
status = name_query(ServerFD,lookup,lookup_type,use_bcast,
|
||||
status = name_query(lookup,lookup_type,use_bcast,
|
||||
use_bcast?true:recursion_desired,
|
||||
&bcast_addr, talloc_tos(),
|
||||
&ip_list, &count, &flags, NULL);
|
||||
&ip_list, &count, &flags);
|
||||
} else {
|
||||
const struct in_addr *bcast;
|
||||
for (j=iface_count() - 1;
|
||||
@ -181,11 +182,11 @@ static bool query_one(const char *lookup, unsigned int lookup_type)
|
||||
print_sockaddr(addr, sizeof(addr), &bcast_ss);
|
||||
d_printf("querying %s on %s\n",
|
||||
lookup, addr);
|
||||
status = name_query(ServerFD,lookup,lookup_type,
|
||||
status = name_query(lookup,lookup_type,
|
||||
use_bcast,
|
||||
use_bcast?True:recursion_desired,
|
||||
&bcast_ss, talloc_tos(),
|
||||
&ip_list, &count, &flags, NULL);
|
||||
&ip_list, &count, &flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,25 +35,21 @@ bool winbindd_running(void)
|
||||
bool nmbd_running(void)
|
||||
{
|
||||
struct in_addr loopback_ip;
|
||||
int fd, count, flags;
|
||||
int count, flags;
|
||||
struct sockaddr_storage *ss_list;
|
||||
struct sockaddr_storage ss;
|
||||
NTSTATUS status;
|
||||
|
||||
loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
|
||||
in_addr_to_sockaddr_storage(&ss, loopback_ip);
|
||||
|
||||
if ((fd = open_socket_in(SOCK_DGRAM, 0, 3,
|
||||
&ss, True)) != -1) {
|
||||
NTSTATUS status = name_query(fd, "__SAMBA__", 0,
|
||||
True, True, &ss,
|
||||
talloc_tos(), &ss_list, &count,
|
||||
&flags, NULL);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(ss_list);
|
||||
close(fd);
|
||||
return True;
|
||||
}
|
||||
close (fd);
|
||||
status = name_query("__SAMBA__", 0,
|
||||
True, True, &ss,
|
||||
talloc_tos(), &ss_list, &count,
|
||||
&flags);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(ss_list);
|
||||
return True;
|
||||
}
|
||||
|
||||
return False;
|
||||
|
@ -94,10 +94,9 @@ static struct sockaddr_storage *lookup_byname_backend(TALLOC_CTX *mem_ctx,
|
||||
const char *name,
|
||||
int *count)
|
||||
{
|
||||
int fd;
|
||||
struct ip_service *ret = NULL;
|
||||
struct sockaddr_storage *return_ss = NULL;
|
||||
int j, i, flags = 0;
|
||||
int j, i;
|
||||
NTSTATUS status;
|
||||
|
||||
*count = 0;
|
||||
@ -121,11 +120,6 @@ static struct sockaddr_storage *lookup_byname_backend(TALLOC_CTX *mem_ctx,
|
||||
return return_ss;
|
||||
}
|
||||
|
||||
fd = wins_lookup_open_socket_in();
|
||||
if (fd == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* uggh, we have to broadcast to each interface in turn */
|
||||
for (j=iface_count() - 1;
|
||||
j >= 0;
|
||||
@ -134,14 +128,13 @@ static struct sockaddr_storage *lookup_byname_backend(TALLOC_CTX *mem_ctx,
|
||||
if (!bcast_ss) {
|
||||
continue;
|
||||
}
|
||||
status = name_query(fd, name, 0x20, True, True,bcast_ss,
|
||||
mem_ctx, &return_ss, count, &flags, NULL);
|
||||
status = name_query(name, 0x20, True, True,bcast_ss,
|
||||
mem_ctx, &return_ss, count, NULL);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return return_ss;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user