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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "nmbd/nmbd.h"
/***************************************************************************
Add a DNS result to the name cache.
static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr addr)
{
- int name_type = question->name_type;
- char *qname = question->name;
-
+ int name_type = question->name_type;
+ unstring qname;
+
+ pull_ascii_nstring(qname, sizeof(qname), question->name);
- if (!addr.s_addr) {
- /* add the fail to WINS cache of names. give it 1 hour in the cache */
- DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
- (void)add_name_to_subnet( wins_server_subnet, qname, name_type,
- NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr );
- return( NULL );
- }
-
- /* add it to our WINS cache of names. give it 2 hours in the cache */
- DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
-
- return( add_name_to_subnet( wins_server_subnet, qname, name_type,
- NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr ) );
-}
+ if (!addr.s_addr) {
+ /* add the fail to WINS cache of names. give it 1 hour in the cache */
+ DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
+ add_name_to_subnet( wins_server_subnet, qname, name_type,
+ NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr );
+ return NULL;
+ }
+ /* add it to our WINS cache of names. give it 2 hours in the cache */
+ DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
+ add_name_to_subnet( wins_server_subnet, qname, name_type,
+ NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr);
+
+ return find_name_on_subnet(wins_server_subnet, question, FIND_ANY_NAME);
+}
#ifndef SYNC_DNS
return the fd used to gather async dns replies. This is added to the select
loop
****************************************************************************/
+
int asyncdns_fd(void)
{
return fd_in;
static void asyncdns_process(void)
{
struct query_record r;
- fstring qname;
+ unstring qname;
DEBUGLEVEL = -1;
while (1) {
- if (read_data(fd_in, (char *)&r, sizeof(r)) != sizeof(r))
- break;
+ NTSTATUS status;
- fstrcpy(qname, r.name.name);
+ status = read_data(fd_in, (char *)&r, sizeof(r));
+ if (!NT_STATUS_IS_OK(status)) {
+ break;
+ }
+
+ pull_ascii_nstring( qname, sizeof(qname), r.name.name);
r.result.s_addr = interpret_addr(qname);
if (write_data(fd_out, (char *)&r, sizeof(r)) != sizeof(r))
static void sig_term(int sig)
{
- _exit(0);
+ _exit(0);
}
/***************************************************************************
{
if (child_pid > 0) {
kill(child_pid, SIGTERM);
+ child_pid = -1;
}
}
void start_async_dns(void)
{
int fd1[2], fd2[2];
+ NTSTATUS status;
CatchChild();
CatchSignal(SIGUSR2, SIG_IGN);
CatchSignal(SIGUSR1, SIG_IGN);
CatchSignal(SIGHUP, SIG_IGN);
- CatchSignal(SIGTERM, SIGNAL_CAST sig_term );
+ CatchSignal(SIGTERM, sig_term);
+
+ status = reinit_after_fork(nmbd_messaging_context(),
+ nmbd_event_context(),
+ true);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("reinit_after_fork() failed\n"));
+ smb_panic("reinit_after_fork() failed");
+ }
asyncdns_process();
}
/***************************************************************************
check if a particular name is already being queried
****************************************************************************/
-static BOOL query_current(struct query_record *r)
+static bool query_current(struct query_record *r)
{
return dns_current &&
nmb_name_equal(&r->name,
/***************************************************************************
write a query to the child process
****************************************************************************/
-static BOOL write_child(struct packet_struct *p)
+static bool write_child(struct packet_struct *p)
{
struct query_record r;
struct query_record r;
struct packet_struct *p, *p2;
struct name_record *namerec;
- int size;
+ NTSTATUS status;
if (fd_in == -1)
return;
- /* Allow SIGTERM to kill us. */
- BlockSignals(False, SIGTERM);
-
- if (!process_exists(child_pid)) {
+ if (!process_exists_by_pid(child_pid)) {
close(fd_in);
+ close(fd_out);
start_async_dns();
}
- if ((size=read_data(fd_in, (char *)&r, sizeof(r))) != sizeof(r)) {
- if (size) {
- DEBUG(0,("Incomplete DNS answer from child!\n"));
- fd_in = -1;
- }
- BlockSignals(True, SIGTERM);
+ status = read_data(fd_in, (char *)&r, sizeof(r));
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("read from child failed: %s\n", nt_errstr(status)));
+ fd_in = -1;
return;
}
- BlockSignals(True, SIGTERM);
-
namerec = add_dns_result(&r.name, r.result);
if (dns_current) {
if (query_current(&r)) {
DEBUG(3,("DNS calling send_wins_name_query_response\n"));
in_dns = 1;
- if(namerec == NULL)
- send_wins_name_query_response(NAM_ERR, dns_current, NULL);
- else
- send_wins_name_query_response(0,dns_current,namerec);
+ if(namerec == NULL)
+ send_wins_name_query_response(NAM_ERR, dns_current, NULL);
+ else
+ send_wins_name_query_response(0,dns_current,namerec);
in_dns = 0;
}
if (nmb_name_equal(question, &r.name)) {
DEBUG(3,("DNS calling send_wins_name_query_response\n"));
in_dns = 1;
- if(namerec == NULL)
- send_wins_name_query_response(NAM_ERR, p, NULL);
- else
- send_wins_name_query_response(0,p,namerec);
+ if(namerec == NULL)
+ send_wins_name_query_response(NAM_ERR, p, NULL);
+ else
+ send_wins_name_query_response(0,p,namerec);
in_dns = 0;
p->locked = False;
- if (p->prev)
- p->prev->next = p->next;
- else
- dns_queue = p->next;
- if (p->next)
- p->next->prev = p->prev;
p2 = p->next;
+ DLIST_REMOVE(dns_queue, p);
free_packet(p);
p = p2;
} else {
if (dns_queue) {
dns_current = dns_queue;
- dns_queue = dns_queue->next;
- if (dns_queue) dns_queue->prev = NULL;
- dns_current->next = NULL;
+ DLIST_REMOVE(dns_queue, dns_queue);
if (!write_child(dns_current)) {
DEBUG(3,("failed to send DNS query to child!\n"));
return;
}
}
-
}
/***************************************************************************
queue a DNS query
****************************************************************************/
-BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
- struct name_record **n)
+
+bool queue_dns_query(struct packet_struct *p,struct nmb_name *question)
{
if (in_dns || fd_in == -1)
return False;
p->locked = True;
} else {
p->locked = True;
- p->next = dns_queue;
- p->prev = NULL;
- if (p->next)
- p->next->prev = p;
- dns_queue = p;
+ DLIST_ADD(dns_queue, p);
}
DEBUG(3,("added DNS query for %s\n", nmb_namestr(question)));
/***************************************************************************
we use this when we can't do async DNS lookups
****************************************************************************/
-BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
- struct name_record **n)
+
+bool queue_dns_query(struct packet_struct *p,struct nmb_name *question)
{
- char *qname = question->name;
+ struct name_record *namerec = NULL;
struct in_addr dns_ip;
+ unstring qname;
- DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
+ pull_ascii_nstring(qname, sizeof(qname), question->name);
- /* Unblock TERM signal so we can be killed in DNS lookup. */
- BlockSignals(False, SIGTERM);
+ DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
dns_ip.s_addr = interpret_addr(qname);
- /* Re-block TERM signal. */
- BlockSignals(True, SIGTERM);
-
- *n = add_dns_result(question, dns_ip);
- if(*n == NULL)
- send_wins_name_query_response(NAM_ERR, p, NULL);
- else
- send_wins_name_query_response(0, p, *n);
+ namerec = add_dns_result(question, dns_ip);
+ if(namerec == NULL) {
+ send_wins_name_query_response(NAM_ERR, p, NULL);
+ } else {
+ send_wins_name_query_response(0, p, namerec);
+ }
return False;
}
/***************************************************************************
With sync dns there is no child to kill on SIGTERM.
****************************************************************************/
+
void kill_async_dns_child(void)
{
- return;
+ return;
}
#endif