diff options
Diffstat (limited to 'contrib/bind/bin')
91 files changed, 0 insertions, 59775 deletions
diff --git a/contrib/bind/bin/Makefile b/contrib/bind/bin/Makefile deleted file mode 100644 index 57fcc58f6900e..0000000000000 --- a/contrib/bind/bin/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 8.28 2000/07/11 06:41:26 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = .. -O=o -A=a -INCL = ${TOP}/include -LIBBIND = ${TOP}/lib/libbind.${A} -LIBPORT = ${TOP}/port/libport.${A} -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LEX = lex -I -YACC = yacc -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -AR= ar cru -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -LDFLAGS= - -MARGS = "SYSTYPE=${SYSTYPE}" "SHELL=${SHELL}" "A=${A}" "O=${O}" \ - "CC=${CC}" "LEX=${LEX}" "YACC=${YACC}" "CDEBUG=${CDEBUG}" \ - "SYSLIBS=${SYSLIBS}" "LDFLAGS=${LDFLAGS}" \ - "DESTDIR=${DESTDIR}" "DESTMAN=${DESTMAN}" \ - "DESTBIN=${DESTBIN}" "DESTSBIN=${DESTSBIN}" "DESTEXEC=${DESTEXEC}" \ - "DESTLIB=${DESTLIB}" "DESTINC=${DESTINC}" "DESTETC=${DESTETC}" \ - "DESTRUN=${DESTRUN}" "DESTHELP=${DESTHELP}" \ - "RANLIB=${RANLIB}" "AR=${AR}" "ARPREF=${ARPREF}" "ARSUFF=${ARSUFF}" \ - "INCL=../${INCL}" "PORTINCL=../${PORTINCL}" "EXE=${EXE}" \ - "LIBBIND=../${LIBBIND}" "LIBPORT=../${LIBPORT}" \ - "INSTALL=${INSTALL}" "TOP=../${TOP}" \ - "VER=${VER}" "STRIP=${STRIP}" "PS=${PS}" "INSTALL_LIB=${INSTALL_LIB}" \ - "INSTALL_EXEC=${INSTALL_EXEC}" "BOUNDS=${BOUNDS}" - -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -SUBDIRS = addr nslookup dig dnsquery host named named-xfer ndc nsupdate \ - mkservdb irpd dnskeygen named-bootconf - -all: ${SUBDIRS} - -${SUBDIRS}: FRC - @(cd $@; pwd; ${MAKE} ${MARGS}) - -install depend tags clean distclean:: - @for x in ${SUBDIRS}; do \ - (cd $$x; pwd; ${MAKE} ${MARGS} $@); \ - done - -distclean:: clean - -clean:: - rm -f *.BAK *.CKP *~ *.orig - -links: FRC - @set -e; \ - for x in $(SUBDIRS); do \ - ( mkdir $$x; cd $$x; pwd; ln -s ../SRC/$$x SRC; \ - cp SRC/Makefile Makefile; chmod +w Makefile; \ - $(MAKE) $(MARGS) links; \ - ); \ - done - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/addr/Makefile b/contrib/bind/bin/addr/Makefile deleted file mode 100644 index 98b7a9197b537..0000000000000 --- a/contrib/bind/bin/addr/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 8.26 2000/07/11 06:41:27 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -EXE= -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -PROG= addr -SRCS= ${PROG}.c -OBJS= ${PROG}.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} \ - ${LIBBIND} ${SYSLIBS} - -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${SRCS} - -${DESTDIR}${DESTBIN}: - mkdir -p ${DESTDIR}${DESTBIN} - -install: ${DESTDIR}${DESTBIN} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTBIN}/${PROG}${EXE} - -links: FRC - @set -e; ln -s SRC/*.[ch] . - -tags: FRC - ctags *.[ch] - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/addr/addr.c b/contrib/bind/bin/addr/addr.c deleted file mode 100644 index a6933918c8675..0000000000000 --- a/contrib/bind/bin/addr/addr.c +++ /dev/null @@ -1,177 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: addr.c,v 8.8 1999/10/13 16:38:55 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996,1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" -#include <sys/param.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <ctype.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include "port_after.h" - -static const char *prog = "addr"; - -#define BIGGEST_ADDRESS IN6ADDRSZ - -static void -usage() { - fprintf(stderr, - "usage: %s [-4] [-6] [-n hexstring] [-p address]\n", - prog); - exit(1); -} - -/* Warning: this scribbles on `dst' even if it's going to return `0'. */ -static int -hexstring(src, dst, len) - const char *src; - u_char *dst; - int len; -{ - static const char xdigits[] = "0123456789abcdef"; - u_char *ptr = dst, *end = dst + len; - u_int val; - int ch, digits; - - val = 0; - digits = 0; - memset(dst, 0, len); - while ((ch = *src++) != '\0') { - if (ch == '0' && (*src == 'x' || *src == 'X')) { - src++; - continue; - } - if (isascii(ch) && (isspace(ch) || ispunct(ch))) { - if (digits > 0) { - if (ptr == end) - return (0); - *ptr++ = (u_char) (val & 0xff); - val = 0; - digits = 0; - } - digits = 0; - continue; - } - if (!isascii(ch) || !isxdigit(ch)) - return (0); - if (isupper(ch)) - ch = tolower(ch); - /* Clock it in using little endian arithmetic. */ - val <<= 4; - val |= (strchr(xdigits, ch) - xdigits); - if (++digits == 2) { - if (ptr == end) - return (0); - *ptr++ = (u_char) (val & 0xff); - digits = 0; - val = 0; - } - } - if (digits > 0) { - if (ptr == end) - return (0); - *ptr++ = (u_char) (val & 0xff); - } - return ((ptr - dst) == len); -} - -static void -display(input, af, addr, len) - const char *input; - int af; - const u_char *addr; - int len; -{ - static int before = 0; - char p[sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255"]; - int i; - - if (before) - putchar('\n'); - else - before++; - - printf("Input: \"%s\"\n", input); - printf("Network: [af%d len%d]", af, len); - for (i = 0; i < len; i++) - printf(" %02x", addr[i]); - putchar('\n'); - printf("Presentation: \"%s\"\n", inet_ntop(af, addr, p, sizeof p)); -} - -int -main(argc, argv) - int argc; - char *argv[]; -{ - u_char addr[BIGGEST_ADDRESS]; - int optchr, af, len, some; - - prog = argv[0]; - af = AF_INET; - len = INADDRSZ; - some = 0; - while ((optchr = getopt(argc, argv, "46n:p:")) != -1) { - switch (optchr) { - case '4': - af = AF_INET; - len = INADDRSZ; - break; - case '6': - af = AF_INET6; - len = IN6ADDRSZ; - break; - case 'n': - if (!hexstring(optarg, addr, len)) { - fprintf(stderr, "bad hex string: \"%s\"\n", - optarg); - usage(); - /* NOTREACHED */ - } - display(optarg, af, addr, len); - some++; - break; - case 'p': - if (inet_pton(af, optarg, addr) <= 0) { - fprintf(stderr, "bad address: \"%s\"\n", - optarg); - usage(); - /* NOTREACHED */ - } - display(optarg, af, addr, len); - some++; - break; - default: - usage(); - /* NOTREACHED */ - } - } - if (!some) - usage(); - exit(0); - /* NOTREACHED */ -} diff --git a/contrib/bind/bin/dig/Makefile b/contrib/bind/bin/dig/Makefile deleted file mode 100644 index ca7775d753631..0000000000000 --- a/contrib/bind/bin/dig/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 8.26 2000/07/11 06:41:27 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -EXE= -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -NSLOOKUP_OBJS= \ - ../nslookup/subr.${O} ../nslookup/send.${O} \ - ../nslookup/list.${O} ../nslookup/debug.${O} - -PROG= dig -SRCS= ${PROG}.c -OBJS= ${PROG}.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${OBJS} ${NSLOOKUP_OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} \ - ${NSLOOKUP_OBJS} ${LIBBIND} ${SYSLIBS} - -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${SRCS} - -${DESTDIR}${DESTBIN}: - mkdir -p ${DESTDIR}${DESTBIN} - -install: ${DESTDIR}${DESTBIN} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTBIN}/${PROG}${EXE} - -links: FRC - @set -e; ln -s SRC/*.[ch] . - -tags: FRC - ctags *.[ch] - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/dig/dig.c b/contrib/bind/bin/dig/dig.c deleted file mode 100644 index de192e03047a1..0000000000000 --- a/contrib/bind/bin/dig/dig.c +++ /dev/null @@ -1,1661 +0,0 @@ -#ifndef lint -static const char rcsid[] = "$Id: dig.c,v 8.42 2000/07/17 07:36:52 vixie Exp $"; -#endif - -/* - * Copyright (c) 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/*********************** Notes for the BIND 4.9 release (Paul Vixie, DEC) - * dig 2.0 was written by copying sections of libresolv.a and nslookup - * and modifying them to be more useful for a general lookup utility. - * as of BIND 4.9, the changes needed to support dig have mostly been - * incorporated into libresolv.a and nslookup; dig now links against - * some of nslookup's .o files rather than #including them or maintaining - * local copies of them. - * - * while merging dig back into the BIND release, i made a number of - * structural changes. for one thing, i put all of dig's private - * library routines into this file rather than maintaining them in - * separate, #included, files. i don't like to #include ".c" files. - * i removed all calls to "bcopy", replacing them with structure - * assignments. i removed all "extern"'s of standard functions, - * replacing them with #include's of standard header files. this - * version of dig is probably as portable as the rest of BIND. - * - * i had to remove the query-time and packet-count statistics since - * the current libresolv.a is a lot harder to modify to maintain these - * than the 4.8 one (used in the original dig) was. for consolation, - * i added a "usage" message with extensive help text. - * - * to save my (limited, albeit) sanity, i ran "indent" over the source. - * i also added the standard berkeley/DEC copyrights, since this file now - * contains a fair amount of non-USC code. note that the berkeley and - * DEC copyrights do not prohibit redistribution, with or without fee; - * we add them only to protect ourselves (you have to claim copyright - * in order to disclaim liability and warranty). - * - * Paul Vixie, Palo Alto, CA, April 1993 - **************************************************************************** - - ****************************************************************** - * DiG -- Domain Information Groper * - * * - * dig.c - Version 2.1 (7/12/94) ("BIND takeover") * - * * - * Developed by: Steve Hotz & Paul Mockapetris * - * USC Information Sciences Institute (USC-ISI) * - * Marina del Rey, California * - * 1989 * - * * - * dig.c - * - * Version 2.0 (9/1/90) * - * o renamed difftime() difftv() to avoid * - * clash with ANSI C * - * o fixed incorrect # args to strcmp,gettimeofday * - * o incorrect length specified to strncmp * - * o fixed broken -sticky -envsa -envset functions * - * o print options/flags redefined & modified * - * * - * Version 2.0.beta (5/9/90) * - * o output format - helpful to `doc` * - * o minor cleanup * - * o release to beta testers * - * * - * Version 1.1.beta (10/26/89) * - * o hanging zone transer (when REFUSED) fixed * - * o trailing dot added to domain names in RDATA * - * o ISI internal * - * * - * Version 1.0.tmp (8/27/89) * - * o Error in prnttime() fixed * - * o no longer dumps core on large pkts * - * o zone transfer (axfr) added * - * o -x added for inverse queries * - * (i.e. "dig -x 128.9.0.32") * - * o give address of default server * - * o accept broadcast to server @255.255.255.255 * - * * - * Version 1.0 (3/27/89) * - * o original release * - * * - * DiG is Public Domain, and may be used for any purpose as * - * long as this notice is not removed. * - ******************************************************************/ - -/* Import. */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/wait.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <isc/dst.h> - -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <netdb.h> -#include <resolv.h> -#include <setjmp.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "port_after.h" - -#include "../nslookup/res.h" - -/* Global. */ - -#define VERSION 83 -#define VSTRING "8.3" - -#define PRF_DEF 0x2ff9 -#define PRF_MIN 0xA930 -#define PRF_ZONE 0x24f9 - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif - -#define SAVEENV "DiG.env" -#define DIG_MAXARGS 30 - -static int eecode = 0; -static FILE * qfp; -static int sockFD; -static char *defsrv, *srvmsg; -static char defbuf[40] = "default -- "; -static char srvbuf[60]; -static char myhostname[MAXHOSTNAMELEN]; -static struct sockaddr_in myaddress; -static u_int32_t ixfr_serial; - -/* stuff for nslookup modules */ -struct __res_state res; -FILE *filePtr; -jmp_buf env; -HostInfo *defaultPtr = NULL; -HostInfo curHostInfo, defaultRec; -int curHostValid = FALSE; -int queryType, queryClass; -extern int StringToClass(), StringToType(); /* subr.c */ -#if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD) -FILE *yyin = NULL; -void yyrestart(FILE *f) { } -#endif -char *pager = NULL; -/* end of nslookup stuff */ - -/* Forward. */ - -static void Usage(void); -static int SetOption(const char *); -static void res_re_init(void); -static int xstrtonum(char *); -static int printZone(ns_type, const char *, - const struct sockaddr_in *, ns_tsig_key *); -static int print_axfr(FILE *output, const u_char *msg, - size_t msglen); -static struct timeval difftv(struct timeval, struct timeval); -static void prnttime(struct timeval); -static void stackarg(char *, char **); - -/* Public. */ - -int -main(int argc, char **argv) { - struct hostent *hp; - short port = htons(NAMESERVER_PORT); - /* Wierd stuff for SPARC alignment, hurts nothing else. */ - union { - HEADER header_; - u_char packet_[PACKETSZ]; - } packet_; -#define header (packet_.header_) -#define packet (packet_.packet_) - u_char answer[64*1024]; - int n; - char doping[90]; - char pingstr[50]; - char *afile; - char *addrc, *addrend, *addrbegin; - - time_t exectime; - struct timeval tv1, tv2, start_time, end_time, query_time; - - char *srv; - int anyflag = 0; - int sticky = 0; - int tmp; - int qtypeSet; - int addrflag = 0; - ns_type xfr = ns_t_invalid; - int bytes_out, bytes_in; - - char cmd[512]; - char domain[MAXDNAME]; - char msg[120], *msgptr; - char **vtmp; - char *args[DIG_MAXARGS]; - char **ax; - int once = 1, dofile = 0; /* batch -vs- interactive control */ - char fileq[384]; - int fp; - int wait=0, delay; - int envset=0, envsave=0; - struct __res_state res_x, res_t; - char *pp; - - ns_tsig_key key; - char *keyfile = NULL, *keyname = NULL; - - res_ninit(&res); - res.pfcode = PRF_DEF; - qtypeSet = 0; - memset(domain, 0, sizeof domain); - gethostname(myhostname, (sizeof myhostname)); -#ifdef HAVE_SA_LEN - myaddress.sin_len = sizeof(struct sockaddr_in); -#endif - myaddress.sin_family = AF_INET; - myaddress.sin_addr.s_addr = INADDR_ANY; - myaddress.sin_port = 0; /*INPORT_ANY*/; - defsrv = strcat(defbuf, inet_ntoa(res.nsaddr.sin_addr)); - res_x = res; - -/* - * If LOCALDEF in environment, should point to file - * containing local favourite defaults. Also look for file - * DiG.env (i.e. SAVEENV) in local directory. - */ - - if ((((afile = (char *) getenv("LOCALDEF")) != (char *) NULL) && - ((fp = open(afile, O_RDONLY)) > 0)) || - ((fp = open(SAVEENV, O_RDONLY)) > 0)) { - read(fp, (char *)&res_x, (sizeof res_x)); - close(fp); - res = res_x; - } -/* - * Check for batch-mode DiG; also pre-scan for 'help'. - */ - vtmp = argv; - ax = args; - while (*vtmp != NULL) { - if (strcmp(*vtmp, "-h") == 0 || - strcmp(*vtmp, "-help") == 0 || - strcmp(*vtmp, "-usage") == 0 || - strcmp(*vtmp, "help") == 0) { - Usage(); - exit(0); - } - - if (strcmp(*vtmp, "-f") == 0) { - dofile++; once=0; - if ((qfp = fopen(*++vtmp, "r")) == NULL) { - fflush(stdout); - perror("file open"); - fflush(stderr); - exit(10); - } - } else { - if (ax - args == DIG_MAXARGS) { - fprintf(stderr, "dig: too many arguments\n"); - exit(10); - } - *ax++ = *vtmp; - } - vtmp++; - } - - res.id = 1; - gettimeofday(&tv1, NULL); - assert(tv1.tv_usec >= 0 && tv1.tv_usec < 1000000); - -/* - * Main section: once if cmd-line query - * while !EOF if batch mode - */ - *fileq = '\0'; - while ((dofile && fgets(fileq, sizeof fileq, qfp) != NULL) || - (!dofile && once--)) - { - if (*fileq == '\n' || *fileq == '#' || *fileq==';') { - printf("%s", fileq); /* echo but otherwise ignore */ - continue; /* blank lines and comments */ - } - -/* - * "Sticky" requests that before current parsing args - * return to current "working" environment (X******). - */ - if (sticky) { - printf(";; (using sticky settings)\n"); - res = res_x; - } - -/* - * Concat cmd-line and file args. - */ - stackarg(fileq, ax); - - /* defaults */ - queryType = ns_t_ns; - queryClass = ns_c_in; - xfr = ns_t_invalid; - *pingstr = 0; - srv = NULL; - - sprintf(cmd, "\n; <<>> DiG %s <<>> ", VSTRING); - argv = args; - argc = ax - args; -/* - * More cmd-line options than anyone should ever have to - * deal with .... - */ - while (*(++argv) != NULL && **argv != '\0') { - strcat(cmd, *argv); - strcat(cmd, " "); - if (**argv == '@') { - srv = (*argv+1); - continue; - } - if (**argv == '%') - continue; - if (**argv == '+') { - SetOption(*argv+1); - continue; - } - if (**argv == '=') { - ixfr_serial = strtoul(*argv+1, NULL, 0); - continue; - } - if (strncmp(*argv, "-nost", 5) == 0) { - sticky = 0; - continue; - } else if (strncmp(*argv, "-st", 3) == 0) { - sticky++; - continue; - } else if (strncmp(*argv, "-envsa", 6) == 0) { - envsave++; - continue; - } else if (strncmp(*argv, "-envse", 6) == 0) { - envset++; - continue; - } - - if (**argv == '-') { - switch (argv[0][1]) { - case 'T': - wait = atoi(*++argv); - break; - case 'c': - if ((tmp = atoi(*++argv)) - || *argv[0]=='0') { - queryClass = tmp; - } else if ((tmp = StringToClass(*argv, - 0, NULL) - ) != 0) { - queryClass = tmp; - } else { - printf( - "; invalid class specified\n" - ); - } - break; - case 't': - if ((tmp = atoi(*++argv)) - || *argv[0]=='0') { - queryType = tmp; - qtypeSet++; - } else if ((tmp = StringToType(*argv, - 0, NULL) - ) != 0) { - queryType = tmp; - qtypeSet++; - } else { - printf( - "; invalid type specified\n" - ); - } - break; - case 'x': - if (!qtypeSet) { - queryType = T_ANY; - qtypeSet++; - } - if (!(addrc = *++argv)) { - printf( - "; no arg for -x?\n" - ); - break; - } - addrend = addrc + strlen(addrc); - if (*addrend == '.') - *addrend = '\0'; - *domain = '\0'; - while ((addrbegin = strrchr(addrc,'.'))) { - strcat(domain, addrbegin+1); - strcat(domain, "."); - *addrbegin = '\0'; - } - strcat(domain, addrc); - strcat(domain, ".in-addr.arpa."); - break; - case 'p': - if (argv[0][2] != '\0') - port = ntohs(atoi(argv[0]+2)); - else - port = htons(atoi(*++argv)); - break; - case 'P': - if (argv[0][2] != '\0') - strcpy(pingstr, argv[0]+2); - else - strcpy(pingstr, "ping -s"); - break; - case 'n': - if (argv[0][2] != '\0') - res.ndots = atoi(argv[0]+2); - else - res.ndots = atoi(*++argv); - break; - case 'b': { - char *a, *p; - - if (argv[0][2] != '\0') - a = argv[0]+2; - else - a = *++argv; - if ((p = strchr(a, ':')) != NULL) { - *p++ = '\0'; - myaddress.sin_port = - ntohs(atoi(p)); - } - if (!inet_aton(a,&myaddress.sin_addr)){ - fprintf(stderr, - ";; bad -b addr\n"); - exit(1); - } - } - break; - case 'k': - /* -k keydir:keyname */ - - if (argv[0][2] != '\0') - keyfile = argv[0]+2; - else - keyfile = *++argv; - - keyname = strchr(keyfile, ':'); - if (keyname == NULL) { - fprintf(stderr, - "key option argument should be keydir:keyname\n"); - exit(1); - } - *keyname++='\0'; - break; - } /* switch - */ - continue; - } /* if '-' */ - - if ((tmp = StringToType(*argv, -1, NULL)) != -1) { - if ((T_ANY == tmp) && anyflag++) { - queryClass = C_ANY; - continue; - } - if (ns_t_xfr_p(tmp) && - (tmp == ns_t_axfr || - (res.options & RES_USEVC) != 0) - ) { - res.pfcode = PRF_ZONE; - xfr = (ns_type)tmp; - } else { - queryType = tmp; - qtypeSet++; - } - } else if ((tmp = StringToClass(*argv, -1, NULL)) - != -1) { - queryClass = tmp; - } else { - memset(domain, 0, sizeof domain); - sprintf(domain,"%s",*argv); - } - } /* while argv remains */ - - /* process key options */ - if (keyfile) { -#ifdef PARSE_KEYFILE - int i, n1; - char buf[BUFSIZ], *p; - FILE *fp = NULL; - int file_major, file_minor, alg; - - fp = fopen(keyfile, "r"); - if (fp == NULL) { - perror(keyfile); - exit(1); - } - /* Now read the header info from the file. */ - i = fread(buf, 1, BUFSIZ, fp); - if (i < 5) { - fclose(fp); - exit(1); - } - fclose(fp); - - p = buf; - - n=strlen(p); /* get length of strings */ - n1=strlen("Private-key-format: v"); - if (n1 > n || - strncmp(buf, "Private-key-format: v", n1)) { - fprintf(stderr, "Invalid key file format\n"); - exit(1); /* not a match */ - } - p+=n1; /* advance pointer */ - sscanf((char *)p, "%d.%d", &file_major, &file_minor); - /* should do some error checking with these someday */ - while (*p++!='\n'); /* skip to end of line */ - - n=strlen(p); /* get length of strings */ - n1=strlen("Algorithm: "); - if (n1 > n || strncmp(p, "Algorithm: ", n1)) { - fprintf(stderr, "Invalid key file format\n"); - exit(1); /* not a match */ - } - p+=n1; /* advance pointer */ - if (sscanf((char *)p, "%d", &alg)!=1) { - fprintf(stderr, "Invalid key file format\n"); - exit(1); - } - while (*p++!='\n'); /* skip to end of line */ - - n=strlen(p); /* get length of strings */ - n1=strlen("Key: "); - if (n1 > n || strncmp(p, "Key: ", n1)) { - fprintf(stderr, "Invalid key file format\n"); - exit(1); /* not a match */ - } - p+=n1; /* advance pointer */ - pp=p; - while (*pp++!='\n'); /* skip to end of line, - * terminate it */ - *--pp='\0'; - - key.data=malloc(1024*sizeof(char)); - key.len=b64_pton(p, key.data, 1024); - - strcpy(key.name, keyname); - strcpy(key.alg, "HMAC-MD5.SIG-ALG.REG.INT"); -#else - /* use the dst* routines to parse the key files - * - * This requires that both the .key and the .private - * files exist in your cwd, so the keyfile parmeter - * here is assumed to be a path in which the - * K*.{key,private} files exist. - */ - DST_KEY *dst_key; - char cwd[PATH_MAX+1]; - - if (getcwd(cwd, PATH_MAX)==NULL) { - perror("unable to get current directory"); - exit(1); - } - if (chdir(keyfile)<0) { - fprintf(stderr, - "unable to chdir to %s: %s\n", keyfile, - strerror(errno)); - exit(1); - } - - dst_init(); - dst_key = dst_read_key(keyname, - 0 /* not used for priv keys */, - KEY_HMAC_MD5, DST_PRIVATE); - if (!dst_key) { - fprintf(stderr, - "dst_read_key: error reading key\n"); - exit(1); - } - key.data=malloc(1024*sizeof(char)); - dst_key_to_buffer(dst_key, key.data, 1024); - key.len=dst_key->dk_key_size; - - strcpy(key.name, keyname); - strcpy(key.alg, "HMAC-MD5.SIG-ALG.REG.INT"); - - if (chdir(cwd)<0) { - fprintf(stderr, "unable to chdir to %s: %s\n", - cwd, strerror(errno)); - exit(1); - } -#endif - } - - if (res.pfcode & 0x80000) - printf("; pfcode: %08lx, options: %08lx\n", - res.pfcode, res.options); - -/* - * Current env. (after this parse) is to become the - * new "working" environmnet. Used in conj. with sticky. - */ - if (envset) { - res_x = res; - envset = 0; - } - -/* - * Current env. (after this parse) is to become the - * new default saved environmnet. Save in user specified - * file if exists else is SAVEENV (== "DiG.env"). - */ - if (envsave) { - afile = (char *) getenv("LOCALDEF"); - if ((afile && - ((fp = open(afile, - O_WRONLY|O_CREAT|O_TRUNC, - S_IREAD|S_IWRITE)) > 0)) - || - ((fp = open(SAVEENV, - O_WRONLY|O_CREAT|O_TRUNC, - S_IREAD|S_IWRITE)) > 0)) { - write(fp, (char *)&res, (sizeof res)); - close(fp); - } - envsave = 0; - } - - if (res.pfcode & RES_PRF_CMD) - printf("%s\n", cmd); - - addrflag = anyflag = 0; - -/* - * Find address of server to query. If not dot-notation, then - * try to resolve domain-name (if so, save and turn off print - * options, this domain-query is not the one we want. Restore - * user options when done. - * Things get a bit wierd since we need to use resolver to be - * able to "put the resolver to work". - */ - - srvbuf[0] = 0; - srvmsg = defsrv; - if (srv != NULL) { - struct in_addr addr; - - if (inet_aton(srv, &addr)) { - res.nscount = 1; - res.nsaddr.sin_addr = addr; - srvmsg = strcat(srvbuf, srv); - } else { - res_t = res; - res_ninit(&res); - res.pfcode = 0; - res.options = RES_DEFAULT; - hp = gethostbyname(srv); - res = res_t; - if (hp == NULL - || hp->h_addr_list == NULL - || *hp->h_addr_list == NULL) { - fflush(stdout); - fprintf(stderr, - "; Bad server: %s -- using default server and timer opts\n", - srv); - fflush(stderr); - srvmsg = defsrv; - srv = NULL; - } else { - u_int32_t **addr; - - res.nscount = 0; - for (addr = (u_int32_t**)hp->h_addr_list; - *addr && (res.nscount < MAXNS); - addr++) { - res.nsaddr_list[ - res.nscount++ - ].sin_addr.s_addr = **addr; - } - - srvmsg = strcat(srvbuf,srv); - strcat(srvbuf, " "); - strcat(srvmsg, - inet_ntoa(res.nsaddr.sin_addr)); - } - } - printf("; (%d server%s found)\n", - res.nscount, (res.nscount==1)?"":"s"); - res.id += res.retry; - } - - { - int i; - - for (i = 0; i < res.nscount; i++) { - res.nsaddr_list[i].sin_family = AF_INET; - res.nsaddr_list[i].sin_port = port; - } - res.id += res.retry; - } - - if (ns_t_xfr_p(xfr)) { - int i; - - for (i = 0; i < res.nscount; i++) { - int x; - - if (keyfile) - x = printZone(xfr, domain, - &res.nsaddr_list[i], - &key); - else - x = printZone(xfr, domain, - &res.nsaddr_list[i], - NULL); - if (res.pfcode & RES_PRF_STATS) { - exectime = time(NULL); - printf(";; FROM: %s to SERVER: %s\n", - myhostname, - inet_ntoa(res.nsaddr_list[i] - .sin_addr)); - printf(";; WHEN: %s", ctime(&exectime)); - } - if (!x) - break; /* success */ - } - fflush(stdout); - continue; - } - - if (*domain && !qtypeSet) { - queryType = T_A; - qtypeSet++; - } - - bytes_out = n = res_nmkquery(&res, QUERY, domain, - queryClass, queryType, - NULL, 0, NULL, - packet, sizeof packet); - if (n < 0) { - fflush(stderr); - printf(";; res_nmkquery: buffer too small\n\n"); - continue; - } - if (queryType == T_IXFR) { - HEADER *hp = (HEADER *) packet; - u_char *cpp = packet + bytes_out; - - hp->nscount = htons(1+ntohs(hp->nscount)); - n = dn_comp(domain, cpp, - (sizeof packet) - (cpp - packet), - NULL, NULL); - cpp += n; - PUTSHORT(T_SOA, cpp); /* type */ - PUTSHORT(C_IN, cpp); /* class */ - PUTLONG(0, cpp); /* ttl */ - PUTSHORT(22, cpp); /* dlen */ - *cpp++ = 0; /* mname */ - *cpp++ = 0; /* rname */ - PUTLONG(ixfr_serial, cpp); - PUTLONG(0xDEAD, cpp); /* Refresh */ - PUTLONG(0xBEEF, cpp); /* Retry */ - PUTLONG(0xABCD, cpp); /* Expire */ - PUTLONG(0x1776, cpp); /* Min TTL */ - bytes_out = n = cpp - packet; - }; - - eecode = 0; - if (res.pfcode & RES_PRF_HEAD1) - fp_resstat(&res, stdout); - (void) gettimeofday(&start_time, NULL); - assert(start_time.tv_usec >= 0 && start_time.tv_usec < 1000000); - if (keyfile) - n = res_nsendsigned(&res, packet, n, &key, answer, sizeof answer); - else - n = res_nsend(&res, packet, n, answer, sizeof answer); - if ((bytes_in = n) < 0) { - fflush(stdout); - n = 0 - n; - msg[0]=0; - if (keyfile) - strcat(msg,";; res_nsendsigned to server "); - else - strcat(msg,";; res_nsend to server "); - strcat(msg,srvmsg); - perror(msg); - fflush(stderr); - - if (!dofile) { - if (eecode) - exit(eecode); - else - exit(9); - } - } - (void) gettimeofday(&end_time, NULL); - assert(end_time.tv_usec >= 0 && end_time.tv_usec < 1000000); - - if (res.pfcode & RES_PRF_STATS) { - time_t t; - - query_time = difftv(start_time, end_time); - printf(";; Total query time: "); - prnttime(query_time); - putchar('\n'); - exectime = time(NULL); - printf(";; FROM: %s to SERVER: %s\n", - myhostname, srvmsg); - printf(";; WHEN: %s", ctime(&exectime)); - printf(";; MSG SIZE sent: %d rcvd: %d\n", - bytes_out, bytes_in); - } - - fflush(stdout); -/* - * Argh ... not particularly elegant. Should put in *real* ping code. - * Would necessitate root priviledges for icmp port though! - */ - if (*pingstr) { - sprintf(doping,"%s %s 56 3 | tail -3",pingstr, - (srv==NULL)?(defsrv+10):srv); - system(doping); - } - putchar('\n'); - -/* - * Fairly crude method and low overhead method of keeping two - * batches started at different sites somewhat synchronized. - */ - gettimeofday(&tv2, NULL); - assert(tv2.tv_usec >= 0 && tv2.tv_usec < 1000000); - delay = (int)(tv2.tv_sec - tv1.tv_sec); - if (delay < wait) { - sleep(wait - delay); - } - } - return (eecode); -} - -/* Private. */ - -static void -Usage() { - fputs("\ -usage: dig [@server] [domain] [q-type] [q-class] {q-opt} {d-opt} [%comment]\n\ -where: server,\n\ - domain are names in the Domain Name System\n\ - q-class is one of (in,any,...) [default: in]\n\ - q-type is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default: a]\n\ -", stderr); - fputs("\ - q-opt is one of:\n\ - -x dot-notation-address (shortcut to in-addr.arpa lookups)\n\ - -f file (batch mode input file name)\n\ - -T time (batch mode time delay, per query)\n\ - -p port (nameserver is on this port) [53]\n\ - -b addr[:port] (bind to this tcp address) [*]\n\ - -P[ping-string] (see man page)\n\ - -t query-type (synonym for q-type)\n\ - -c query-class (synonym for q-class)\n\ - -k keydir:keyname (sign the query with this TSIG key)\n\ - -envsav,-envset (see man page)\n\ - -[no]stick (see man page)\n\ -", stderr); - fputs("\ - d-opt is of the form ``+keyword=value'' where keyword is one of:\n\ - [no]debug [no]d2 [no]recurse retry=# time=# [no]ko [no]vc\n\ - [no]defname [no]search domain=NAME [no]ignore [no]primary\n\ - [no]aaonly [no]cmd [no]stats [no]Header [no]header\n\ - [no]ttlid [no]cl [no]qr [no]reply [no]ques [no]answer\n\ - [no]author [no]addit pfdef pfmin pfset=# pfand=# pfor=#\n\ -", stderr); - fputs("\ -notes: defname and search don't work; use fully-qualified names.\n\ - this is DiG version " VSTRING "\n\ - $Id: dig.c,v 8.42 2000/07/17 07:36:52 vixie Exp $\n\ -", stderr); -} - -static int -SetOption(const char *string) { - char option[NAME_LEN], type[NAME_LEN], *ptr; - int i; - - i = pickString(string, option, sizeof option); - if (i == 0) { - fprintf(stderr, ";*** Invalid option: %s\n", string); - - /* this is ugly, but fixing the caller to behave - properly with an error return value would require a major - cleanup. */ - exit(9); - } - - if (strncmp(option, "aa", 2) == 0) { /* aaonly */ - res.options |= RES_AAONLY; - } else if (strncmp(option, "noaa", 4) == 0) { - res.options &= ~RES_AAONLY; - } else if (strncmp(option, "deb", 3) == 0) { /* debug */ - res.options |= RES_DEBUG; - } else if (strncmp(option, "nodeb", 5) == 0) { - res.options &= ~(RES_DEBUG | RES_DEBUG2); - } else if (strncmp(option, "ko", 2) == 0) { /* keepopen */ - res.options |= (RES_STAYOPEN | RES_USEVC); - } else if (strncmp(option, "noko", 4) == 0) { - res.options &= ~RES_STAYOPEN; - } else if (strncmp(option, "d2", 2) == 0) { /* d2 (more debug) */ - res.options |= (RES_DEBUG | RES_DEBUG2); - } else if (strncmp(option, "nod2", 4) == 0) { - res.options &= ~RES_DEBUG2; - } else if (strncmp(option, "def", 3) == 0) { /* defname */ - res.options |= RES_DEFNAMES; - } else if (strncmp(option, "nodef", 5) == 0) { - res.options &= ~RES_DEFNAMES; - } else if (strncmp(option, "sea", 3) == 0) { /* search list */ - res.options |= RES_DNSRCH; - } else if (strncmp(option, "nosea", 5) == 0) { - res.options &= ~RES_DNSRCH; - } else if (strncmp(option, "do", 2) == 0) { /* domain */ - ptr = strchr(option, '='); - if (ptr != NULL) { - i = pickString(++ptr, res.defdname, sizeof res.defdname); - if (i == 0) { /* value's too long or non-existant. This actually - shouldn't happen due to pickString() - above */ - fprintf(stderr, "*** Invalid domain: %s\n", ptr) ; - exit(9); /* see comment at previous call to exit()*/ - } - } - } else if (strncmp(option, "ti", 2) == 0) { /* timeout */ - ptr = strchr(option, '='); - if (ptr != NULL) - sscanf(++ptr, "%d", &res.retrans); - } else if (strncmp(option, "ret", 3) == 0) { /* retry */ - ptr = strchr(option, '='); - if (ptr != NULL) - sscanf(++ptr, "%d", &res.retry); - } else if (strncmp(option, "i", 1) == 0) { /* ignore */ - res.options |= RES_IGNTC; - } else if (strncmp(option, "noi", 3) == 0) { - res.options &= ~RES_IGNTC; - } else if (strncmp(option, "pr", 2) == 0) { /* primary */ - res.options |= RES_PRIMARY; - } else if (strncmp(option, "nop", 3) == 0) { - res.options &= ~RES_PRIMARY; - } else if (strncmp(option, "rec", 3) == 0) { /* recurse */ - res.options |= RES_RECURSE; - } else if (strncmp(option, "norec", 5) == 0) { - res.options &= ~RES_RECURSE; - } else if (strncmp(option, "v", 1) == 0) { /* vc */ - res.options |= RES_USEVC; - } else if (strncmp(option, "nov", 3) == 0) { - res.options &= ~RES_USEVC; - } else if (strncmp(option, "pfset", 5) == 0) { - ptr = strchr(option, '='); - if (ptr != NULL) - res.pfcode = xstrtonum(++ptr); - } else if (strncmp(option, "pfand", 5) == 0) { - ptr = strchr(option, '='); - if (ptr != NULL) - res.pfcode = res.pfcode & xstrtonum(++ptr); - } else if (strncmp(option, "pfor", 4) == 0) { - ptr = strchr(option, '='); - if (ptr != NULL) - res.pfcode |= xstrtonum(++ptr); - } else if (strncmp(option, "pfmin", 5) == 0) { - res.pfcode = PRF_MIN; - } else if (strncmp(option, "pfdef", 5) == 0) { - res.pfcode = PRF_DEF; - } else if (strncmp(option, "an", 2) == 0) { /* answer section */ - res.pfcode |= RES_PRF_ANS; - } else if (strncmp(option, "noan", 4) == 0) { - res.pfcode &= ~RES_PRF_ANS; - } else if (strncmp(option, "qu", 2) == 0) { /* question section */ - res.pfcode |= RES_PRF_QUES; - } else if (strncmp(option, "noqu", 4) == 0) { - res.pfcode &= ~RES_PRF_QUES; - } else if (strncmp(option, "au", 2) == 0) { /* authority section */ - res.pfcode |= RES_PRF_AUTH; - } else if (strncmp(option, "noau", 4) == 0) { - res.pfcode &= ~RES_PRF_AUTH; - } else if (strncmp(option, "ad", 2) == 0) { /* addition section */ - res.pfcode |= RES_PRF_ADD; - } else if (strncmp(option, "noad", 4) == 0) { - res.pfcode &= ~RES_PRF_ADD; - } else if (strncmp(option, "tt", 2) == 0) { /* TTL & ID */ - res.pfcode |= RES_PRF_TTLID; - } else if (strncmp(option, "nott", 4) == 0) { - res.pfcode &= ~RES_PRF_TTLID; - } else if (strncmp(option, "he", 2) == 0) { /* head flags stats */ - res.pfcode |= RES_PRF_HEAD2; - } else if (strncmp(option, "nohe", 4) == 0) { - res.pfcode &= ~RES_PRF_HEAD2; - } else if (strncmp(option, "H", 1) == 0) { /* header all */ - res.pfcode |= RES_PRF_HEADX; - } else if (strncmp(option, "noH", 3) == 0) { - res.pfcode &= ~(RES_PRF_HEADX); - } else if (strncmp(option, "qr", 2) == 0) { /* query */ - res.pfcode |= RES_PRF_QUERY; - } else if (strncmp(option, "noqr", 4) == 0) { - res.pfcode &= ~RES_PRF_QUERY; - } else if (strncmp(option, "rep", 3) == 0) { /* reply */ - res.pfcode |= RES_PRF_REPLY; - } else if (strncmp(option, "norep", 5) == 0) { - res.pfcode &= ~RES_PRF_REPLY; - } else if (strncmp(option, "cm", 2) == 0) { /* command line */ - res.pfcode |= RES_PRF_CMD; - } else if (strncmp(option, "nocm", 4) == 0) { - res.pfcode &= ~RES_PRF_CMD; - } else if (strncmp(option, "cl", 2) == 0) { /* class mnemonic */ - res.pfcode |= RES_PRF_CLASS; - } else if (strncmp(option, "nocl", 4) == 0) { - res.pfcode &= ~RES_PRF_CLASS; - } else if (strncmp(option, "st", 2) == 0) { /* stats*/ - res.pfcode |= RES_PRF_STATS; - } else if (strncmp(option, "nost", 4) == 0) { - res.pfcode &= ~RES_PRF_STATS; - } else { - fprintf(stderr, "; *** Invalid option: %s\n", option); - return (ERROR); - } - res_re_init(); - return (SUCCESS); -} - -/* - * Force a reinitialization when the domain is changed. - */ -static void -res_re_init() { - static char localdomain[] = "LOCALDOMAIN"; - u_long pfcode = res.pfcode, options = res.options; - unsigned ndots = res.ndots; - int retrans = res.retrans, retry = res.retry; - char *buf; - - /* - * This is ugly but putenv() is more portable than setenv(). - */ - buf = malloc((sizeof localdomain) + strlen(res.defdname) +10/*fuzz*/); - sprintf(buf, "%s=%s", localdomain, res.defdname); - putenv(buf); /* keeps the argument, so we won't free it */ - res_ninit(&res); - res.pfcode = pfcode; - res.options = options; - res.ndots = ndots; - res.retrans = retrans; - res.retry = retry; -} - -/* - * convert char string (decimal, octal, or hex) to integer - */ -static int -xstrtonum(char *p) { - int v = 0; - int i; - int b = 10; - int flag = 0; - while (*p != 0) { - if (!flag++) - if (*p == '0') { - b = 8; p++; - continue; - } - if (isupper(*p)) - *p = tolower(*p); - if (*p == 'x') { - b = 16; p++; - continue; - } - if (isdigit(*p)) { - i = *p - '0'; - } else if (isxdigit(*p)) { - i = *p - 'a' + 10; - } else { - fprintf(stderr, - "; *** Bad char in numeric string..ignored\n"); - i = -1; - } - if (i >= b) { - fprintf(stderr, - "; *** Bad char in numeric string..ignored\n"); - i = -1; - } - if (i >= 0) - v = v * b + i; - p++; - } - return (v); -} - -typedef union { - HEADER qb1; - u_char qb2[PACKETSZ]; -} querybuf; - -static int -printZone(ns_type xfr, const char *zone, const struct sockaddr_in *sin, - ns_tsig_key *key) -{ - static u_char *answer = NULL; - static int answerLen = 0; - - querybuf buf; - HEADER *headerPtr; - int msglen, amtToRead, numRead, result = 0, sockFD, len; - int count, type, class, rlen, done, n; - int numAnswers = 0, numRecords = 0, soacnt = 0; - u_char *cp, tmp[NS_INT16SZ]; - char dname[2][NS_MAXDNAME], file[NAME_LEN]; - enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING } - error = NO_ERRORS; - pid_t zpid; - u_char *newmsg; - int newmsglen; - ns_tcp_tsig_state tsig_state; - int tsig_ret, tsig_required, tsig_present; - - switch (xfr) { - case ns_t_axfr: - case ns_t_zxfr: - break; - default: - fprintf(stderr, ";; %s - transfer type not supported\n", - p_type(xfr)); - return (ERROR); - } - - /* - * Create a query packet for the requested zone name. - */ - msglen = res_nmkquery(&res, ns_o_query, zone, - queryClass, ns_t_axfr, NULL, - 0, 0, buf.qb2, sizeof buf); - if (msglen < 0) { - if (res.options & RES_DEBUG) - fprintf(stderr, ";; res_nmkquery failed\n"); - return (ERROR); - } - - /* - * Sign the message if a key was sent - */ - if (key == NULL) { - newmsg = (u_char *)&buf; - newmsglen = msglen; - } else { - DST_KEY *dstkey; - int bufsize, siglen; - u_char sig[64]; - int ret; - - /* ns_sign() also calls dst_init(), but there is no harm - * doing it twice - */ - dst_init(); - - bufsize = msglen + 1024; - newmsg = (u_char *) malloc(bufsize); - if (newmsg == NULL) { - errno = ENOMEM; - return (-1); - } - memcpy(newmsg, (u_char *)&buf, msglen); - newmsglen = msglen; - - if (strcmp(key->alg, NS_TSIG_ALG_HMAC_MD5) != 0) - dstkey = NULL; - else - dstkey = dst_buffer_to_key(key->name, KEY_HMAC_MD5, - NS_KEY_TYPE_AUTH_ONLY, - NS_KEY_PROT_ANY, - key->data, key->len); - if (dstkey == NULL) { - errno = EINVAL; - if (key) - free(newmsg); - return (-1); - } - - siglen = sizeof(sig); -/* newmsglen++; */ - ret = ns_sign(newmsg, &newmsglen, bufsize, NOERROR, dstkey, NULL, 0, - sig, &siglen, 0); - if (ret < 0) { - if (key) - free (newmsg); - if (ret == NS_TSIG_ERROR_NO_SPACE) - errno = EMSGSIZE; - else if (ret == -1) - errno = EINVAL; - return (ret); - } - ns_verify_tcp_init(dstkey, sig, siglen, &tsig_state); - } - - /* - * Set up a virtual circuit to the server. - */ - if ((sockFD = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) { - int e = errno; - - perror(";; socket"); - return (e); - } - if (bind(sockFD, (struct sockaddr *)&myaddress, sizeof myaddress) < 0){ - int e = errno; - - fprintf(stderr, ";; bind(%s:%u): %s\n", - inet_ntoa(myaddress.sin_addr), - ntohs(myaddress.sin_port), - strerror(e)); - (void) close(sockFD); - sockFD = -1; - return (e); - } - if (connect(sockFD, (struct sockaddr *)sin, sizeof *sin) < 0) { - int e = errno; - - perror(";; connect"); - (void) close(sockFD); - sockFD = -1; - return (e); - } - - /* - * Send length & message for zone transfer - */ - - ns_put16(newmsglen, tmp); - if (write(sockFD, (char *)tmp, NS_INT16SZ) != NS_INT16SZ || - write(sockFD, (char *)newmsg, newmsglen) != newmsglen) { - int e = errno; - if (key) - free (newmsg); - perror(";; write"); - (void) close(sockFD); - sockFD = -1; - return (e); - } - - /* - * If we're compressing, push a gzip into the pipeline. - */ - if (xfr == ns_t_zxfr) { - enum { rd = 0, wr = 1 }; - int z[2]; - - if (pipe(z) < 0) { - int e = errno; - if (key) - free (newmsg); - - perror(";; pipe"); - (void) close(sockFD); - sockFD = -1; - return (e); - } - zpid = vfork(); - if (zpid < 0) { - int e = errno; - if (key) - free (newmsg); - - perror(";; fork"); - (void) close(sockFD); - sockFD = -1; - return (e); - } else if (zpid == 0) { - /* Child. */ - (void) close(z[rd]); - (void) dup2(sockFD, STDIN_FILENO); - (void) close(sockFD); - (void) dup2(z[wr], STDOUT_FILENO); - (void) close(z[wr]); - execlp("gzip", "gzip", "-d", "-v", NULL); - perror(";; child: execlp(gunzip)"); - _exit(1); - } - /* Parent. */ - (void) close(z[wr]); - (void) dup2(z[rd], sockFD); - (void) close(z[rd]); - } - - dname[0][0] = '\0'; - for (done = 0; !done; (void)NULL) { - /* - * Read the length of the response. - */ - - cp = tmp; - amtToRead = INT16SZ; - while (amtToRead > 0 && - (numRead = read(sockFD, cp, amtToRead)) > 0) { - cp += numRead; - amtToRead -= numRead; - } - if (numRead <= 0) { - error = ERR_READING_LEN; - break; - } - - len = ns_get16(tmp); - if (len == 0) - break; /* nothing left to read */ - - /* - * The server sent too much data to fit the existing buffer -- - * allocate a new one. - */ - if (len > answerLen) { - if (answerLen != 0) - free(answer); - answerLen = len; - answer = (u_char *)Malloc(answerLen); - } - - /* - * Read the response. - */ - - amtToRead = len; - cp = answer; - while (amtToRead > 0 && - (numRead = read(sockFD, cp, amtToRead)) > 0) { - cp += numRead; - amtToRead -= numRead; - } - if (numRead <= 0) { - error = ERR_READING_MSG; - break; - } - - result = print_axfr(stdout, answer, len); - if (result != 0) { - error = ERR_PRINTING; - break; - } - numRecords += htons(((HEADER *)answer)->ancount); - numAnswers++; - - /* Header. */ - cp = answer + HFIXEDSZ; - /* Question. */ - for (count = ntohs(((HEADER *)answer)->qdcount); - count > 0; - count--) { - n = dn_skipname(cp, answer + len); - if (n < 0) { - error = ERR_PRINTING; - done++; - break; - } - cp += n + QFIXEDSZ; - if (cp > answer + len) { - error = ERR_PRINTING; - done++; - break; - } - } - /* Answer. */ - for (count = ntohs(((HEADER *)answer)->ancount); - count > 0 && !done; - count--) { - n = dn_expand(answer, answer + len, cp, - dname[soacnt], sizeof dname[0]); - if (n < 0) { - error = ERR_PRINTING; - done++; - break; - } - cp += n; - if (cp + 3 * INT16SZ + INT32SZ > answer + len) { - error = ERR_PRINTING; - done++; - break; - } - GETSHORT(type, cp); - GETSHORT(class, cp); - cp += INT32SZ; /* ttl */ - GETSHORT(rlen, cp); - cp += rlen; - if (cp > answer + len) { - error = ERR_PRINTING; - done++; - break; - } - if (type == T_SOA && soacnt++ && - ns_samename(dname[0], dname[1]) == 1) { - done++; - break; - } - } - - /* - * Verify the TSIG - */ - - if (key) { - if (ns_find_tsig(answer, answer + len) != NULL) - tsig_present = 1; - else - tsig_present = 0; - if (numAnswers == 1 || soacnt > 1) - tsig_required = 1; - else - tsig_required = 0; - tsig_ret = ns_verify_tcp(answer, &len, &tsig_state, - tsig_required); - if (tsig_ret == 0) { - if (tsig_present) - printf("; TSIG ok\n"); - } - else - printf("; TSIG invalid\n"); - } - - } - - printf(";; Received %d answer%s (%d record%s).\n", - numAnswers, (numAnswers != 1) ? "s" : "", - numRecords, (numRecords != 1) ? "s" : ""); - - (void) close(sockFD); - sockFD = -1; - - /* - * If we were uncompressing, reap the uncompressor. - */ - if (xfr == ns_t_zxfr) { - pid_t pid; - int status; - - pid = wait(&status); - if (pid < 0) { - int e = errno; - - perror(";; wait"); - return (e); - } - if (pid != zpid) { - fprintf(stderr, ";; wrong pid (%lu != %lu)\n", - (u_long)pid, (u_long)zpid); - return (ERROR); - } - printf(";; pid %lu: exit %d, signal %d, core %c\n", - pid, WEXITSTATUS(status), - WIFSIGNALED(status) ? WTERMSIG(status) : 0, - WCOREDUMP(status) ? 't' : 'f'); - } - - /* XXX This should probably happen sooner than here */ - if (key) - free (newmsg); - - switch (error) { - case NO_ERRORS: - return (0); - - case ERR_READING_LEN: - return (EMSGSIZE); - - case ERR_PRINTING: - return (result); - - case ERR_READING_MSG: - return (EMSGSIZE); - - default: - return (EFAULT); - } -} - -static int -print_axfr(FILE *file, const u_char *msg, size_t msglen) { - ns_msg handle; - - if (ns_initparse(msg, msglen, &handle) < 0) { - fprintf(file, ";; ns_initparse: %s\n", strerror(errno)); - return (ns_r_formerr); - } - if (ns_msg_getflag(handle, ns_f_rcode) != ns_r_noerror) - return (ns_msg_getflag(handle, ns_f_rcode)); - - /* - * We are looking for info from answer resource records. - * If there aren't any, return with an error. We assume - * there aren't any question records. - */ - if (ns_msg_count(handle, ns_s_an) == 0) - return (NO_INFO); - -#ifdef PROTOCOLDEBUG - printf(";;; (message of %d octets has %d answers)\n", - msglen, ns_msg_count(handle, ns_s_an)); -#endif - for (;;) { - static char origin[NS_MAXDNAME], name_ctx[NS_MAXDNAME]; - const char *name; - char buf[2048]; /* XXX need to malloc/realloc. */ - ns_rr rr; - - if (ns_parserr(&handle, ns_s_an, -1, &rr)) { - if (errno != ENODEV) { - fprintf(file, ";; ns_parserr: %s\n", - strerror(errno)); - return (FORMERR); - } - break; - } - name = ns_rr_name(rr); - if (origin[0] == '\0' && name[0] != '\0') { - if (strcmp(name, ".") != 0) - strcpy(origin, name); - fprintf(file, "$ORIGIN %s.\n", origin); - if (strcmp(name, ".") == 0) - strcpy(origin, name); - strcpy(name_ctx, "@"); - } - if (ns_sprintrr(&handle, &rr, name_ctx, origin, - buf, sizeof buf) < 0) { - fprintf(file, ";; ns_sprintrr: %s\n", strerror(errno)); - return (FORMERR); - } - strcpy(name_ctx, name); - fputs(buf, file); - fputc('\n', file); - } - return (SUCCESS); -} - -static struct timeval -difftv(struct timeval a, struct timeval b) { - static struct timeval diff; - - diff.tv_sec = b.tv_sec - a.tv_sec; - if ((diff.tv_usec = b.tv_usec - a.tv_usec) < 0) { - diff.tv_sec--; - diff.tv_usec += 1000000; - } - return (diff); -} - -static void -prnttime(struct timeval t) { - printf("%lu msec", (u_long)(t.tv_sec * 1000 + (t.tv_usec / 1000))); -} - -/* - * Take arguments appearing in simple string (from file or command line) - * place in char**. - */ -static void -stackarg(char *l, char **y) { - int done = 0; - - while (!done) { - switch (*l) { - case '\t': - case ' ': - l++; - break; - case '\0': - case '\n': - done++; - *y = NULL; - break; - default: - *y++ = l; - while (!isspace(*l)) - l++; - if (*l == '\n') - done++; - *l++ = '\0'; - *y = NULL; - } - } -} diff --git a/contrib/bind/bin/dnskeygen/Makefile b/contrib/bind/bin/dnskeygen/Makefile deleted file mode 100644 index 232a20623c1ed..0000000000000 --- a/contrib/bind/bin/dnskeygen/Makefile +++ /dev/null @@ -1,86 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 1.6 2000/07/11 06:41:28 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -AR= ar cru -INSTALL= install -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -PS=ps -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -PROG= dnskeygen -SRCS= dnskeygen.c -OBJS= dnskeygen.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} \ - ${LIBBIND} ${SYSLIBS} -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${SRCS} - -${DESTDIR}${DESTEXEC}: - mkdir -p ${DESTDIR}${DESTEXEC} - -install: ${DESTDIR}${DESTEXEC} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTEXEC}/${PROG}${EXE} - -links: FRC - @set -e; ln -s SRC/*.[ch] . - -tags: FRC - ctags ${SRCS} *.h - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/dnskeygen/dnskeygen.c b/contrib/bind/bin/dnskeygen/dnskeygen.c deleted file mode 100644 index c30eae748f70b..0000000000000 --- a/contrib/bind/bin/dnskeygen/dnskeygen.c +++ /dev/null @@ -1,318 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: dnskeygen.c,v 1.9 1999/10/13 16:38:59 vixie Exp $"; -#endif /* not lint */ - -/* - * Portions Copyright (c) 1995-1999 by TISLabs at Network Associates, Inc. - * - * Permission to use, copy modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. - */ - -#include "port_before.h" - -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include "arpa/nameser.h" - -#include <isc/dst.h> - -#include "port_after.h" - -#define PRINT_SUPPORTED 2 - -static void usage(char *str, int full); - -static short dsa_sizes[] = {512, 576, 640, 704, 768, 832, 896, 960, 1024, 0}; -static char *prog; - -int -main(int argc, char **argv) { - DST_KEY *pubkey; - char *name=NULL; - int ch; - char str[128]; - int alg = 0; - int zone_key = 0, user_key = 0, end_key = 0, key_type = 0; - int size = -1, exp = 0; - int no_auth = 0, no_conf = 0; - int sign_val = 0, flags = 0, protocol = -1; - int i, err = 0, n; - extern char *optarg; - char array[1024]; - - dst_init(); - if ((prog = strrchr(argv[0],'/')) == NULL) - prog = strdup(argv[0]); - else - prog = strdup(++prog); - -/* process input arguments */ - while ((ch = getopt(argc, argv, "achiuzn:s:p:D:H:R:F"))!= -1) { - switch (ch) { - case 'a': - no_auth = NS_KEY_NO_AUTH; - break; - case 'c': - no_conf = NS_KEY_NO_CONF; - break; - case 'F': - exp=1; - break; - case 'n': - if (optarg) - name = strdup(optarg); - else - usage("-n not followed by name", 0); - i = strlen(name); - if (name[i-1] != '.') { - printf("** Adding dot to the name to make it" - " fully qualified domain name**\n"); - free(name); - name = malloc(i+2); - strcpy(name, optarg); - strcat(name, "."); - } - break; - case 'p': - if (optarg && isdigit(optarg[0])) - protocol = atoi(optarg); - else - usage("-p flag not followed by a number", 0); - break; - case 's': - /* Default: not signatory key */ - if (optarg && isdigit(optarg[0])) - sign_val = (int) atoi(optarg); - else - usage("-s flag requires a value",0); - break; - case 'h': - end_key = NS_KEY_NAME_ENTITY; - key_type++; - break; - case 'u' : - user_key = NS_KEY_NAME_USER; - key_type++; - break ; - case 'z': - zone_key = NS_KEY_NAME_ZONE; - key_type++; - break; - case 'H': - if (optarg && isdigit(optarg[0])) - size = (int) atoi(optarg); - else - usage("-H flag requires a size",0); - if (alg != 0) - usage("Only ONE alg can be specified", 1); - alg = KEY_HMAC_MD5; - if (!dst_check_algorithm(alg)) - usage("Algorithm HMAC-MD5 not available", - PRINT_SUPPORTED); - break; - case 'R': - if (optarg && isdigit(optarg[0])) - size = (int) atoi(optarg); - else - usage("-R flag requires a size",0); - if (alg != 0) - usage("Only ONE alg can be specified", 1); - alg = NS_ALG_MD5RSA; - if (!dst_check_algorithm(alg)) - usage("Algorithm RSA not available", - PRINT_SUPPORTED); - break; - case 'D': - if (optarg && isdigit(optarg[0])) - size = (int) atoi(optarg); - else - usage("-D flag requires a size", 0); - if (alg != 0) - usage("Only ONE alg can be specified", 1); - alg = NS_ALG_DSS; - if (dst_check_algorithm(alg) == 0) - usage("Algorithm DSS not available", - PRINT_SUPPORTED); - break; - default: - err++; - } /* switch */ - } /* while (getopt) */ - - /* - * Command line parsed make sure required parameters are present - */ - if (name == NULL) - usage("No key name specified -n <name>", 1); - - if (alg == 0) - usage("No algorithm specififed -{DHR}", 1); - - if (key_type == 0) - usage("Key type -{zhu} must be specified", 1); - else if (key_type > 1) - usage("Only one key type -{zhu} must be specified", 1); - - if (alg == NS_ALG_DSS) - no_conf = NS_KEY_NO_CONF; /* dss keys can not encrypt */ - - if (protocol == -1) { - if (zone_key || end_key) - protocol = NS_KEY_PROT_DNSSEC; - else - protocol = NS_KEY_PROT_EMAIL; - } - if (protocol < 0 || protocol > 255) - usage("Protocol value out of range [0..255]", 0); - - if (sign_val < 0 || sign_val > 15) { - sprintf(str, "%s: Signatory value %d out of range[0..15]\n", - prog, sign_val); - usage(str, 0); - } - /* if any of bits 321 is set bit 0 can not be set*/ - if (sign_val & 0xe) - sign_val &= 0xe; - - /* if a zone key make sure at least one of the signer flags is set */ - if ((protocol == NS_KEY_PROT_DNSSEC) && (sign_val == 0)) - sign_val = 0x01; - - if (no_auth && no_conf) { /* null key specified */ - if (sign_val > 0) - sign_val = 0x0; /* null key can not sign */ - if (size > 0) - size = 0; /* null key must have size 0 */ - } - - if (size > 0) { - if (alg == NS_ALG_MD5RSA){ - if (size < 512 || size > 4096) - usage("Size out of range", 1); - } - else if (exp) - usage("-F can only be specified with -R", 0); - if (alg == NS_ALG_DSS) { - for (i = 0; dsa_sizes[i]; i++) - if (size <= dsa_sizes[i]) - break; - if (size != dsa_sizes[i]) - usage("Invalid DSS key size", 1); - } - } - else if (size < 0) - usage("No size specified", 0); - - if (err) - usage("errors encountered/unknown flag", 1); - - flags = no_conf | no_auth | end_key | user_key | zone_key | sign_val; - -/* process defaults */ -#ifdef WARN_NONZONE_SIGNER - if (signer && (user_key | end_key)) - printf("Warning: User/End key is allowed to sign\n"); -#endif - - /* create a public/private key pair */ - if (alg == NS_ALG_MD5RSA) - printf("Generating %d bit RSA Key for %s\n\n",size, name); - else if (alg == NS_ALG_DSS) - printf("Generating %d bit DSS Key for %s\n\n",size, name); - else if (alg == KEY_HMAC_MD5) - printf("Generating %d bit HMAC-MD5 Key for %s\n\n", - size, name); - - /* Make the key - * dst_generate_key_pair will place result in files that it - * knows about K<name><foot>.public and K<name><foot>.private - */ - pubkey = dst_generate_key(name, size, exp, flags, protocol, alg); - - if (pubkey == NULL) { - printf("Failed generating key for %s\n", name); - exit(12); - } - - if (dst_write_key(pubkey, DST_PRIVATE) < 0) { - printf ("Failed to write private key for %s %d %d\n", - name, pubkey->dk_id, pubkey->dk_alg); - exit(12); - } - - if (dst_write_key(pubkey, DST_PUBLIC) <= 0) { - if (access(name, F_OK)) - printf("Not allowed to overwrite existing file\n"); - else - printf("Failed to write public key for %s %d %d\n", - name, pubkey->dk_id, pubkey->dk_alg); - exit(12); - } - - printf("Generated %d bit Key for %s id=%d alg=%d flags=%d\n\n", - size, name, pubkey->dk_id, pubkey->dk_alg, - pubkey->dk_flags); - exit(0); -} - -static void -usage(char *str, int flag){ - int i; - printf ("\nNo key generated\n"); - if (*str != '\0') - printf("Usage:%s: %s\n",prog, str); - printf("Usage:%s -{DHR} <size> [-F] -{zhu} [-ac] [-p <no>]" - " [-s <no>] -n name\n", prog); - if (flag == 0) - exit(2); - printf("\t-D generate DSA/DSS KEY: size must be one of following:\n"); - printf("\t\t"); - for(i = 0; dsa_sizes[i] > 0; i++) - printf(" %d,", dsa_sizes[i]); - printf("\n"); - printf("\t-H generate HMAC-MD5 KEY: size in the range [1..512]:\n"); - printf("\t-R generate RSA KEY: size in the range [512..4096]\n"); - printf("\t-F RSA KEYS only: use large exponent\n"); - - printf("\t-z Zone key \n"); - printf("\t-h Host/Entity key \n"); - printf("\t-u User key \n"); - - printf("\t-a Key CANNOT be used for authentication\n"); - printf("\t-c Key CANNOT be used for encryption\n"); - - printf("\t-p Set protocol field to <no>\n"); - printf("\t\t default: 2 (email) for Host keys, 3 (dnssec) for all others\n"); - printf("\t-s Strength value this key signs DNS records with\n"); - printf("\t\t default: 1 for Zone keys, 0 for all others\n"); - printf("\t-n name: the owner of the key\n"); - - if (flag == PRINT_SUPPORTED) { - printf("Available algorithms are:"); - if (dst_check_algorithm(NS_ALG_MD5RSA) == 1) - printf(" RSA"); - if (dst_check_algorithm(NS_ALG_DSS) == 1) - printf(" DSS"); - if (dst_check_algorithm(KEY_HMAC_MD5) == 1) - printf(" HMAC-MD5"); - printf("\n"); - } - - exit (-3); -} - - diff --git a/contrib/bind/bin/dnsquery/Makefile b/contrib/bind/bin/dnsquery/Makefile deleted file mode 100644 index 511cb664d7558..0000000000000 --- a/contrib/bind/bin/dnsquery/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 8.25 2000/07/11 06:41:29 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -EXE= -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -PROG= dnsquery -SRCS= ${PROG}.c -OBJS= ${PROG}.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} \ - ${LIBBIND} ${SYSLIBS} - -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${SRCS} - -${DESTDIR}${DESTBIN}: - mkdir -p ${DESTDIR}${DESTBIN} - -install: ${DESTDIR}${DESTBIN} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTBIN}/${PROG}${EXE} - -links: FRC - @set -e; ln -s SRC/*.[ch] . - -tags: FRC - ctags *.[ch] - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/dnsquery/dnsquery.c b/contrib/bind/bin/dnsquery/dnsquery.c deleted file mode 100644 index 218c8a8a4e8a1..0000000000000 --- a/contrib/bind/bin/dnsquery/dnsquery.c +++ /dev/null @@ -1,210 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: dnsquery.c,v 8.13 1999/10/13 16:38:59 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996,1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <netdb.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "port_after.h" - -extern int errno; -extern int h_errno; -extern char *h_errlist[]; - -struct __res_state res; - -int -main(int argc, char *argv[]) { - char name[MAXDNAME]; - u_char answer[8*1024]; - int c, n, i = 0; - u_int32_t ul; - int nameservers = 0, class, type, len; - struct in_addr q_nsaddr[MAXNS]; - struct hostent *q_nsname; - extern int optind, opterr; - extern char *optarg; - HEADER *hp; - int stream = 0, debug = 0; - - /* set defaults */ - len = MAXDNAME; - gethostname(name, len); - class = C_IN; - type = T_ANY; - - /* if no args, exit */ - if (argc == 1) { - fprintf(stderr, "Usage: %s [-h] host [-n ns] [-t type] [-c class] [-r retry] [-p period] [-s] [-v] [-d] [-a]\n", argv[0]); - exit(-1); - } - - /* handle args */ - while ((c = getopt(argc, argv, "c:dh:n:p:r:st:u:v")) != -1) { - switch (c) { - - case 'r' : res.retry = atoi(optarg); - break; - - case 'p' : res.retrans = atoi(optarg); - break; - - case 'h' : strcpy(name, optarg); - break; - - case 'c' : { - int success, proto_class; - - proto_class = sym_ston(__p_class_syms, - optarg, &success); - if (success) - class = proto_class; - else { - fprintf(stderr, "Bad class (%s)\n", optarg); - exit(-1); - } - } - break; - - case 't' : { - int success, proto_type; - - proto_type = sym_ston(__p_type_syms, - optarg, &success); - if (success) - type = proto_type; - else { - fprintf(stderr, "Bad type (%s)\n", optarg); - exit(-1); - } - } - break; - - case 'd' : debug++; - break; - - case 's' : - case 'v' : stream++; - break; - - case 'n' : - /* - * If we set some nameservers here without - * using gethostbyname() first, then they will - * get overwritten when we do the first query. - * So, we must init the resolver before any - * of this. - */ - if (!(res.options & RES_INIT)) - if (res_ninit(&res) == -1) { - fprintf(stderr, - "res_ninit() failed\n" - ); - exit(-1); - } - if (nameservers >= MAXNS) break; - (void) inet_aton(optarg, - &q_nsaddr[nameservers]); - if (!inet_aton(optarg, (struct in_addr *)&ul)){ - q_nsname = gethostbyname(optarg); - if (q_nsname == 0) { - fprintf(stderr, - "Bad nameserver (%s)\n", - optarg); - exit(-1); - } - memcpy(&q_nsaddr[nameservers], - q_nsname->h_addr, INADDRSZ); - } - else - q_nsaddr[nameservers].s_addr = ul; - nameservers++; - break; - - default : fprintf(stderr, - "\tUsage: %s [-n ns] [-h host] [-t type] [-c class] [-r retry] [-p period] [-s] [-v] [-d] [-a]\n", argv[0]); - exit(-1); - } - } - if (optind < argc) - strcpy(name, argv[optind]); - - len = sizeof(answer); - - if (!(res.options & RES_INIT)) - if (res_ninit(&res) == -1) { - fprintf(stderr, "res_ninit() failed\n"); - exit(-1); - } - - /* - * set these here so they aren't set for a possible call to - * gethostbyname above - */ - if (debug) - res.options |= RES_DEBUG; - if (stream) - res.options |= RES_USEVC; - - /* if the -n flag was used, add them to the resolver's list */ - if (nameservers != 0) { - res.nscount = nameservers; - for (i = nameservers - 1; i >= 0; i--) { - res.nsaddr_list[i].sin_addr.s_addr = q_nsaddr[i].s_addr; - res.nsaddr_list[i].sin_family = AF_INET; - res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT); - } - } - - /* - * if the -h arg is fully-qualified, use res_query() since - * using res_search() will lead to use of res_querydomain() - * which will strip the trailing dot - */ - if (name[strlen(name) - 1] == '.') { - n = res_nquery(&res, name, class, type, answer, len); - if (n < 0) { - fprintf(stderr, "Query failed (h_errno = %d) : %s\n", - h_errno, h_errlist[h_errno]); - exit(-1); - } - } else if ((n = res_nsearch(&res, name, class, type, - answer, len)) < 0) { - fprintf(stderr, "Query failed (h_errno = %d) : %s\n", - h_errno, h_errlist[h_errno]); - exit(-1); - } - res_pquery(&res, answer, n, stdout); - exit(0); -} diff --git a/contrib/bind/bin/host/Makefile b/contrib/bind/bin/host/Makefile deleted file mode 100644 index b4f07ad157022..0000000000000 --- a/contrib/bind/bin/host/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 8.25 2000/07/11 06:41:29 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -EXE= -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -PROG= host -SRCS= ${PROG}.c -OBJS= ${PROG}.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} \ - ${LIBBIND} ${SYSLIBS} - -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${SRCS} - -${DESTDIR}${DESTBIN}: - mkdir -p ${DESTDIR}${DESTBIN} - -install: ${DESTDIR}${DESTBIN} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTBIN}/${PROG}${EXE} - -links: FRC - @set -e; ln -s SRC/*.[ch] . - -tags: FRC - ctags *.[ch] - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/host/host.c b/contrib/bind/bin/host/host.c deleted file mode 100644 index 77e5329224aea..0000000000000 --- a/contrib/bind/bin/host/host.c +++ /dev/null @@ -1,1954 +0,0 @@ -#ifndef lint -static const char rcsid[] = "$Id: host.c,v 8.37 2000/07/11 07:06:14 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1986 Regents of the University of California.\n\ - Portions Copyright (c) 1993 Digital Equipment Corporation.\n\ - Portions Copyright (c) 1996-1999 Internet Software Consortium.\n\ - All rights reserved.\n"; -#endif /* not lint */ - -/* - * Actually, this program is from Rutgers University, however it is - * based on nslookup and other pieces of named tools, so it needs - * the above copyright notices. - */ - -/* Import. */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <ctype.h> -#include <netdb.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <memory.h> -#include <errno.h> -#include <sys/stat.h> -#include <isc/dst.h> - -#include "port_after.h" - -/* Global. */ - -#define SIG_RDATA_BY_NAME 18 -#define NS_HEADERDATA_SIZE 10 - -#define NUMNS 8 -#define NUMNSADDR 16 -#define NUMMX 50 -#define NUMRR 127 /* max rr's per node to verify signatures for */ - -#define SUCCESS 0 -#define TIME_OUT -1 -#define NO_INFO -2 -#define ERROR -3 -#define NONAUTH -4 - -#define MY_PACKETSZ 64*1024 /* need this to hold tcp answers */ - -typedef union { - HEADER qb1; - u_char qb2[MY_PACKETSZ]; -} querybuf; - -#define SD_RR 1 -#define SD_SIG 2 -#define SD_BADSIG 4 - -typedef struct { - u_char data[MY_PACKETSZ]; - size_t len; -} rrstruct; - -static char chase_domain[NS_MAXDNAME]; -static int chase_class; -static int chase_type; -static char chase_sigorigttl[NS_INT32SZ]; -static rrstruct chase_rr[NUMRR]; -static int chase_rr_num; -static char chase_lastgoodkey[NS_MAXDNAME]; -static char chase_signer[NS_MAXDNAME]; -static u_char chase_sigrdata[MY_PACKETSZ]; -static size_t chase_sigrdata_len; -static u_char chase_signature[MY_PACKETSZ]; -static size_t chase_signature_len; -static int chase_step; -static int sigchase; - -static char cnamebuf[NS_MAXDNAME]; -static u_char hostbuf[NS_MAXDNAME]; - -static int sockFD; -static FILE *filePtr; - -static struct __res_state res, orig; -static char *cname = NULL; -static const char *progname = "amnesia"; -static int getclass = ns_c_in, verbose = 0, list = 0; -static int server_specified = 0; -static int gettype = 0; -static char getdomain[NS_MAXDNAME]; - -/* Forward. */ - -static int parsetype(const char *s); -static int parseclass(const char *s); -static void printanswer(const struct hostent *hp); -static void hperror(int errnum); -static int addrinfo(struct in_addr addr); -static int gethostinfo(char *name); -static int getdomaininfo(const char *name, const char *domain); -static int getinfo(const char *name, const char *domain, - int type); -static int printinfo(const querybuf *answer, const u_char *eom, - int filter, int isls); -static const u_char * pr_rr(const u_char *cp, const u_char *msg, FILE *file, - int filter); -static const char * pr_type(int type); -static const char * pr_class(int class); -static const u_char * pr_cdname(const u_char *cp, const u_char *msg, - char *name, int namelen); -static int ListHosts(char *namePtr, int queryType); -static const char * DecodeError(int result); - -static void -usage(const char *msg) { - fprintf(stderr, "%s: usage error (%s)\n", progname, msg); - fprintf(stderr, "\ -Usage: %s [-adlrwv] [-t querytype] [-c class] host [server]\n\ -\t-a is equivalent to '-v -t *'\n\ -\t-c class to look for non-Internet data\n\ -\t-d to turn on debugging output\n\ -\t-l to turn on 'list mode'\n\ -\t-r to disable recursive processing\n\ -\t-s recursively chase signature found in answers\n\ -\t-t querytype to look for a specific type of information\n\ -\t-v for verbose output\n\ -\t-w to wait forever until reply\n\ -", progname); - exit(1); -} - -/* Public. */ - -int -main(int argc, char **argv) { - struct in_addr addr; - struct hostent *hp; - char *s; - int inverse = 0, waitmode = 0; - int ncnames, ch; - int nkeychains, i; - - dst_init(); - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - progname++; - res_ninit(&res); - res.retrans = 5; - while ((ch = getopt(argc, argv, "ac:dlrst:vw")) != -1) { - switch (ch) { - case 'a': - verbose = 1; - gettype = ns_t_any; - break; - case 'c': - getclass = parseclass(optarg); - break; - case 'd': - res.options |= RES_DEBUG; - break; - case 'l': - list = 1; - break; - case 'r': - res.options &= ~RES_RECURSE; - break; - case 's': - sigchase = 1; - break; - case 't': - gettype = parsetype(optarg); - break; - case 'v': - verbose = 1; - break; - case 'w': - res.retry = 1; - res.retrans = 15; - waitmode = 1; - break; - default: - usage("unrecogized switch"); - /*NOTREACHED*/ - } - } - if ((gettype == 0) && (sigchase)) { - if (verbose) - printf ("Forcing `-t a' for signature trace.\n"); - gettype = ns_t_a; - } - argc -= optind; - argv += optind; - if (argc < 1) - usage("missing host argument"); - strncpy(getdomain, *argv++, NS_MAXDNAME); - getdomain[NS_MAXDNAME-1] = 0; - argc--; - if (argc > 1) - usage("extra undefined arguments"); - if (argc == 1) { - s = *argv++; - argc--; - server_specified++; - - if (!inet_aton(s, &addr)) { - hp = gethostbyname(s); - if (hp == NULL) { - fprintf(stderr, - "Error in looking up server name:\n"); - hperror(res.res_h_errno); - exit(1); - } - memcpy(&res.nsaddr.sin_addr, hp->h_addr, NS_INADDRSZ); - printf("Using domain server:\n"); - printanswer(hp); - } else { - res.nsaddr.sin_family = AF_INET; - res.nsaddr.sin_addr = addr; - res.nsaddr.sin_port = htons(NAMESERVER_PORT); - printf("Using domain server %s:\n", - inet_ntoa(res.nsaddr.sin_addr)); - } - res.nscount = 1; - res.retry = 2; - } - if (strcmp(getdomain, ".") == 0 || !inet_aton(getdomain, &addr)) - addr.s_addr = INADDR_NONE; - hp = NULL; - res.res_h_errno = TRY_AGAIN; -/* - * We handle default domains ourselves, thank you. - */ - res.options &= ~RES_DEFNAMES; - - if (list) - exit(ListHosts(getdomain, gettype ? gettype : ns_t_a)); - ncnames = 5; nkeychains = 18; - while (hp == NULL && res.res_h_errno == TRY_AGAIN) { - if (addr.s_addr == INADDR_NONE) { - cname = NULL; - hp = (struct hostent *)gethostinfo(getdomain); - getdomain[0] = 0; /* clear this query */ - if (sigchase && (chase_step & SD_RR)) { - if (nkeychains-- == 0) { - printf("Too many sig/key chains. Loop?\n"); - exit(1); - } - if (chase_step & SD_SIG) { - /* start new query, for KEY */ - strcpy (getdomain, chase_signer); - strcat (getdomain, "."); - gettype = ns_t_key; - } else if (!(chase_step & SD_BADSIG)) { - /* start new query, for SIG */ - strcpy (getdomain, chase_domain); - strcat (getdomain, "."); - gettype = ns_t_sig; - } else if (hp && !(chase_step & SD_SIG) && - (chase_step & SD_BADSIG)) { - printf ("%s for %s not found, last verified key %s\n", - chase_step & SD_SIG ? "Key" : "Signature", - chase_step & SD_SIG ? chase_signer : chase_domain, - chase_domain, - chase_lastgoodkey ? chase_lastgoodkey : "None"); - } - } - if (!getdomain[0] && cname) { - if (ncnames-- == 0) { - printf("Too many cnames. Loop?\n"); - exit(1); - } - strcpy(getdomain, cname); - strcat(getdomain, "."); - } - if (getdomain[0]) { - if (chase_step & SD_SIG) { - printf ("Locating key for %s\n", getdomain); - } else if (chase_step & SD_SIG) { - printf ("Locating signature for %s record(s) on %s\n", - sym_ntos(__p_type_syms, chase_type, NULL), - getdomain); - } - hp = NULL; - res.res_h_errno = TRY_AGAIN; - continue; - } - } else { - if (addrinfo(addr) == 0) - hp = NULL; - else - hp = (struct hostent *)1; /* XXX */ - } - if (!waitmode) - break; - } - - if (hp == NULL) { - hperror(res.res_h_errno); - exit(1); - } - - exit(0); -} - -/* Private. */ - -static int -parsetype(const char *s) { - int type, success; - - type = sym_ston(__p_type_syms, s, &success); - if (success) - return (type); - if (strcmp(s, "*") == 0) - return (ns_t_any); - if (atoi(s)) - return (atoi(s)); - fprintf(stderr, "Invalid query type: %s\n", s); - exit(2); - /*NOTREACHED*/ -} - -static int -parseclass(const char *s) { - int class, success; - - class = sym_ston(__p_class_syms, s, &success); - if (success) - return (class); - if (atoi(s)) - return (atoi(s)); - fprintf(stderr, "Invalid query class: %s\n", s); - exit(2); - /*NOTREACHED*/ -} - -static void -printanswer(const struct hostent *hp) { - struct in_addr **hptr; - char **cp; - - printf("Name: %s\n", hp->h_name); - printf("Address:"); - for (hptr = (struct in_addr **)hp->h_addr_list; *hptr; hptr++) - printf(" %s", inet_ntoa(**hptr)); - printf("\nAliases:"); - for (cp = hp->h_aliases; cp && *cp && **cp; cp++) - printf(" %s", *cp); - printf("\n\n"); -} - -static void -hperror(int errnum) { - switch(errnum) { - case HOST_NOT_FOUND: - fprintf(stderr, "Host not found.\n"); - break; - case TRY_AGAIN: - fprintf(stderr, "Host not found, try again.\n"); - break; - case NO_RECOVERY: - fprintf(stderr, "No recovery, Host not found.\n"); - break; - case NO_ADDRESS: - fprintf(stderr, - "There is an entry for this host, but it doesn't have " - ); - switch (gettype) { - case ns_t_a: - fprintf(stderr, "an Internet address.\n"); - break; - case ns_t_ns: - fprintf(stderr, "a Name Server.\n"); - break; - case ns_t_md: - fprintf(stderr, "a Mail Destination.\n"); - break; - case ns_t_mf: - fprintf(stderr, "a Mail Forwarder.\n"); - break; - case ns_t_cname: - fprintf(stderr, "a Canonical Name.\n"); - break; - case ns_t_soa: - fprintf(stderr, "a Start of Authority record.\n"); - break; - case ns_t_mb: - fprintf(stderr, "a Mailbox Domain Name.\n"); - break; - case ns_t_mg: - fprintf(stderr, "a Mail Group Member.\n"); - break; - case ns_t_mr: - fprintf(stderr, "a Mail Rename Name.\n"); - break; - case ns_t_null: - fprintf(stderr, "a Null Resource record.\n"); - break; - case ns_t_wks: - fprintf(stderr, "any Well Known Service information.\n"); - break; - case ns_t_ptr: - fprintf(stderr, "a Pointer record.\n"); - break; - case ns_t_hinfo: - fprintf(stderr, "any Host Information.\n"); - break; - case ns_t_minfo: - fprintf(stderr, "any Mailbox Information.\n"); - break; - case ns_t_mx: - fprintf(stderr, "a Mail Exchanger record.\n"); - break; - case ns_t_txt: - fprintf(stderr, "a Text record.\n"); - break; - case ns_t_rp: - fprintf(stderr, "a Responsible Person.\n"); - break; - case ns_t_srv: - fprintf(stderr, "a Server Selector.\n"); - break; - case ns_t_naptr: - fprintf(stderr, "a URN Naming Authority.\n"); - break; - default: - fprintf(stderr, "the information you requested.\n"); - break; - } - break; - } -} - -static int -addrinfo(struct in_addr addr) { - u_int32_t ha = ntohl(addr.s_addr); - char name[NS_MAXDNAME]; - - sprintf(name, "%u.%u.%u.%u.IN-ADDR.ARPA.", - (ha) & 0xff, - (ha >> 8) & 0xff, - (ha >> 16) & 0xff, - (ha >> 24) & 0xff); - return (getinfo(name, NULL, ns_t_ptr)); -} - -static int -gethostinfo(char *name) { - char *cp, **domain; - char tmp[NS_MAXDNAME]; - const char *tp; - int hp, nDomain; - int asis = 0; - u_int n; - - if (strcmp(name, ".") == 0) - return (getdomaininfo(name, NULL)); - for (cp = name, n = 0; *cp; cp++) - if (*cp == '.') - n++; - if (n && cp[-1] == '.') { - if (cp[-1] == '.') - cp[-1] = 0; - hp = getdomaininfo(name, (char *)NULL); - if (cp[-1] == 0) - cp[-1] = '.'; - return (hp); - } - if (n == 0 && (tp = res_hostalias(&res, name, tmp, sizeof tmp))) { - if (verbose) - printf("Aliased to \"%s\"\n", tp); - res.options |= RES_DEFNAMES; - return (getdomaininfo(tp, (char *)NULL)); - } - if (n >= res.ndots) { - asis = 1; - if (verbose) - printf("Trying null domain\n"); - hp = getdomaininfo(name, (char*)NULL); - if (hp) - return (hp); - } - for (domain = res.dnsrch; *domain; domain++) { - if (verbose) - printf("Trying domain \"%s\"\n", *domain); - hp = getdomaininfo(name, *domain); - if (hp) - return (hp); - } - if (res.res_h_errno != HOST_NOT_FOUND || (res.options & RES_DNSRCH) == 0) - return (0); - if (!asis) - return (0); - if (verbose) - printf("Trying null domain\n"); - return (getdomaininfo(name, (char *)NULL)); -} - -static int -getdomaininfo(const char *name, const char *domain) { - int val1, val2; - - if (gettype) - return (getinfo(name, domain, gettype)); - else { - val1 = getinfo(name, domain, gettype=ns_t_a); - if (cname || verbose) - return (val1); - val2 = getinfo(name, domain, gettype=ns_t_mx); - return (val1 || val2); - } -} - -static int -getinfo(const char *name, const char *domain, int type) { - HEADER *hp; - u_char *eom, *bp, *cp; - querybuf buf, answer; - int n, n1, i, j, nmx, ancount, nscount, arcount, qdcount, buflen; - u_short pref, class; - char host[NS_MAXDNAME]; - - if (domain == NULL) - sprintf(host, "%.*s", NS_MAXDNAME, name); - else - sprintf(host, "%.*s.%.*s", - NS_MAXDNAME, name, NS_MAXDNAME, domain); - - n = res_nmkquery(&res, QUERY, host, getclass, type, NULL, 0, NULL, - buf.qb2, sizeof buf); - if (n < 0) { - if (res.options & RES_DEBUG) - printf("res_nmkquery failed\n"); - res.res_h_errno = NO_RECOVERY; - return (0); - } - n = res_nsend(&res, buf.qb2, n, answer.qb2, sizeof answer); - if (n < 0) { - if (res.options & RES_DEBUG) - printf("res_nsend failed\n"); - res.res_h_errno = TRY_AGAIN; - return (0); - } - eom = answer.qb2 + n; - return (printinfo(&answer, eom, ns_t_any, 0)); -} - -static int -printinfo(const querybuf *answer, const u_char *eom, int filter, int isls) { - int n, n1, i, j, nmx, ancount, nscount, arcount, qdcount, buflen, savesigchase; - u_short pref, class; - const u_char *bp, *cp; - const HEADER *hp; - - /* - * Find first satisfactory answer. - */ - hp = (HEADER *) answer; - ancount = ntohs(hp->ancount); - qdcount = ntohs(hp->qdcount); - nscount = ntohs(hp->nscount); - arcount = ntohs(hp->arcount); - if (res.options & RES_DEBUG || (verbose && isls == 0)) - printf("rcode = %d (%s), ancount=%d\n", - hp->rcode, DecodeError(hp->rcode), ancount); - if (hp->rcode != NOERROR || (ancount+nscount+arcount) == 0) { - switch (hp->rcode) { - case NXDOMAIN: - res.res_h_errno = HOST_NOT_FOUND; - return (0); - case SERVFAIL: - res.res_h_errno = TRY_AGAIN; - return (0); - case NOERROR: - res.res_h_errno = NO_DATA; - return (0); - case FORMERR: - case NOTIMP: - case REFUSED: - res.res_h_errno = NO_RECOVERY; - return (0); - } - return (0); - } - bp = hostbuf; - nmx = 0; - buflen = sizeof(hostbuf); - cp = answer->qb2 + HFIXEDSZ; - if (qdcount > 0) { - while (qdcount-- > 0) { - n = dn_skipname(cp, eom); - if (n < 0) { - printf("Form error.\n"); - return (0); - } - cp += n + QFIXEDSZ; - if (cp > eom) { - printf("Form error.\n"); - return (0); - } - } - } - if (ancount) { - if (!hp->aa) - if (verbose && isls == 0) - printf( - "The following answer is not authoritative:\n" - ); - if (!hp->ad) - if (verbose && isls == 0) - printf("The following answer is not verified as authentic by the server:\n"); - while (--ancount >= 0 && cp && cp < eom) - cp = pr_rr(cp, answer->qb2, stdout, filter); - } - if (!verbose) - return (1); - - /* don't chase signatures for non-answer stuff */ - - savesigchase = sigchase; - sigchase = 0; - - if (nscount) { - printf("For authoritative answers, see:\n"); - while (--nscount >= 0 && cp && cp < eom) - cp = (u_char *)pr_rr(cp, answer->qb2, stdout, filter); - } - if (arcount) { - printf("Additional information:\n"); - while (--arcount >= 0 && cp && cp < eom) - cp = (u_char *)pr_rr(cp, answer->qb2, stdout, filter); - } - - /* restore sigchase value */ - - sigchase = savesigchase; - - return (1); -} - -void print_hex_field (u_int8_t field[], int length, int width, char *pref) -{ - /* Prints an arbitrary bit field, from one address for some number of - bytes. Output is formatted via the width, and includes the raw - hex value and (if printable) the printed value underneath. "pref" - is a string used to start each line, e.g., " " to indent. - - This is very useful in gdb to see what's in a memory field. - */ - int i, start, stop; - - start=0; - do - { - stop=(start+width)<length?(start+width):length; - printf (pref); - for (i = start; i < stop; i++) - printf ("%02x ", (u_char) field[i]); - printf ("\n"); - - printf (pref); - for (i = start; i < stop; i++) - if (isprint(field[i])) - printf (" %c ", (u_char) field[i]); - else - printf (" "); - printf ("\n"); - - start = stop; - } while (start < length); -} - -void memswap (void *s1, void *s2, size_t n) -{ - void *tmp; - - tmp = malloc(n); - if (!tmp) { - printf ("Out of memory\n"); - exit (1); - } - - memcpy(tmp, s1, n); - memcpy(s1, s2, n); - memcpy(s2, tmp, n); - - free (tmp); -} - -void print_hex (u_int8_t field[], int length) -{ - /* Prints the hex values of a field...not as pretty as the print_hex_field. - */ - int i, start, stop; - - start=0; - do - { - stop=length; - for (i = start; i < stop; i++) - printf ("%02x ", (u_char) field[i]); - start = stop; - if (start < length) printf ("\n"); - } while (start < length); -} - -/* - * Print resource record fields in human readable form. - */ -static const u_char * -pr_rr(const u_char *cp, const u_char *msg, FILE *file, int filter) { - int type, class, dlen, n, c, proto, ttl; - struct in_addr inaddr; - u_char in6addr[NS_IN6ADDRSZ]; - const u_char *savecp = cp; - const u_char *cp1; - struct protoent *protop; - struct servent *servp; - char punc = ' '; - int doprint; - char name[NS_MAXDNAME]; - char thisdomain[NS_MAXDNAME]; - char tmpbuf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - u_char canonrr[MY_PACKETSZ]; - size_t canonrr_len = 0; - - if ((cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name))) == NULL) - return (NULL); /* compression error */ - strcpy(thisdomain, name); - - type = ns_get16(cp); - cp += INT16SZ; - - class = ns_get16(cp); - cp += INT16SZ; - - ttl = ns_get32(cp); - cp += INT32SZ; - - if (filter == type || filter == ns_t_any || - (filter == ns_t_a && (type == ns_t_ptr || type == ns_t_ns))) - doprint = 1; - else - doprint = 0; - - if (doprint) { - if (verbose) - fprintf(file, "%s\t%d%s\t%s", - name, ttl, pr_class(class), pr_type(type)); - else - fprintf(file, "%s%s %s", - name, pr_class(class), pr_type(type)); - if (verbose) - punc = '\t'; - else - punc = ' '; - } - dlen = ns_get16(cp); - cp += INT16SZ; - cp1 = cp; - - /* - * Print type specific data, if appropriate. - */ - switch (type) { - case ns_t_a: - memcpy(&inaddr, cp, NS_INADDRSZ); - if (doprint) - fprintf(file,"%c%s", punc, inet_ntoa(inaddr)); - cp += dlen; - break; - case ns_t_aaaa: - memcpy(in6addr, cp, NS_IN6ADDRSZ); - if (doprint) { - if (inet_ntop(AF_INET6, in6addr, tmpbuf, - sizeof tmpbuf) != NULL) - fprintf(file,"%c%s", punc, tmpbuf); - else - fprintf(file,"%c???", punc); - } - cp += dlen; - break; - case ns_t_cname: - if (dn_expand(msg, msg + 512, cp, cnamebuf, - sizeof(cnamebuf)) >= 0) - cname = cnamebuf; - case ns_t_mb: - case ns_t_mg: - case ns_t_mr: - case ns_t_ns: - case ns_t_ptr: - { - const u_char *startrdata = cp; - u_char cdname[NS_MAXCDNAME]; - - cp = (u_char *)pr_cdname(cp, msg, name, sizeof name); - if (doprint) - fprintf(file, "%c%s", punc, name); - - /* Extract DNSSEC canonical RR. */ - - n = ns_name_unpack(msg, msg+MY_PACKETSZ, startrdata, - cdname, sizeof cdname); - if (n >= 0) - n = ns_name_ntol(cdname, cdname, sizeof cdname); - if (n >= 0) { - /* Copy header. */ - memcpy(canonrr, cp1 - NS_HEADERDATA_SIZE, NS_HEADERDATA_SIZE); - /* Overwrite length field. */ - ns_put16(n, canonrr + NS_HEADERDATA_SIZE - NS_INT16SZ); - /* Copy unpacked name. */ - memcpy(canonrr + NS_HEADERDATA_SIZE, cdname, n); - canonrr_len = NS_HEADERDATA_SIZE + n; - } - break; - } - - case ns_t_hinfo: - case ns_t_isdn: - { - const u_char *cp2 = cp + dlen; - n = *cp++; - if (n != 0) { - if (doprint) - fprintf(file,"%c%.*s", punc, n, cp); - cp += n; - } - if ((cp < cp2) && (n = *cp++)) { - if (doprint) - fprintf(file,"%c%.*s", punc, n, cp); - cp += n; - } else if (type == ns_t_hinfo) - if (doprint) - fprintf(file, - "\n; *** Warning *** OS-type missing" - ); - } - break; - - case ns_t_soa: - { - const u_char *startname = cp; - u_char cdname[NS_MAXCDNAME]; - - cp = (u_char *)pr_cdname(cp, msg, name, sizeof name); - if (doprint) - fprintf(file, "\t%s", name); - - n = ns_name_unpack(msg, msg + 512, startname, - cdname, sizeof cdname); - if (n >= 0) - n = ns_name_ntol(cdname, cdname, sizeof cdname); - if (n >= 0) { - /* Copy header. */ - memcpy(canonrr, cp1 - NS_HEADERDATA_SIZE, NS_HEADERDATA_SIZE); - /* Copy expanded name. */ - memcpy(canonrr + NS_HEADERDATA_SIZE, cdname, n); - canonrr_len = NS_HEADERDATA_SIZE + n; - } - - startname = cp; - cp = (u_char *)pr_cdname(cp, msg, name, sizeof name); - if (doprint) - fprintf(file, " %s", name); - - n = ns_name_unpack(msg, msg + 512, startname, - cdname, sizeof cdname); - if (n >= 0) - n = ns_name_ntol(cdname, cdname, sizeof cdname); - if (n >= 0) { - /* Copy expanded name. */ - memcpy(canonrr + canonrr_len, cdname, n); - canonrr_len += n; - /* Copy rest of SOA. */ - memcpy(canonrr + canonrr_len, cp, 5 * INT32SZ); - canonrr_len += 5 * INT32SZ; - /* Overwrite length field. */ - ns_put16(canonrr_len - NS_HEADERDATA_SIZE, - canonrr + NS_HEADERDATA_SIZE - NS_INT16SZ); - } - - if (doprint) - fprintf(file, "(\n\t\t\t%ld\t;serial (version)", - ns_get32(cp)); - cp += INT32SZ; - if (doprint) - fprintf(file, "\n\t\t\t%ld\t;refresh period", - ns_get32(cp)); - cp += INT32SZ; - if (doprint) - fprintf(file, - "\n\t\t\t%ld\t;retry refresh this often", - ns_get32(cp)); - cp += INT32SZ; - if (doprint) - fprintf(file, "\n\t\t\t%ld\t;expiration period", - ns_get32(cp)); - cp += INT32SZ; - if (doprint) - fprintf(file, "\n\t\t\t%ld\t;minimum TTL\n\t\t\t)", - ns_get32(cp)); - cp += INT32SZ; - break; - } - case ns_t_mx: - case ns_t_afsdb: - case ns_t_rt: - { - const u_char *startrdata = cp; - u_char cdname[NS_MAXCDNAME]; - - if (doprint) { - if (type == ns_t_mx && !verbose) - fprintf(file," (pri=%d) by ", ns_get16(cp)); - else if (verbose) - fprintf(file,"\t%d ", ns_get16(cp)); - else - fprintf(file," "); - } - cp += sizeof(u_short); - cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name)); - if (doprint) - fprintf(file, "%s", name); - - n = ns_name_unpack(msg, msg+512, startrdata + sizeof(u_short), - cdname, sizeof cdname); - if (n >= 0) - n = ns_name_ntol(cdname, cdname, sizeof cdname); - if (n >= 0) { - /* Copy header. */ - memcpy(canonrr, cp1 - NS_HEADERDATA_SIZE, - NS_HEADERDATA_SIZE); - /* Overwrite length field. */ - ns_put16(sizeof(u_short) + n, - canonrr + NS_HEADERDATA_SIZE - NS_INT16SZ); - /* Copy u_short. */ - memcpy(canonrr + NS_HEADERDATA_SIZE, startrdata, - sizeof(u_short)); - /* Copy expanded name. */ - memcpy(canonrr + NS_HEADERDATA_SIZE + sizeof(u_short), - cdname, n); - canonrr_len = NS_HEADERDATA_SIZE + sizeof(u_short) + n; - } - break; - } - - case ns_t_srv: - if (doprint) - fprintf(file," %d", ns_get16(cp)); - cp += sizeof(u_short); - if (doprint) - fprintf(file," %d", ns_get16(cp)); - cp += sizeof(u_short); - if (doprint) - fprintf(file," %d", ns_get16(cp)); - cp += sizeof(u_short); - cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name)); - if (doprint) - fprintf(file, " %s", name); - break; - - case ns_t_naptr: - /* order */ - if (doprint) - fprintf(file, " %d", ns_get16(cp)); - cp += sizeof(u_short); - /* preference */ - if (doprint) - fprintf(file, " %d", ns_get16(cp)); - cp += NS_INT16SZ; - /* Flags */ - n = *cp++; - if (doprint) { - if (n) - fprintf(file, "%c%.*s", punc, n, cp); - else - fprintf(file, "%c\"\"",punc); - } - cp += n; - /* Service */ - n = *cp++; - if (doprint) { - if (n) - fprintf(file, "%c%.*s", punc, n, cp); - else - fprintf(file,"%c\"\"",punc); - } - cp += n; - /* Regexp */ - n = *cp++; - if (doprint) { - if (n) - fprintf(file, "%c%.*s", punc, n, cp); - else - fprintf(file, "%c\"\"",punc); - } - cp += n; - /* replacement */ - cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name)); - if (doprint) - fprintf(file, "%s", name); - break; - - case ns_t_minfo: - case ns_t_rp: - cp = (u_char *)pr_cdname(cp, msg, name, sizeof name); - if (doprint) { - if (type == ns_t_rp) { - char *p; - - p = strchr(name, '.'); - if (p != NULL) - *p = '@'; - } - fprintf(file, "%c%s", punc, name); - } - cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name)); - if (doprint) - fprintf(file, " %s", name); - break; - - case ns_t_x25: - n = *cp++; - if (n != 0) { - if (doprint) - fprintf(file, "%c%.*s", punc, n, cp); - cp += n; - } - break; - - case ns_t_txt: - { - int n, j; - const u_char *end = cp + dlen; - - while (cp < end) { - if (doprint) - (void) fputs(" \"", file); - n = *cp++; - if (n != 0) - for (j = n; j > 0 && cp < end ; j --) { - if (doprint) { - if (*cp == '\n' || - *cp == '"' || - *cp == '\\') - putc('\\', - file); - putc(*cp, file); - } - cp++; - } - if (doprint) - putc('"', file); - } - } - break; - - case ns_t_wks: - if (dlen < INT32SZ + 1) - break; - memcpy(&inaddr, cp, INADDRSZ); - cp += INT32SZ; - proto = *cp++; - protop = getprotobynumber(proto); - if (doprint) { - if (protop) - fprintf(file, "%c%s %s", punc, - inet_ntoa(inaddr), protop->p_name); - else - fprintf(file, "%c%s %d", punc, - inet_ntoa(inaddr), proto); - } - n = 0; - while (cp < cp1 + dlen) { - c = *cp++; - do { - if (c & 0200) { - servp = NULL; - if (protop) - servp = getservbyport(htons(n), - protop-> - p_name); - if (doprint) { - if (servp) - fprintf(file, " %s", - servp->s_name); - else - fprintf(file, " %d", - n); - } - } - c <<= 1; - } while (++n & 07); - } - break; - case ns_t_nxt: - { - const u_char *startrdata = cp; - u_char cdname[NS_MAXCDNAME]; - size_t bitmaplen; - - cp = (u_char *) pr_cdname(cp, msg, name, sizeof name); - if (doprint) - fprintf(file, "%c%s", punc, name); - bitmaplen = dlen - (cp - startrdata); - - /* extract dnssec canonical rr */ - - n = ns_name_unpack(msg, msg+MY_PACKETSZ, startrdata, - cdname, sizeof cdname); - if (n >= 0) - n = ns_name_ntol(cdname, cdname, sizeof cdname); - if (n >= 0) { - /* Copy header. */ - memcpy(canonrr, cp1 - NS_HEADERDATA_SIZE, - NS_HEADERDATA_SIZE); - /* Overwrite length field. */ - ns_put16(n + bitmaplen, - canonrr + NS_HEADERDATA_SIZE - NS_INT16SZ); - /* Copy expanded name. */ - memcpy(canonrr + NS_HEADERDATA_SIZE, cdname, n); - /* Copy type bit map. */ - memcpy(canonrr + NS_HEADERDATA_SIZE + n, cp, - bitmaplen); - canonrr_len = NS_HEADERDATA_SIZE + n + bitmaplen; - } - cp += bitmaplen; - break; - } - case ns_t_sig: - { - int tc; - const u_char *origttl; - - /* type covered */ - tc = ns_get16(cp); - if (doprint && verbose) - fprintf(file, "%c%s", punc, sym_ntos(__p_type_syms, tc, NULL)); - cp += sizeof(u_short); - /* algorithm */ - if (doprint && verbose) - fprintf(file, " %d", *cp); - cp++; - /* labels */ - if (doprint && verbose) - fprintf(file, " %d", *cp); - cp++; - /* original ttl */ - origttl = cp; - if (doprint && verbose) - fprintf(file, " %d", ns_get32(cp)); - cp += INT32SZ; - /* signature expiration */ - if (doprint && verbose) - fprintf(file, " %d", ns_get32(cp)); - cp += INT32SZ; - /* time signed */ - if (doprint && verbose) - fprintf(file, " %d", ns_get32(cp)); - cp += INT32SZ; - /* key footprint */ - if (doprint && verbose) - fprintf(file, " %d", ns_get16(cp)); - cp += sizeof(u_short); - /* signer's name */ - cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name)); - if (doprint && verbose) - fprintf(file, " %s", name); - else if (doprint && !verbose) - fprintf (file, " %s for type %s", name, - sym_ntos(__p_type_syms, tc, NULL)); - /* signature */ - { - char str[MY_PACKETSZ]; - size_t len = cp1-cp+dlen; - - b64_ntop (cp, len, str, MY_PACKETSZ-1); - - if (sigchase && !(chase_step & SD_SIG) && - strcmp (chase_domain, thisdomain) == 0 && - chase_class == class & chase_type == tc) - { - u_char cdname[NS_MAXCDNAME]; - - if (doprint && !verbose) - fprintf(file, " (chasing key)"); - - strcpy(chase_signer, name); - - memcpy(&chase_sigorigttl[0], origttl, - NS_INT32SZ); - - n = ns_name_ntol(cp1 + SIG_RDATA_BY_NAME, - cdname, sizeof cdname); - if (n >= 0) { - memcpy(chase_sigrdata, cp1, - SIG_RDATA_BY_NAME); - memcpy(chase_sigrdata + SIG_RDATA_BY_NAME, - cdname, n); - chase_sigrdata_len += SIG_RDATA_BY_NAME + n; - memcpy(chase_signature, cp, len); - chase_signature_len = len; - - chase_step |= SD_SIG; - } - } else if (sigchase) { - chase_step |= SD_BADSIG; - } - - cp += len; - if (doprint && verbose) - fprintf (file, " %s", str); - } - break; - } - case ns_t_key: - /* flags */ - if (doprint && verbose) - fprintf(file, "%c%d", punc, ns_get16(cp)); - cp += sizeof(u_short); - /* protocol */ - if (doprint && verbose) - fprintf(file, " %d", *cp); - cp++; - /* algorithm */ - n = *cp; - if (doprint && verbose) - fprintf(file, " %d", *cp); - cp++; - switch (n) { - case 1: /* MD5/RSA */ - { - char str[MY_PACKETSZ]; - size_t len = cp1-cp+dlen; - - b64_ntop (cp, len, str, MY_PACKETSZ-1); - cp += len; - - if (doprint && verbose) - fprintf (file, " %s", str); - break; - } - - default: - fprintf (stderr, "Unknown algorithm %d\n", n); - cp = cp1 + dlen; - break; - } - - if (sigchase && (chase_step & (SD_SIG|SD_RR)) && - strcmp (getdomain, name) == 0 && - getclass == class & gettype == type) - { - DST_KEY *dstkey; - int rc, len, i, j; - - /* convert dnskey to dstkey */ - - dstkey = dst_dnskey_to_key (name, cp1, dlen); - - /* fix ttl in rr */ - - for (i = 0; i < NUMRR && chase_rr[i].len; i++) - { - len = dn_skipname(chase_rr[i].data, - chase_rr[i].data + - chase_rr[i].len); - if (len>=0) - memcpy(chase_rr[i].data + len + NS_INT16SZ + - NS_INT16SZ, - &chase_sigorigttl, INT32SZ); - } - - /* sort rr's (qsort() is too slow) */ - - for (i = 0; i < NUMRR && chase_rr[i].len; i++) - for (j = i + 1; i < NUMRR && chase_rr[j].len; j++) - if (memcmp(chase_rr[i].data, chase_rr[j].data, MY_PACKETSZ) > 0) - memswap(&chase_rr[i], &chase_rr[j], sizeof(rrstruct)); - - /* append rr's to sigrdata */ - - for (i = 0; i < NUMRR && chase_rr[i].len; i++) - { - memcpy (chase_sigrdata + chase_sigrdata_len, - chase_rr[i].data, chase_rr[i].len); - chase_sigrdata_len += chase_rr[i].len; - } - - /* print rr-data and signature */ - - if (verbose) { - print_hex_field(chase_sigrdata, - chase_sigrdata_len, - 21,"DATA: "); - print_hex_field(chase_signature, - chase_signature_len, - 21,"SIG: "); - } - - /* do the works */ - - if (dstkey) - rc = dst_verify_data(SIG_MODE_ALL, dstkey, NULL, - chase_sigrdata, - chase_sigrdata_len, - chase_signature, - chase_signature_len); - else - rc = 1; - - dst_free_key(dstkey); - - if (verbose) - { - fprintf(file, "\nVerification %s", rc == 0 ? - "was SUCCESSFULL" : - "FAILED"); - } - else - { - fprintf (file, - " that %s verify our %s " - "record(s) on %s", - rc == 0 ? "successfully" : - "DOES NOT", - sym_ntos(__p_type_syms, chase_type, - NULL), - chase_domain); - } - - if (rc == 0) - { - strcpy (chase_lastgoodkey, name); - } - else - { - /* don't trace further after a failure */ - sigchase = 0; - } - - chase_step = 0; - chase_signature_len = 0; - chase_sigrdata_len = 0; - memset(chase_sigorigttl, 0, NS_INT32SZ); - memset(chase_rr, 0, sizeof(chase_rr)); - chase_rr_num = 0; - } - break; - - default: - if (doprint) - fprintf(file, "%c???", punc); - cp += dlen; - break; - } - if (cp != cp1 + dlen) - fprintf(file, "packet size error (%p != %p)\n", - cp, cp1 + dlen); - - if (sigchase && !(chase_step & SD_SIG) && - strcmp (getdomain, thisdomain) == 0 && getclass == class && - gettype == type && type != ns_t_sig) - { - u_char cdname[NS_MAXCDNAME]; - - if (doprint && !verbose) - fprintf (file, " (chasing signature)", sigchase-1); - - /* unpack rr */ - - n = ns_name_unpack(msg, msg + MY_PACKETSZ, savecp, - cdname, sizeof cdname); - if (n >= 0) - n = ns_name_ntol(cdname, cdname, sizeof cdname); - if (n >= 0) { - memcpy(chase_rr[chase_rr_num].data, cdname, n); - memcpy(chase_rr[chase_rr_num].data + n, - canonrr_len ? canonrr : cp1 - NS_HEADERDATA_SIZE, - canonrr_len ? canonrr_len : dlen + NS_HEADERDATA_SIZE); - chase_rr[chase_rr_num].len = - n + (canonrr_len != 0 ? canonrr_len : - dlen + NS_HEADERDATA_SIZE); - - strcpy(chase_domain, getdomain); - chase_class = class; - chase_type = type; - chase_step |= SD_RR; - chase_rr_num++; - } - } - - if (doprint) - fprintf(file, "\n"); - - return (cp); -} - -/* - * Return a string for the type. A few get special treatment when - * not in verbose mode, to make the program more chatty and easier to - * understand. - */ -static const char * -pr_type(int type) { - if (!verbose) switch (type) { - case ns_t_a: - return ("has address"); - case ns_t_cname: - return ("is a nickname for"); - case ns_t_mx: - return ("mail is handled"); - case ns_t_txt: - return ("descriptive text"); - case ns_t_sig: - return ("has a signature signed by"); - case ns_t_key: - return ("has a key"); - case ns_t_nxt: - return ("next valid name"); - case ns_t_afsdb: - return ("DCE or AFS service from"); - } - if (verbose) - return (sym_ntos(__p_type_syms, type, NULL)); - else - return (sym_ntop(__p_type_syms, type, NULL)); -} - -/* - * Return a mnemonic for class - */ -static const char * -pr_class(int class) { - static char spacestr[20]; - - if (!verbose) switch (class) { - case ns_c_in: /* internet class */ - return (""); - case ns_c_hs: /* hesiod class */ - return (""); - } - - spacestr[0] = ' '; - strcpy(&spacestr[1], p_class(class)); - return (spacestr); -} - -static const u_char * -pr_cdname(const u_char *cp, const u_char *msg, char *name, int namelen) { - int n = dn_expand(msg, msg + MY_PACKETSZ, cp, name, namelen - 2); - - if (n < 0) - return (NULL); - if (name[0] == '\0') { - name[0] = '.'; - name[1] = '\0'; - } - return (cp + n); -} - -static int -ListHosts(char *namePtr, int queryType) { - querybuf buf, answer; - struct sockaddr_in sin; - const HEADER *headerPtr; - const struct hostent *hp; - enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING } - error = NO_ERRORS; - - int msglen, amtToRead, numRead, i, len, dlen, type, nscount, n; - int numAnswers = 0, soacnt = 0, result = 0; - u_char tmp[NS_INT16SZ]; - char name[NS_MAXDNAME], dname[2][NS_MAXDNAME], domain[NS_MAXDNAME]; - u_char *cp, *nmp, *eom; - - /* Names and addresses of name servers to try. */ - char nsname[NUMNS][NS_MAXDNAME]; - int nshaveaddr[NUMNS]; - struct in_addr nsipaddr[NUMNSADDR]; - int numns, numnsaddr, thisns; - - /* - * Normalize to not have trailing dot. We do string compares below - * of info from name server, and it won't have trailing dots. - */ - i = strlen(namePtr); - if (namePtr[i-1] == '.') - namePtr[i-1] = 0; - - if (server_specified) { - memcpy(&nsipaddr[0], &res.nsaddr.sin_addr, NS_INADDRSZ); - numnsaddr = 1; - } else { - /* - * First we have to find out where to look. This needs a NS - * query, possibly followed by looking up addresses for some - * of the names. - */ - msglen = res_nmkquery(&res, ns_o_query, namePtr, - ns_c_in, ns_t_ns, - NULL, 0, NULL, - buf.qb2, sizeof buf); - if (msglen < 0) { - printf("res_nmkquery failed\n"); - return (ERROR); - } - - msglen = res_nsend(&res, buf.qb2, msglen, - answer.qb2, sizeof answer); - if (msglen < 0) { - printf("Cannot find nameserver -- try again later\n"); - return (ERROR); - } - if (res.options & RES_DEBUG || verbose) - printf("rcode = %d (%s), ancount=%d\n", - answer.qb1.rcode, DecodeError(answer.qb1.rcode), - ntohs(answer.qb1.ancount)); - - /* - * Analyze response to our NS lookup. - */ - - nscount = ntohs(answer.qb1.ancount) + - ntohs(answer.qb1.nscount) + - ntohs(answer.qb1.arcount); - - if (answer.qb1.rcode != NOERROR || nscount == 0) { - switch (answer.qb1.rcode) { - case NXDOMAIN: - /* Check if it's an authoritive answer */ - if (answer.qb1.aa) - printf("No such domain\n"); - else - printf("Unable to get information about domain -- try again later.\n"); - break; - case SERVFAIL: - printf("Unable to get information about that domain -- try again later.\n"); - break; - case NOERROR: - printf("That domain exists, but seems to be a leaf node.\n"); - break; - case FORMERR: - case NOTIMP: - case REFUSED: - printf("Unrecoverable error looking up domain name.\n"); - break; - } - return (0); - } - - cp = answer.qb2 + HFIXEDSZ; - eom = answer.qb2 + msglen; - if (ntohs(answer.qb1.qdcount) > 0) { - n = dn_skipname(cp, eom); - if (n < 0) { - printf("Form error.\n"); - return (ERROR); - } - cp += n + QFIXEDSZ; - if (cp > eom) { - printf("Form error.\n"); - return (ERROR); - } - } - - numns = 0; - numnsaddr = 0; - - /* - * Look at response from NS lookup for NS and A records. - */ - - for ((void)NULL; nscount; nscount--) { - cp += dn_expand(answer.qb2, answer.qb2 + msglen, cp, - domain, sizeof(domain)); - if (cp + 3 * INT16SZ + INT32SZ > eom) { - printf("Form error.\n"); - return (ERROR); - } - type = ns_get16(cp); - cp += INT16SZ + INT16SZ + INT32SZ; - dlen = ns_get16(cp); - cp += INT16SZ; - if (cp + dlen > eom) { - printf("Form error.\n"); - return (ERROR); - } - if (type == ns_t_ns) { - if (dn_expand(answer.qb2, eom, - cp, name, sizeof(name)) >= 0) { - if (numns < NUMNS && - ns_samename((char *)domain, - namePtr) == 1) { - for (i = 0; i < numns; i++) - if (ns_samename( - nsname[i], - (char *)name - ) == 1) - /* duplicate */ - break; - if (i >= numns) { - strncpy(nsname[numns], - (char *)name, - sizeof(name)); - nshaveaddr[numns] = 0; - numns++; - } - } - } - } else if (type == ns_t_a) { - if (numnsaddr < NUMNSADDR) - for (i = 0; i < numns; i++) { - if (ns_samename(nsname[i], - (char *)domain) - == 1) { - nshaveaddr[i]++; - memcpy( - &nsipaddr[numnsaddr], - cp, NS_INADDRSZ); - numnsaddr++; - break; - } - } - } - cp += dlen; - } - - /* - * Usually we'll get addresses for all the servers in the - * additional info section. But in case we don't, look up - * their addresses. - */ - - for (i = 0; i < numns; i++) { - if (nshaveaddr[i] == 0) { - struct in_addr **hptr; - int numaddrs = 0; - - hp = gethostbyname(nsname[i]); - if (hp) { - for (hptr = (struct in_addr **) - hp->h_addr_list; - *hptr != NULL; - hptr++) - if (numnsaddr < NUMNSADDR) { - memcpy( - &nsipaddr[numnsaddr], - *hptr, NS_INADDRSZ); - numnsaddr++; - numaddrs++; - } - } - if (res.options & RES_DEBUG || verbose) - printf( - "Found %d addresses for %s by extra query\n", - numaddrs, nsname[i]); - } else if (res.options & RES_DEBUG || verbose) - printf("Found %d addresses for %s\n", - nshaveaddr[i], nsname[i]); - } - } - /* - * Now nsipaddr has numnsaddr addresses for name servers that - * serve the requested domain. Now try to find one that will - * accept a zone transfer. - */ - thisns = 0; - - again: - numAnswers = 0; - soacnt = 0; - - /* - * Create a query packet for the requested domain name. - */ - msglen = res_nmkquery(&res, QUERY, namePtr, getclass, ns_t_axfr, NULL, - 0, NULL, buf.qb2, sizeof buf); - if (msglen < 0) { - if (res.options & RES_DEBUG) - fprintf(stderr, "ListHosts: Res_mkquery failed\n"); - return (ERROR); - } - - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(NAMESERVER_PORT); - - /* - * Set up a virtual circuit to the server. - */ - - for ((void)NULL; thisns < numnsaddr; thisns++) { - if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("ListHosts"); - return (ERROR); - } - memcpy(&sin.sin_addr, &nsipaddr[thisns], NS_INADDRSZ); - if (res.options & RES_DEBUG || verbose) - printf("Trying %s\n", inet_ntoa(sin.sin_addr)); - if (connect(sockFD, (struct sockaddr *)&sin, sizeof(sin)) >= 0) - break; - if (verbose) - perror("Connection failed, trying next server"); - close(sockFD); - sockFD = -1; - } - if (thisns >= numnsaddr) { - printf("No server for that domain responded\n"); - if (!verbose) - perror("Error from the last server was"); - return (ERROR); - } - - /* - * Send length & message for zone transfer - */ - - ns_put16(msglen, tmp); - if (write(sockFD, (char *)tmp, INT16SZ) != INT16SZ || - write(sockFD, (char *)buf.qb2, msglen) != msglen) { - perror("ListHosts"); - (void) close(sockFD); - sockFD = -1; - return (ERROR); - } - - filePtr = stdout; - - for (;;) { - /* - * Read the length of the response. - */ - cp = buf.qb2; - amtToRead = INT16SZ; - while (amtToRead > 0 && - (numRead = read(sockFD, cp, amtToRead)) > 0) { - cp += numRead; - amtToRead -= numRead; - } - if (numRead <= 0) { - error = ERR_READING_LEN; - break; - } - - if ((len = ns_get16(buf.qb2)) == 0) - break; /* Protocol violation. */ - - /* - * Read the response. - */ - - amtToRead = len; - cp = buf.qb2; - while (amtToRead > 0 && - (numRead = read(sockFD, cp, amtToRead)) > 0) { - cp += numRead; - amtToRead -= numRead; - } - if (numRead <= 0) { - error = ERR_READING_MSG; - break; - } - - i = buf.qb1.rcode; - if (i != NOERROR || ntohs(buf.qb1.ancount) == 0) { - if (thisns + 1 < numnsaddr && - (i == SERVFAIL || i == NOTIMP || i == REFUSED)) { - if (res.options & RES_DEBUG || verbose) - printf( - "Server failed, trying next server: %s\n", - i != NOERROR - ? DecodeError(i) - : "Premature end of data"); - (void) close(sockFD); - sockFD = -1; - thisns++; - goto again; - } - printf("Server failed: %s\n", i != NOERROR - ? DecodeError(i) : "Premature end of data"); - break; - } - - result = printinfo(&buf, cp, queryType, 1); - if (! result) { - error = ERR_PRINTING; - break; - } - numAnswers++; - cp = buf.qb2 + HFIXEDSZ; - if (ntohs(buf.qb1.qdcount) > 0) { - n = dn_skipname(cp, buf.qb2 + len); - if (n < 0) { - error = ERR_PRINTING; - break; - } - cp += n + QFIXEDSZ; - } - nmp = cp; - n = dn_skipname(cp, buf.qb2 + len); - if (n < 0) { - error = ERR_PRINTING; - break; - } - cp += n; - if (cp + INT16SZ > buf.qb2 + len) { - error = ERR_PRINTING; - break; - } - if ((ns_get16(cp) == ns_t_soa)) { - (void) dn_expand(buf.qb2, buf.qb2 + len, nmp, - dname[soacnt], sizeof dname[0]); - if (soacnt) { - if (ns_samename(dname[0], dname[1]) == 1) - break; - } else - soacnt++; - } - } - - (void) close(sockFD); - sockFD = -1; - - switch (error) { - case NO_ERRORS: - return (SUCCESS); - - case ERR_READING_LEN: - return (ERROR); - - case ERR_PRINTING: - fprintf(stderr,"*** Error during listing of %s: %s\n", - namePtr, DecodeError(result)); - return (result); - - case ERR_READING_MSG: - headerPtr = (HEADER *) &buf; - fprintf(stderr,"ListHosts: error receiving zone transfer:\n"); - fprintf(stderr, - " result: %s, answers = %d, authority = %d, additional = %d\n", - p_rcode(headerPtr->rcode), - ntohs(headerPtr->ancount), ntohs(headerPtr->nscount), - ntohs(headerPtr->arcount)); - return (ERROR); - default: - return (ERROR); - } -} - -static const char * -DecodeError(int result) { - switch(result) { - case NOERROR: return ("Success"); - case FORMERR: return ("Format error"); - case SERVFAIL: return ("Server failed"); - case NXDOMAIN: return ("Non-existent domain"); - case NOTIMP: return ("Not implemented"); - case REFUSED: return ("Query refused"); - case NO_INFO: return ("No information"); - case ERROR: return ("Unspecified error"); - case TIME_OUT: return ("Timed out"); - case NONAUTH: return ("Non-authoritative answer"); - default: return ("BAD ERROR VALUE"); - } - /* NOTREACHED */ -} diff --git a/contrib/bind/bin/irpd/Makefile b/contrib/bind/bin/irpd/Makefile deleted file mode 100644 index 9eaf4cc939367..0000000000000 --- a/contrib/bind/bin/irpd/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -## Copyright (c) 1996, 1997 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 1.6 2000/07/17 07:15:08 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -EXE= -LEX = lex -I -YACC = yacc -d -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -DESTETC= /etc -DESTRUN= /var/run -AR= ar cru -INSTALL= install -STRIP=-s - -PS=ps -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} -I${TOP}/lib/irs ${DEFS} - -VER= LOCAL-`date +%y%m%d.%H%M%S` -HOSTNAMECMD= hostname || uname -n - -PROG= irpd -HDRS= -SRCS= irpd.c -OBJS= irpd.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: irpd.${O} tmp_version.${O} ${LIBBIND} - ${CC} ${CDEBUG} ${LDFLAGS} -o ${PROG}${EXE} ${OBJS} tmp_version.${O} \ - ${LIBBIND} ${SYSLIBS} -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -tmp_version.${O}: tmp_version.c - -tmp_version.c: version.c Makefile ../Makefile ${SRCS} ${HDRS} - (u=$${USER-root} d=`pwd` h=`${HOSTNAMECMD}` t=`date`; \ - sed -e "s|%WHEN%|$${t}|" -e "s|%VERSION%|"${VER}"|" \ - -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \ - < version.c > tmp_version.c); sleep 1 - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - rm -f tmp_version.c tmp_version.${O} - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} -I${TOP}/lib/irs ${DEFS} ${SRCS} - -${DESTDIR}${DESTSBIN}: - mkdir -p ${DESTDIR}${DESTSBIN} - -install: ${DESTDIR}${DESTSBIN} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c -m 755 ${PROG}${EXE} ${DESTDIR}${DESTSBIN}/${PROG}${EXE} - -links: FRC - @ln -s SRC/*.[chy] SRC/test .; rm -f ns_parser.[ch] - -tags: FRC - ctags ${SRCS} *.h - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/irpd/irpd.c b/contrib/bind/bin/irpd/irpd.c deleted file mode 100644 index 4a94d2c01a729..0000000000000 --- a/contrib/bind/bin/irpd/irpd.c +++ /dev/null @@ -1,2259 +0,0 @@ -/* - * Copyright(c) 1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* Notes. */ - -#if 0 - -I have to use an AF_INET. Ctl_server should probably take a AF arugment. - -The server has no way to issue any other greeting than HELLO. E.g., would -like to be able to drop connection on greeting if client is not comming -from 127.0.0.1. - -Need to fix client to handle response with body. - -should add iovec with body to the struct ctl_sess? - -should we close connections on some errors (like marshalling errors)? - -getnetbyname falls back to /etc/networks when named not running. Does not -seem to be so for getnetbyaddr - -#endif - -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: irpd.c,v 1.8 2000/02/04 08:28:27 vixie Exp $"; -#endif /* LIBC_SCCS and not lint */ - -/* Imports. */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <assert.h> -#include <ctype.h> -#include <ctype.h> -#include <errno.h> -#include <grp.h> -#include <netdb.h> -#include <pwd.h> -#include <pwd.h> -#include <resolv.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <utmp.h> - -#ifdef EMPTY -/* Digital UNIX utmp.h defines this. */ -#undef EMPTY -#endif - -#include <isc/ctl.h> -#include <isc/assertions.h> -#include <isc/list.h> -#include <isc/memcluster.h> -#include <isc/logging.h> - -#include <irs.h> -#include <irp.h> -#include <isc/irpmarshall.h> -#include <irs_data.h> - -#include "port_after.h" - -/* Macros. */ - -#define ALLDIGITS(s) (strspn((s), "0123456789") == strlen((s))) - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif - -#define MAXNETNAMELEN 256 - -#if !defined(SUN_LEN) -#define SUN_LEN(su) \ - (sizeof (*(su)) - sizeof ((su)->sun_path) + strlen((su)->sun_path)) -#endif - -/* - * This macro is used to initialize a specified field of a net_data struct. - * If the initialization fails then an error response code is sent with a - * description of which field failed to be initialized. - * - * This is only meant for use at the start of the various verb functions. - */ - -#define ND_INIT(nd, field, sess, respcode) \ - do{ if ((nd)->field == 0) { \ - (nd)->field = (*(nd)->irs->field ## _map)(nd->irs); \ - if ((nd)->field == 0) { \ - char *msg = "net_data " #field " initialization failed"; \ - ctl_response(sess, respcode, msg, CTL_EXIT, NULL, \ - NULL, NULL, NULL, 0); \ - return; \ - } \ - } \ - } while (0) - -/* Data structures. */ - -struct arg_s { - struct iovec * iov; - int iovlen; -}; - -struct response_buff { - char * buff; - size_t bufflen; -}; - -struct client_ctx { - struct net_data * net_data; -}; - -/* Forwards. */ - -static struct response_buff *newbuffer(u_int length); -static void release_buffer(struct response_buff *b); -static struct arg_s *split_string(const char *string); -static void free_args(struct arg_s *args); -static int is_all_digits(char *p); -static struct client_ctx *make_cli_ctx(void); -static struct net_data *get_net_data(struct ctl_sess *sess); - -static void irpd_gethostbyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_gethostbyname2(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_gethostbyaddr(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_gethostent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_sethostent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getpwnam(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getpwuid(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getpwent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_setpwent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getnetbyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getnetbyaddr(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getnetent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_setnetent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getgrnam(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getgrgid(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_setgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getservbyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getservbyport(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getservent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_setservent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getprotobyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getprotobynumber(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getprotoent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_setprotoent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_getnetgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_innetgr(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_setnetgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_endnetgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_quit(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_help(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_accept(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); -static void irpd_abort(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx); - -static void irpd_done(struct ctl_sctx *ctx, struct ctl_sess *sess, - void *param); -static void response_done(struct ctl_sctx *ctx, struct ctl_sess *sess, - void *uap); -static void logger(enum ctl_severity, const char *fmt, ...); - -/* Constants. */ - -static const u_int hello_code = IRPD_WELCOME_CODE; -static const char hello_msg[] = "Welcome to IRPD (v 1)"; -static const u_int unkncode = 500; -static const u_int timeoutcode = 501; -static const u_int irpd_quit_ok = 201; -static const u_int timeout = IRPD_TIMEOUT; - -/* Globals. */ - -static int main_needs_exit = 0; -static evContext ev; - -struct ctl_verb verbs [] = { - { "gethostbyname", irpd_gethostbyname }, - { "gethostbyname2", irpd_gethostbyname2 }, - { "gethostbyaddr", irpd_gethostbyaddr }, - { "gethostent", irpd_gethostent }, - { "sethostent", irpd_sethostent }, -#ifdef WANT_IRS_PW - { "getpwnam", irpd_getpwnam }, - { "getpwuid", irpd_getpwuid }, - { "getpwent", irpd_getpwent }, - { "setpwent", irpd_setpwent }, -#endif - { "getnetbyname", irpd_getnetbyname }, - { "getnetbyaddr", irpd_getnetbyaddr }, - { "getnetent", irpd_getnetent }, - { "setnetent", irpd_setnetent }, -#ifdef WANT_IRS_GR - { "getgrnam", irpd_getgrnam }, - { "getgrgid", irpd_getgrgid }, - { "getgrent", irpd_getgrent }, - { "setgrent", irpd_setgrent }, -#endif - { "getservbyname", irpd_getservbyname }, - { "getservbyport", irpd_getservbyport }, - { "getservent", irpd_getservent }, - { "setservent", irpd_setservent }, - - { "getprotobyname", irpd_getprotobyname }, - { "getprotobynumber", irpd_getprotobynumber }, - { "getprotoent", irpd_getprotoent }, - { "setprotoent", irpd_setprotoent }, - - { "getnetgrent", irpd_getnetgrent }, - { "innetgr", irpd_innetgr }, - { "setnetgrent", irpd_setnetgrent }, - { "endnetgrent", irpd_endnetgrent }, - { "quit", irpd_quit }, - { "help", irpd_help }, - - { "", irpd_accept }, /* For connection setups. */ - - /* abort is a verb expected by the ctl library. Is called when the - * client drops the connection unexpectedly. - */ - { "abort", irpd_abort }, - - { NULL, NULL } -}; - -/* - * An empty string causes the library to use the compiled in - * defaults and to ignore any external files. - */ -char *conffile = ""; - -/* Public. */ - -int -main(int argc, char **argv) { - struct ctl_sctx *ctx; - struct sockaddr *addr; -#ifndef NO_SOCKADDR_UN - struct sockaddr_un uaddr; -#endif - struct sockaddr_in iaddr; - log_channel chan; - short port = IRPD_PORT; - char *prog = argv[0]; - char *sockname = IRPD_PATH; - char *p; - int ch; - size_t socksize; - - addr = (struct sockaddr *)&iaddr; - socksize = sizeof iaddr; - - openlog("iprd", LOG_CONS|LOG_PID, LOG_DAEMON); - while ((ch = getopt(argc, argv, "u:p:c:")) != -1) { - switch(ch) { - case 'c': - conffile = optarg; - break; - - case 'p': - port = strtol(optarg, &p, 10); - if (*p != '\0') { - /* junk in argument */ - syslog(LOG_ERR, "port option not a number"); - exit(1); - } - break; - -#ifndef NO_SOCKADDR_UN - case 'u': - sockname = optarg; - addr = (struct sockaddr *)&uaddr; - socksize = sizeof uaddr; - break; -#endif - - case 'h': - case '?': - default: - fprintf(stderr, "%s [ -c config-file ]\n", prog); - exit(1); - } - } - argc -= optind; - argv += optind; - - memset(&iaddr, 0, sizeof iaddr); - -#ifdef HAVE_SA_LEN - iaddr.sin_len = sizeof iaddr; -#endif - iaddr.sin_family = AF_INET; - iaddr.sin_port = htons(IRPD_PORT); - iaddr.sin_addr.s_addr = htonl(INADDR_ANY); - -#ifndef NO_SOCKADDR_UN - memset(&uaddr, 0, sizeof uaddr); - if (addr == (struct sockaddr *)&uaddr) { - uaddr.sun_family = AF_UNIX; - strncpy(uaddr.sun_path, sockname, sizeof uaddr.sun_path); -#ifdef HAVE_SA_LEN - uaddr.sun_len = SUN_LEN(&uaddr); -#endif - - socksize = SUN_LEN(&uaddr); - - /* XXX what if this file is not currently a socket? */ - unlink(sockname); - } -#endif - - evCreate(&ev); - - ctx = ctl_server(ev, addr, socksize, verbs, - unkncode, timeoutcode, /* IRPD_TIMEOUT */ 30, 5, - IRPD_MAXSESS, logger, NULL); - - INSIST(ctx != NULL); - - while (!main_needs_exit) { - evEvent event; - - INSIST_ERR(evGetNext(ev, &event, EV_WAIT) != -1); - INSIST_ERR(evDispatch(ev, event) != -1); - } - - return (0); -} - - -/* - * static void - * simple_response(struct ctl_sess *sess, u_int code, char *msg); - * Send back a simple, one-line response to the client. - */ -static void -simple_response(struct ctl_sess *sess, u_int code, char *msg) { - struct response_buff *b = newbuffer(strlen(msg) + 1); - - if (b == 0) - return; - strcpy(b->buff, msg); - ctl_response(sess, code, b->buff, 0, 0, response_done, b, NULL, 0); -} - -/* - * static void - * send_hostent(struct ctl_sess *sess, struct hostent *ho); - * Send a hostent struct over the wire. If HO is NULL, then - * a "No such host" is sent instead. - */ -static void -send_hostent(struct ctl_sess *sess, struct hostent *ho) { - if (ho == NULL) - simple_response(sess, IRPD_GETHOST_NONE, "No such host"); - else { - size_t need; - struct response_buff *b = newbuffer(0); - - if (irp_marshall_ho(ho, &b->buff, &b->bufflen) != 0) { - simple_response(sess, IRPD_GETHOST_ERROR, - "Internal error"); - logger(ctl_warning, - "Cannot marshall host data for %s\n", - ho->h_name); - release_buffer(b); - } else { - strcat(b->buff, "\r\n"); - - ctl_response(sess, IRPD_GETHOST_OK, "Host found", - 0, 0, response_done, - b, b->buff, strlen(b->buff)); - } - } -} - -/* - * static void - * do_gethostbyname2(struct ctl_sess *sess, struct net_data *nd, - * const char *hostname, int af); - * Look up the given HOSTNAME by Address-Family - * and then send the results to the client connected to - * SESS. - */ -static void -do_gethostbyname2(struct ctl_sess *sess, struct net_data *nd, - const char *hostname, int af) -{ - struct hostent *ho; - - ho = gethostbyname2_p(hostname, af, nd); - send_hostent(sess, ho); -} - -/* - * static void - * irpd_gethostbyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the GETHOSTBYNAME verb. - */ -static void -irpd_gethostbyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - char hname[MAXHOSTNAMELEN]; - struct arg_s *args; - int i; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, ho, sess, IRPD_GETHOST_ERROR); - - args = split_string(rest); - if (args->iovlen != 2) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETHOST_ERROR, - "Incorrect usage: GETHOSTBYNAME hostname"); - } else { - if (args->iov[0].iov_len >= sizeof hname) { - simple_response(sess, IRPD_GETHOST_ERROR, - "GETHOSTBYNAME: name too long"); - } else { - strncpy(hname, args->iov[0].iov_base, - args->iov[0].iov_len); - hname[args->iov[0].iov_len] = '\0'; - do_gethostbyname2(sess, netdata, hname, AF_INET); - } - } - free_args(args); -} - -/* - * static void - * irpd_gethostbyname2(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the GETHOSTBYNAME2 verb. - */ -static void -irpd_gethostbyname2(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - char hname[MAXHOSTNAMELEN]; - struct arg_s *args; - int i; - int af; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, ho, sess, IRPD_GETHOST_ERROR); - - args = split_string(rest); - if (args->iovlen != 3) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETHOST_ERROR, - "Incorrect usage: GETHOSTBYNAME2 hostname AF"); - } else if (args->iov[0].iov_len >= sizeof hname) { - simple_response(sess, IRPD_GETHOST_ERROR, - "GETHOSTBYNAME2: name too long"); - } else { - if (strncasecmp(args->iov[1].iov_base, "af_inet6", 8) == 0) - af = AF_INET6; - else if (strncasecmp(args->iov[1].iov_base, "af_inet", 7) == 0) - af = AF_INET; - else { - simple_response(sess, IRPD_GETHOST_ERROR, - "Unknown address family"); - goto untimely; - } - - strncpy(hname, args->iov[0].iov_base, - args->iov[0].iov_len); - hname[args->iov[0].iov_len] = '\0'; - do_gethostbyname2(sess, netdata, hname, af); - } - - untimely: - free_args(args); -} - -/* - * static void - * irpd_gethostbyaddr(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the GETHOSTBYADDR verb. - */ -static void -irpd_gethostbyaddr(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct hostent *ho; - char haddr[MAXHOSTNAMELEN]; - char tmpaddr[NS_IN6ADDRSZ]; - struct arg_s *args; - int i; - int af; - int addrlen; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, ho, sess, IRPD_GETHOST_ERROR); - - args = split_string(rest); - if (args->iovlen != 3) { - simple_response(sess, IRPD_GETHOST_ERROR, - "GETHOSTBYADDR addr afamily"); - } else { - if (args->iov[0].iov_len >= sizeof haddr) { - simple_response(sess, IRPD_GETHOST_ERROR, - "Address too long"); - } else { - strncpy(haddr, args->iov[1].iov_base, - args->iov[1].iov_len); - haddr[args->iov[1].iov_len] = '\0'; - if (strcasecmp(haddr, "af_inet") == 0) { - af = AF_INET; - addrlen = NS_INADDRSZ; - } else if (strcasecmp(haddr, "af_inet6") == 0) { - af = AF_INET6; - addrlen = NS_IN6ADDRSZ; - } else { - simple_response(sess, IRPD_GETHOST_ERROR, - "Unknown address family"); - goto untimely; - } - - strncpy(haddr, args->iov[0].iov_base, - args->iov[0].iov_len); - haddr[args->iov[0].iov_len] = '\0'; - - if (inet_pton(af, haddr, tmpaddr) != 1) { - simple_response(sess, IRPD_GETHOST_ERROR, - "Invalid address"); - goto untimely; - } - - ho = gethostbyaddr_p(tmpaddr, addrlen, af, netdata); - send_hostent(sess, ho); - } - } - - untimely: - free_args(args); -} - - -/* - * static void - * irpd_gethostent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the GETHOSTENT verb - */ -static void -irpd_gethostent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct hostent *ho; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, ho, sess, IRPD_GETHOST_ERROR); - - ho = gethostent_p(netdata); - - send_hostent(sess, ho); -} - -/* - * static void - * irpd_sethostent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the SETHOSTENT verb - */ -static void -irpd_sethostent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct hostent *ho; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, ho, sess, IRPD_GETHOST_ERROR); - - sethostent_p(1, netdata); /* always stayopen */ - simple_response(sess, IRPD_GETHOST_SETOK, "ok"); -} - -#ifdef WANT_IRS_PW -/* - * static void - * send_pwent(struct ctl_sess *sess, struct passwd *pw); - * Send PW over the wire, or, if PW is NULL, a "No such - * user" response. - */ -static void -send_pwent(struct ctl_sess *sess, struct passwd *pw) { - if (pw == NULL) { - simple_response(sess, IRPD_GETUSER_NONE, - "No such user"); - } else { - struct response_buff *b = newbuffer(0); - - if (irp_marshall_pw(pw, &b->buff, - &b->bufflen) != 0) { - simple_response(sess, IRPD_GETUSER_ERROR, - "Internal error"); - logger(ctl_warning, "Cant marshall pw\n"); - return; - } - - strcat(b->buff, "\r\n"); - - ctl_response(sess, IRPD_GETUSER_OK, "User found", 0, 0, - response_done, b, b->buff, strlen(b->buff)); - } -} - -/* - * static void - * irpd_getpwnam(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the GETPWNAM verb - */ -static void -irpd_getpwnam(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct passwd *pw; - char username[64]; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, pw, sess, IRPD_GETUSER_ERROR); - - args = split_string(rest); - if (args->iovlen != 2) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETUSER_ERROR, - "GETPWNAM username"); - } else { - if (args->iov[0].iov_len >= sizeof username) { - simple_response(sess, IRPD_GETUSER_ERROR, - "Name too long"); - } else { - strncpy(username, args->iov[0].iov_base, - args->iov[0].iov_len); - username[args->iov[0].iov_len] = '\0'; - - pw = getpwnam_p(username, netdata); - send_pwent(sess, pw); - } - } - - free_args(args); -} - -/* - * static void - * irpd_getpwuid(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the GETPWUID verb. - */ -static void -irpd_getpwuid(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct passwd *pw; - char userid[64]; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, pw, sess, IRPD_GETUSER_ERROR); - - args = split_string(rest); - if (args->iovlen != 2) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETUSER_ERROR, - "GETPWUID uid"); - } else { - if (args->iov[0].iov_len >= sizeof userid) { - simple_response(sess, IRPD_GETUSER_ERROR, - "Name too long"); - } else { - strncpy(userid, args->iov[0].iov_base, - args->iov[0].iov_len); - userid[args->iov[0].iov_len] = '\0'; - - if (!ALLDIGITS(userid)) { - simple_response(sess, IRPD_GETUSER_ERROR, - "Not a uid"); - } else { - uid_t uid; - long lval; - - lval = strtol(userid, 0, 10); - uid = (uid_t)lval; - if ((long)uid != lval) { - /* value was too big */ - simple_response(sess, - IRPD_GETUSER_ERROR, - "Not a valid uid"); - goto untimely; - } - - pw = getpwuid_p(uid, netdata); - send_pwent(sess, pw); - } - } - } - - untimely: - free_args(args); -} - -/* - * static void - * irpd_getpwent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implemtnation of the GETPWENT verb. - */ -static void -irpd_getpwent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct passwd *pw; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, pw, sess, IRPD_GETUSER_ERROR); - - pw = getpwent_p(netdata); - send_pwent(sess, pw); -} - -/* - * static void - * irpd_setpwent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implemtnation of the SETPWENT verb. - */ -static void -irpd_setpwent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct passwd *pw; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, pw, sess, IRPD_GETUSER_ERROR); - - setpwent_p(netdata); - simple_response(sess, IRPD_GETUSER_SETOK, "ok"); -} -#endif /* WANT_IRS_PW */ - -/* - * static void - * send_nwent(struct ctl_sess *sess, struct nwent *ne); - * Sends a nwent structure over the wire, or "No such - * network" if NE is NULL. - */ -static void -send_nwent(struct ctl_sess *sess, struct nwent *nw) { - if (nw == NULL) { - simple_response(sess, IRPD_GETNET_NONE, "No such net"); - } else { - struct response_buff *b = newbuffer(0); - - if (irp_marshall_nw(nw, &b->buff, - &b->bufflen) != 0) { - simple_response(sess, IRPD_GETNET_ERROR, - "Internal error"); - logger(ctl_warning, "Cant marshall nw\n"); - return; - } - - strcat(b->buff, "\r\n"); - - ctl_response(sess, IRPD_GETNET_OK, "Network found", 0, 0, - response_done, b, b->buff, strlen(b->buff)); - } -} - -/* - * static void - * send_netent(struct ctl_sess *sess, struct netent *ne); - * Sends a NETENT structure over the wire, or "No such - * Network" error if NE is NULL. - */ -static void -send_netent(struct ctl_sess *sess, struct netent *ne) { - if (ne == NULL) { - simple_response(sess, IRPD_GETNET_NONE, "No such net"); - } else { - struct response_buff *b = newbuffer(0); - - if (irp_marshall_ne(ne, &b->buff, - &b->bufflen) != 0) { - simple_response(sess, IRPD_GETNET_ERROR, - "Internal error"); - logger(ctl_warning, "Cant marshall ne\n"); - return; - } - - strcat(b->buff, "\r\n"); - - ctl_response(sess, IRPD_GETNET_OK, "Network found", 0, 0, - response_done, b, b->buff, strlen(b->buff)); - } -} - -/* - * static void - * irpd_getnetbyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of GETNETBYNAME verb. - */ -static void -irpd_getnetbyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct netent *ne; - struct nwent *nw; - char netname[MAXNETNAMELEN]; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, nw, sess, IRPD_GETNET_ERROR); - - args = split_string(rest); - if (args->iovlen != 2) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETNET_ERROR, - "GETNETBYNAME name"); - } else { - if (args->iov[0].iov_len >= sizeof netname) { - simple_response(sess, IRPD_GETNET_ERROR, - "Name too long"); - } else { - strncpy(netname, args->iov[0].iov_base, - args->iov[0].iov_len); - netname[args->iov[0].iov_len] = '\0'; - - ne = getnetbyname_p(netname, netdata); - - /* The public interface only gives us a struct - netent, and we need a struct nwent that irs uses - internally, so we go dig it out ourselves. Yuk - */ - nw = NULL; - if (ne != NULL) { - /* Puke. */ - INSIST(netdata->nw_last == ne); - nw = netdata->nww_last; - } - - send_nwent(sess, nw); - } - } - free_args(args); -} - -/* - * static void - * irpd_getnetbyaddr(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - */ -static void -irpd_getnetbyaddr(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct netent *ne; - struct nwent *nw; - char haddr[MAXHOSTNAMELEN]; - long tmpaddr; - struct arg_s *args; - int i; - int af; - int addrlen; - int bits; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, nw, sess, IRPD_GETUSER_ERROR); - - args = split_string(rest); - if (args->iovlen != 3) { - simple_response(sess, IRPD_GETNET_ERROR, - "GETNETBYADDR addr afamily"); - } else { - if (args->iov[0].iov_len >= sizeof haddr) { - simple_response(sess, IRPD_GETNET_ERROR, - "Address too long"); - } else { - strncpy(haddr, args->iov[1].iov_base, - args->iov[1].iov_len); - haddr[args->iov[1].iov_len] = '\0'; - if (strcasecmp(haddr, "af_inet") == 0) { - af = AF_INET; - addrlen = NS_INADDRSZ; - } else if (strcasecmp(haddr, "af_inet6") == 0) { - af = AF_INET6; - addrlen = NS_IN6ADDRSZ; - - /* XXX the interface we use(getnetbyaddr) - * can't handle AF_INET6, so for now we - * bail. - */ - simple_response(sess, IRPD_GETNET_ERROR, - "AF_INET6 unsupported"); - goto untimely; - } else { - simple_response(sess, IRPD_GETNET_ERROR, - "Unknown address family"); - goto untimely; - } - - strncpy(haddr, args->iov[0].iov_base, - args->iov[0].iov_len); - haddr[args->iov[0].iov_len] = '\0'; - - bits = inet_net_pton(af, haddr, - &tmpaddr, sizeof tmpaddr); - if (bits < 0) { - simple_response(sess, IRPD_GETNET_ERROR, - "Invalid address"); - goto untimely; - } - - ne = getnetbyaddr_p(tmpaddr, af, netdata); - - /* The public interface only gives us a struct - netent, and we need a struct nwent that irs uses - internally, so we go dig it out ourselves. Yuk - */ - nw = NULL; - if (ne != NULL) { - /* Puke puke */ - INSIST(netdata->nw_last == ne); - nw = netdata->nww_last; - } - - send_nwent(sess, nw); - } - } - - untimely: - free_args(args); -} - - -/* - * static void - * irpd_getnetent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the GETNETENT verb. - */ -static void -irpd_getnetent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct netent *ne; - struct nwent *nw; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, nw, sess, IRPD_GETNET_ERROR); - - ne = getnetent_p(netdata); - nw = NULL; - if (ne != NULL) { - /* triple puke */ - INSIST(netdata->nw_last == ne); - nw = netdata->nww_last; - } - send_nwent(sess, nw); -} - -/* - * static void - * irpd_setnetent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the SETNETENT verb. - */ -static void -irpd_setnetent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct netent *ne; - struct nwent *nw; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, nw, sess, IRPD_GETNET_ERROR); - - setnetent_p(1, netdata); /* always stayopen */ - simple_response(sess, IRPD_GETNET_SETOK, "ok"); -} - -#ifdef WANT_IRS_GR -/* - * static void - * send_grent(struct ctl_sess *sess, struct group *gr); - * Marshall GR and send as body of response. If GR is NULL - * then a "No such group" response is sent instead. - */ -static void -send_grent(struct ctl_sess *sess, struct group *gr) { - if (gr == NULL) { - simple_response(sess, IRPD_GETGROUP_NONE, - "No such user"); - } else { - struct response_buff *b = newbuffer(0); - - if (irp_marshall_gr(gr, &b->buff, &b->bufflen) != 0) { - simple_response(sess, IRPD_GETGROUP_ERROR, - "Internal error"); - logger(ctl_warning, "Cant marshall gr\n"); - return; - } - - strcat(b->buff, "\r\n"); - - ctl_response(sess, IRPD_GETGROUP_OK, "Group found", 0, 0, - response_done, b, b->buff, strlen(b->buff)); - } -} - -/* - * static void - * irpd_getgrnam(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the GETGRNAM verb. - */ -static void -irpd_getgrnam(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct group *gr; - char groupname[64]; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, gr, sess, IRPD_GETGROUP_ERROR); - - args = split_string(rest); - if (args->iovlen != 2) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETGROUP_ERROR, - "GETGRNAM groupname"); - } else { - if (args->iov[0].iov_len >= sizeof groupname) { - simple_response(sess, IRPD_GETGROUP_ERROR, - "Name too long"); - } else { - strncpy(groupname, args->iov[0].iov_base, - args->iov[0].iov_len); - groupname[args->iov[0].iov_len] = '\0'; - - gr = getgrnam_p(groupname, netdata); - send_grent(sess, gr); - } - } - - free_args(args); -} - -/* - * static void - * irpd_getgrgid(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implentation of the GETGRGID verb. - */ -static void -irpd_getgrgid(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct group *gr; - char groupid[64]; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, gr, sess, IRPD_GETGROUP_ERROR); - - args = split_string(rest); - if (args->iovlen != 2) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETGROUP_ERROR, - "GETGRUID gid"); - } else { - if (args->iov[0].iov_len >= sizeof groupid) { - simple_response(sess, IRPD_GETGROUP_ERROR, - "Name too long"); - } else { - strncpy(groupid, args->iov[0].iov_base, - args->iov[0].iov_len); - groupid[args->iov[0].iov_len] = '\0'; - - if (!ALLDIGITS(groupid)) { - simple_response(sess, IRPD_GETGROUP_ERROR, - "Not a gid"); - } else { - gid_t gid; - long lval; - - lval = strtol(groupid, 0, 10); - gid = (gid_t)lval; - if ((long)gid != lval) { - /* value was too big */ - simple_response(sess, - IRPD_GETGROUP_ERROR, - "Not a valid gid"); - goto untimely; - } - - gr = getgrgid_p(gid, netdata); - send_grent(sess, gr); - } - } - } - - untimely: - free_args(args); -} - -/* - * static void - * irpd_getgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the GETGRENT verb. - */ -static void -irpd_getgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct group *gr; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, gr, sess, IRPD_GETGROUP_ERROR); - - gr = getgrent_p(netdata); - send_grent(sess, gr); -} - -/* - * static void - * irpd_setgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Implementation of the SETGRENT verb. - */ -static void -irpd_setgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct group *gr; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, gr, sess, IRPD_GETGROUP_ERROR); - - setgrent_p(netdata); - simple_response(sess, IRPD_GETGROUP_SETOK, "ok"); -} -#endif /* WANT_IRS_GR */ - -static void -send_servent(struct ctl_sess *sess, struct servent *serv) { - if (serv == NULL) { - simple_response(sess, IRPD_GETSERVICE_NONE, - "No such service"); - } else { - struct response_buff *b = newbuffer(0); - - if (irp_marshall_sv(serv, &b->buff, - &b->bufflen) != 0) { - simple_response(sess, IRPD_GETSERVICE_ERROR, - "Internal error"); - logger(ctl_warning, "Cant marshall servent\n"); - return; - } - - strcat(b->buff, "\r\n"); - - ctl_response(sess, IRPD_GETSERVICE_OK, "Service found", 0, 0, - response_done, b, b->buff, strlen(b->buff)); - } -} - -static void -irpd_getservbyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct servent *serv; - char servicename[64]; - char protoname[10]; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, sv, sess, IRPD_GETSERVICE_ERROR); - - args = split_string(rest); - if (args->iovlen != 3) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETSERVICE_ERROR, - "GETSERVNAM servicename protocol"); - } else { - if (args->iov[0].iov_len >= sizeof servicename) { - simple_response(sess, IRPD_GETSERVICE_ERROR, - "Invalid service name"); - } else if (args->iov[1].iov_len >= sizeof protoname) { - simple_response(sess, IRPD_GETSERVICE_ERROR, - "Invalid protocol name"); - } else { - strncpy(servicename, args->iov[0].iov_base, - args->iov[0].iov_len); - servicename[args->iov[0].iov_len] = '\0'; - - strncpy(protoname, args->iov[1].iov_base, - args->iov[1].iov_len); - protoname[args->iov[1].iov_len] = '\0'; - - serv = getservbyname_p(servicename, protoname, - netdata); - send_servent(sess, serv); - } - } - - free_args(args); -} - -/* - * static void - * irpd_getservbyport(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the GETSERVBYPORT verb. - */ -static void -irpd_getservbyport(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct servent *sv; - char portnum[64]; - char protoname[10]; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, sv, sess, IRPD_GETSERVICE_ERROR); - - args = split_string(rest); - if (args->iovlen != 3) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETSERVICE_ERROR, - "GETSERVBYPORT port protocol"); - } else { - if (args->iov[0].iov_len >= sizeof portnum) { - simple_response(sess, IRPD_GETSERVICE_ERROR, - "Invalid port"); - } else if (args->iov[1].iov_len > sizeof protoname - 1) { - simple_response(sess, IRPD_GETSERVICE_ERROR, - "Invalid protocol"); - } else { - strncpy(portnum, args->iov[0].iov_base, - args->iov[0].iov_len); - portnum[args->iov[0].iov_len] = '\0'; - - strncpy(protoname, args->iov[1].iov_base, - args->iov[1].iov_len); - protoname[args->iov[1].iov_len] = '\0'; - - if (!ALLDIGITS(portnum)) { - simple_response(sess, IRPD_GETSERVICE_ERROR, - "Not a port number"); - } else { - short port; - long lval; - - lval = strtol(portnum, 0, 10); - port = (short)lval; - if ((long)port != lval) { - /* value was too big */ - simple_response(sess, - IRPD_GETSERVICE_ERROR, - "Not a valid port"); - goto untimely; - } - port = htons(port); - - sv = getservbyport_p(port, protoname, netdata); - send_servent(sess, sv); - } - } - } - - untimely: - free_args(args); -} - -/* - * static void - * irpd_getservent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the GETSERVENT verb. - */ -static void -irpd_getservent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct servent *sv; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, sv, sess, IRPD_GETSERVICE_ERROR); - - sv = getservent_p(netdata); - send_servent(sess, sv); -} - -/* - * static void - * irpd_setservent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the SETSERVENT verb. - */ -static void -irpd_setservent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct servent *sv; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, sv, sess, IRPD_GETSERVICE_ERROR); - - setservent_p(1, netdata); /* always stay open */ - simple_response(sess, IRPD_GETSERVICE_SETOK, "ok"); -} - -/* - * static void - * send_prent(struct ctl_sess *sess, struct protoent *pr); - * Send the PR structure over the wire. If PR is NULL, then - * the response "No such protocol" is sent instead. - */ -static void -send_prent(struct ctl_sess *sess, struct protoent *pr) { - if (pr == NULL) { - simple_response(sess, IRPD_GETPROTO_NONE, - "No such protocol"); - } else { - struct response_buff *b = newbuffer(0); - - if (irp_marshall_pr(pr, &b->buff, - &b->bufflen) != 0) { - simple_response(sess, IRPD_GETPROTO_ERROR, - "Internal error"); - logger(ctl_warning, "Cant marshall pr\n"); - return; - } - - strcat(b->buff, "\r\n"); - - ctl_response(sess, IRPD_GETPROTO_OK, "Protocol found", 0, 0, - response_done, b, b->buff, strlen(b->buff)); - } -} - -/* - * static void - * irpd_getprotobyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the GETPROTOBYNAME verb. - */ -static void -irpd_getprotobyname(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct protoent *pr; - char protoname[64]; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, pr, sess, IRPD_GETPROTO_ERROR); - - args = split_string(rest); - if (args->iovlen != 2) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETPROTO_ERROR, - "GETPROTOBYNAME protocol"); - } else { - if (args->iov[0].iov_len >= sizeof protoname) { - simple_response(sess, IRPD_GETPROTO_ERROR, - "Name too long"); - } else { - strncpy(protoname, args->iov[0].iov_base, - args->iov[0].iov_len); - protoname[args->iov[0].iov_len] = '\0'; - - pr = getprotobyname_p(protoname, netdata); - send_prent(sess, pr); - } - } - free_args(args); -} - -/* - * static void - * irpd_getprotobynumber(struct ctl_sctx *ctx, - * struct ctl_sess *sess, const struct ctl_verb *verb, - * const char *rest, u_int respflags, void *respctx, - * void *uctx); - * Handle the GETPROTOBYNUMBER verb. - */ -static void -irpd_getprotobynumber(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct protoent *pr; - char protonum[64]; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, pr, sess, IRPD_GETPROTO_ERROR); - - args = split_string(rest); - if (args->iovlen != 2) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETPROTO_ERROR, - "GETPROTOBYNUMBER protocol"); - } else { - if (args->iov[0].iov_len >= sizeof protonum) { - simple_response(sess, IRPD_GETGROUP_ERROR, - "Name too long"); - } else { - strncpy(protonum, args->iov[0].iov_base, - args->iov[0].iov_len); - protonum[args->iov[0].iov_len] = '\0'; - - if (!ALLDIGITS(protonum)) { - simple_response(sess, IRPD_GETPROTO_ERROR, - "Not a protocol number"); - } else { - int proto; - long lval; - - lval = strtol(protonum, 0, 10); - proto = (int)lval; - if ((long)proto != lval) { - /* value was too big */ - simple_response(sess, - IRPD_GETPROTO_ERROR, - "Not a valid proto"); - goto untimely; - } - - pr = getprotobynumber_p(proto, netdata); - send_prent(sess, pr); - } - } - } - - untimely: - free_args(args); -} - -/* - * static void - * irpd_getprotoent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the GETPROTOENT verb. - */ -static void -irpd_getprotoent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct protoent *pr; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, pr, sess, IRPD_GETPROTO_ERROR); - - pr = getprotoent_p(netdata); - send_prent(sess, pr); -} - -/* - * static void - * irpd_setprotoent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the SETPROTOENT verb. - */ -static void -irpd_setprotoent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct protoent *pr; - size_t need; - size_t need_total = 0; - struct response_buff *b; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, pr, sess, IRPD_GETPROTO_ERROR); - - setprotoent_p(1, netdata); /* always stay open */ - simple_response(sess, IRPD_GETPROTO_SETOK, "ok"); -} - -/* - * static void - * send_pwent(struct ctl_sess *sess, struct passwd *pw); - * Send PW over the wire, or, if PW is NULL, a "No such - * user" response. - */ -static void -send_ngent(struct ctl_sess *sess, char *host, char *user, char *domain) { - struct response_buff *b = newbuffer(0); - - if (irp_marshall_ng(host, user, domain, &b->buff, - &b->bufflen) != 0) { - simple_response(sess, IRPD_GETNETGR_ERROR, - "Internal error"); - logger(ctl_warning, "Cant marshall ng\n"); - return; - } - - strcat(b->buff, "\r\n"); - - ctl_response(sess, IRPD_GETNETGR_OK, "Netgroup entry", 0, 0, - response_done, b, b->buff, strlen(b->buff)); -} - -/* - * static void - * irpd_getnetgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the GETNETGRENT verb. - */ -static void -irpd_getnetgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - char netgroupname[64]; - struct response_buff *b = NULL; - size_t need; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, ng, sess, IRPD_GETNETGR_ERROR); - - if (rest != NULL && strlen(rest) > 0) { - simple_response(sess, IRPD_GETNETGR_ERROR, - "GETNETGRENT"); - } else { - char *host, *user, *domain; - - if (getnetgrent_p(&host, &user, &domain, netdata) == 1) { - send_ngent(sess, host, user, domain); - } else { - simple_response(sess, IRPD_GETNETGR_NOMORE, - "No more"); - } - } -} - -/* - * static void - * irpd_innetgr(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the INNETGR verb. - */ -static void -irpd_innetgr(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct response_buff *b; - size_t need; - struct net_data *netdata = get_net_data(sess); - char *host; - char *user; - char *domain; - - INSIST(netdata != NULL); - - ND_INIT(netdata, ng, sess, IRPD_GETNETGR_ERROR); - - args = split_string(rest); - if (args->iovlen != 3) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETNETGR_ERROR, - "INNETGR netgroup ngentry"); - } else { - char *grptmp = memget(args->iov[0].iov_len + 1); - char *ngtmp = memget(args->iov[1].iov_len + 1); - - strncpy(grptmp, args->iov[0].iov_base, args->iov[0].iov_len); - strncpy(ngtmp, args->iov[1].iov_base, args->iov[1].iov_len); - - grptmp[args->iov[0].iov_len] = '\0'; - ngtmp[args->iov[1].iov_len] = '\0'; - - if (irp_unmarshall_ng(&host, &user, &domain, ngtmp) != 0) { - simple_response(sess, IRPD_GETNETGR_ERROR, - "ngentry must be (host,user,domain)"); - } else { - if (innetgr_p(grptmp, host, user, domain, - netdata) == 1) { - simple_response(sess, IRPD_GETNETGR_MATCHES, - "INNETGR matches"); - } else { - simple_response(sess, IRPD_GETNETGR_NOMATCH, - "INNETGR does not match"); - } - } - - memput(grptmp, args->iov[0].iov_len + 1); - memput(ngtmp, args->iov[1].iov_len + 1); - } - - untimely: - free_args(args); -} - -/* - * static void - * irpd_setnetgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the SETNETGRENT verb. - */ -static void -irpd_setnetgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, ng, sess, IRPD_GETNETGR_ERROR); - - args = split_string(rest); - if (args->iovlen != 2) { /* len includes NULL at end */ - simple_response(sess, IRPD_GETNETGR_ERROR, - "setnetgrent netgroup"); - } else { - setnetgrent_p(rest, netdata); - simple_response(sess, IRPD_GETNETGR_SETOK, - "setnetgrent ok"); - } - - untimely: - free_args(args); -} - -/* - * static void - * irpd_endnetgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the ENDNETGRENT verb. - */ -static void -irpd_endnetgrent(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct arg_s *args; - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - ND_INIT(netdata, ng, sess, IRPD_GETNETGR_ERROR); - - if (rest != NULL && strlen (rest) > 0) { - simple_response(sess, IRPD_GETNETGR_ERROR, - "endnetgrent netgroup"); - } else { - endnetgrent_p(netdata); - simple_response(sess, IRPD_GETNETGR_SETOK, - "endnetgrent ok"); - } -} - -/* - * static void - * irpd_done(struct ctl_sctx *ctx, struct ctl_sess *sess, void *param) - * Callback for when QUIT respnse is sent out. - */ -static void -irpd_done(struct ctl_sctx *ctx, struct ctl_sess *sess, void *param) { - struct net_data *netdata = get_net_data(sess); - - INSIST(netdata != NULL); - - net_data_destroy(netdata); -} - -/* - * static void - * irpd_quit(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the QUIT verb. - */ -static void -irpd_quit(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - ctl_response(sess, irpd_quit_ok, "See ya!", CTL_EXIT, NULL, - 0 , NULL, NULL, 0); -} - -/* - * static void - * irpd_help(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle the HELP verb. - */ -static void -irpd_help(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - /* XXX should make this do something better (like include required - * arguments. - */ - ctl_sendhelp(sess, 231); -} - -/* - * static void - * irpd_accept(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle a new connection. - */ -static void -irpd_accept(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct sockaddr *sa = respctx; - char raddr[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - int reject = 1; - int response; - char *respmsg = NULL; - - if (sa->sa_family == AF_UNIX) { - syslog (LOG_INFO, "New AF_UNIX connection"); - reject = 0; - } else if (sa->sa_family == AF_INET) { - struct sockaddr_in *sin = respctx; - static long localhost; - static long zero; - - if (localhost == 0) { - /* yes, this could be done with simple arithmetic... */ - inet_pton(AF_INET, "127.0.0.1", &localhost); - } - - inet_ntop(AF_INET, &sin->sin_addr, raddr, sizeof raddr); - - /* we reject INET connections that are not from the local - * machine. - */ - if (sin->sin_addr.s_addr == zero || - sin->sin_addr.s_addr == localhost) { - reject = 0; - syslog(LOG_INFO, "New connection from %s", raddr); - } else { - syslog(LOG_INFO, "New connection from %s (reject)", - raddr); - respmsg = "Connections from off host not permitted"; - } - } else if (sa->sa_family == AF_INET6) { - /* XXX should do something intelligent here. */ - respmsg = "IPv6 connections not implemented yet."; - syslog(LOG_ERR, "Cannot handle AF_INET6 connections yet"); - } else { - syslog (LOG_ERR, "Unknown peer type: %d", sa->sa_family); - respmsg = "What are you???"; - } - - if (reject) { - response = IRPD_NOT_WELCOME_CODE; - if (respmsg == NULL) { - respmsg = "Go away!"; - } - /* XXX can we be sure that stacked up commands will not be - * processed before the control connection is closed??? - */ - } else { - void *ctx = make_cli_ctx(); - - if (ctx == NULL) { - response = IRPD_NOT_WELCOME_CODE; - respmsg = "Internal error (client context)"; - } else { - response = IRPD_WELCOME_CODE; - if (respmsg == NULL) { - respmsg = "Welcome to IRPD (v 1)"; - } - ctl_setcsctx(sess, ctx); - } - } - ctl_response(sess, response, respmsg, (reject ? CTL_EXIT : 0), NULL, - 0, NULL, NULL, 0); -} - -/* - * static void - * irpd_abort(struct ctl_sctx *ctx, struct ctl_sess *sess, - * const struct ctl_verb *verb, const char *rest, - * u_int respflags, void *respctx, void *uctx); - * Handle a dropped connection. - */ -static void -irpd_abort(struct ctl_sctx *ctx, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct net_data *netdata = get_net_data(sess); - - if (netdata != NULL) - net_data_destroy(netdata); -} - -/* - * void - * response_done(struct ctl_sctx *ctx, struct ctl_sess *sess, void *uap) - * UAP is the response_buffer passed through to - * ctl_response. - */ -static void -response_done(struct ctl_sctx *ctx, struct ctl_sess *sess, void *uap) { - release_buffer(uap); -} - -/* - * static void - * logger(enum ctl_severity sev, const char *fmt, ...); - * Logging routine called by the ctl_* functions. For now we - * just spit everything to stderr. - */ - -static void -logger(enum ctl_severity sev, const char *fmt, ...) { - char buffer[1024]; - va_list ap; - int level; - - if (sev == ctl_debug) - return; - - if (sev == ctl_warning) - level = LOG_WARNING; - else if (sev == ctl_error) - level = LOG_ERR; - else { - syslog(LOG_CRIT, "Invalid severity: %d", (int)sev); - exit(1); - } - - va_start(ap, fmt); - -#if 0 - fprintf(stderr, "irpd: "); - vfprintf(stderr, fmt, ap); -#else - if (vsprintf(buffer, fmt, ap) > (sizeof (buffer) - 1)) { - syslog(LOG_CRIT, "Buffer overrun in logger"); - abort(); - } - syslog(level, "%s", buffer); -#endif - va_end(ap); -} - -/* - * static struct response_buff * - * newbuffer(u_int length); - * Create a structure to hold an allocated buffer. We do - * this so we can get the size to deallocate later. - * Returns: - * Pointer to the structure - */ -static struct response_buff * -newbuffer(u_int length) { - struct response_buff *h; - - h = memget(sizeof *h); - if (h == NULL) { - errno = ENOMEM; - return (NULL); - } - - h->buff = NULL; - h->bufflen = length; - - if (length > 0) { - h->buff = memget(h->bufflen); - if (h->buff == NULL) { - memput(h, sizeof *h); - errno = ENOMEM; - return (NULL); - } - memset(h->buff, 0, h->bufflen); - } - - return (h); -} - -/* - * static void - * release_buffer(struct response_buff *b); - * Free up a buffer allocated with newbuffer. - */ -static void -release_buffer(struct response_buff *b) { - memset(b->buff, 0, b->bufflen); - memput(b->buff, b->bufflen); - - memset(b, 0, sizeof *b); - memput(b, sizeof *b); -} - -/* - * static struct arg_s * - * split_string(const char *string); - * Create an array of iovecs(last one having NULL fields) - * pointing into STRING at the non-whitespace sections. The - * iovecs are stashed inside a structure so we can get the - * size back later at deallocation time. Iovecs are used to avoid - * modifying the argument with added nulls. - * Returns: - * Pointer to the wrapper structure. Must be given to free_args() - * when done - */ -static struct arg_s * -split_string(const char *string) { - struct iovec *iovs; - const char *p; - int i, c, iswh; - struct arg_s *a; - - /* count + 1 of the number of runs of non-whitespace. */ - for (iswh = 1, i = 1, p = string ; p != NULL && *p ; p++) { - if (iswh && !isspace(*p)) { - iswh = 0; - i++; - } else if (!iswh && isspace(*p)) { - iswh = 1; - } - } - - iovs = memget(sizeof (struct iovec) * i); - if (iovs == NULL) { - errno = ENOMEM; - return (NULL); - } - - a = memget(sizeof *a); - if (a == NULL) { - errno = ENOMEM; - memput(iovs, sizeof (struct iovec) * i); - return (NULL); - } - a->iov = iovs; - a->iovlen = i; - - for (c = 0, p = string ; p != NULL && *p ; c++) { - while (isspace(*p)) { - p++; - } - - if (*p == '\0') - break; - - iovs[c].iov_base = (void *)p; - - while (*p && !isspace(*p)) { - p++; - } - iovs[c].iov_len = p - (char *)iovs[c].iov_base; - } - INSIST(c == i - 1); - iovs[c].iov_base = NULL; - iovs[c].iov_len = 0; - - return (a); -} - -/* - * static void - * free_args(struct arg_s *args); - * Free up the argument structure created with - * split_string(). - */ - -static void -free_args(struct arg_s *args) { - memput(args->iov, sizeof (struct iovec) * args->iovlen); - memput(args, sizeof *args); -} - -static struct client_ctx * -make_cli_ctx(void) { - struct client_ctx *p = memget (sizeof *p); - - if (p == NULL) - return (NULL); - - p->net_data = net_data_create(conffile); - - return (p); -} - -static void -release_cli_ctx(struct client_ctx *ctx) { - INSIST(ctx != NULL); - INSIST(ctx->net_data != NULL); - - net_data_destroy(ctx->net_data); - memput(ctx, sizeof *ctx); -} - -static struct net_data * -get_net_data(struct ctl_sess *sess) { - struct client_ctx *ctx = ctl_getcsctx(sess); - - INSIST(ctx != NULL); - INSIST(ctx->net_data != NULL); - - return (ctx->net_data); -} diff --git a/contrib/bind/bin/irpd/irs-irpd.conf b/contrib/bind/bin/irpd/irs-irpd.conf deleted file mode 100644 index 07385d33c4f3c..0000000000000 --- a/contrib/bind/bin/irpd/irs-irpd.conf +++ /dev/null @@ -1,11 +0,0 @@ -# Private irs config file for irpd so that it doesn't get configured to -# talk to itself. -passwd local -group local -services local -protocols local -hosts dns continue -hosts local -networks dns continue -networks local -netgroup local diff --git a/contrib/bind/bin/irpd/version.c b/contrib/bind/bin/irpd/version.c deleted file mode 100644 index cc42c0bac4d39..0000000000000 --- a/contrib/bind/bin/irpd/version.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 1996 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -char sccsid[] = "@(#)named %VERSION% %WHEN% %WHOANDWHERE%"; -char rcsid[] = "$Id: version.c,v 1.1 1999/01/18 07:47:17 vixie Exp $"; -#endif /* not lint */ - -char Version[] = "named %VERSION% %WHEN%\n\t%WHOANDWHERE%"; -char ShortVersion[] = "%VERSION%"; - diff --git a/contrib/bind/bin/mkservdb/Makefile b/contrib/bind/bin/mkservdb/Makefile deleted file mode 100644 index 300505d3b9317..0000000000000 --- a/contrib/bind/bin/mkservdb/Makefile +++ /dev/null @@ -1,84 +0,0 @@ -## Copyright (c) 1998,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 1.7 2000/07/11 06:41:30 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -PROG= mkservdb -SRCS= ${PROG}.c -OBJS= ${PROG}.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} \ - ${LIBBIND} ${SYSLIBS} - -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${SRCS} - -${DESTDIR}${DESTBIN}: - mkdir -p ${DESTDIR}${DESTBIN} - -install: ${DESTDIR}${DESTBIN} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTBIN}/${PROG}${EXE} - -links: FRC - @set -e; ln -s SRC/*.[ch] . - -tags: FRC - ctags *.[ch] - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/mkservdb/mkservdb.c b/contrib/bind/bin/mkservdb/mkservdb.c deleted file mode 100644 index 5647ec70eb9ea..0000000000000 --- a/contrib/bind/bin/mkservdb/mkservdb.c +++ /dev/null @@ -1,169 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: mkservdb.c,v 1.6 1999/10/13 16:39:00 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1998,1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <resolv.h> - -#include <ctype.h> -#ifdef IRS_LCL_SV_DB -#include <db.h> -#endif -#include <fcntl.h> -#include <limits.h> -#include <netdb.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "../../include/irs.h" -#include "../../lib/irs/irs_p.h" - -#include "port_after.h" - -#ifdef SPRINTF_CHAR -# define SPRINTF(x) strlen(sprintf/**/x) -#else -# define SPRINTF(x) ((size_t)sprintf x) -#endif - -#ifndef IRS_LCL_SV_DB -main(int argc, char **argv) { - fprintf(stderr, "%s: not supported on this architecture\n", argv[0]); - exit(1); -} - -#else - -#define _PATH_SERVICES_DB_TMP _PATH_SERVICES_DB ".new" - -struct servent *getnextent(FILE *); - -main(int argc, char **argv) { - DB *db; - DBT key; - DBT data; - char *filename = _PATH_SERVICES; - char *tmpdatabase = _PATH_SERVICES_DB_TMP; - char *database = _PATH_SERVICES_DB; - char dbuf[1024]; - char kbuf[512]; - u_short *ports; - struct lcl_sv lcl_sv; - struct servent *sv; - int n, r; - char *p; - - unlink(tmpdatabase); - - if (argc > 1) - filename = argv[1]; - - lcl_sv.fp = fopen(filename, "r"); - if (lcl_sv.fp == NULL) - err(1, "%s", filename); - - db = dbopen(tmpdatabase, O_CREAT|O_RDWR, 0444, DB_BTREE, NULL); - if (db == NULL) - err(1, "%s", tmpdatabase); - - while ((sv = irs_lclsv_fnxt(&lcl_sv)) != NULL) { - if (sv->s_proto == NULL) - continue; - - key.data = kbuf; - data.data = dbuf; - - /* Note that (sizeof "/") == 2. */ - if (strlen(sv->s_name) + sizeof "/" + strlen(sv->s_proto) - > sizeof kbuf) - continue; - key.size = SPRINTF((kbuf, "%s/%s", sv->s_name, sv->s_proto))+1; - - ((u_short *)dbuf)[0] = sv->s_port; - p = dbuf; - p += sizeof(u_short); - if (sv->s_aliases) - for (n = 0; sv->s_aliases[n]; ++n) { - strcpy(p, sv->s_aliases[n]); - p += strlen(p) + 1; - } - data.size = p - dbuf; - - if ((r = db->put(db, &key, &data, R_NOOVERWRITE))) - if (r < 0) - errx(1, "failed to write %s", key.data); - else - warnx("will not overwrite %s", key.data); - for (n = 0; sv->s_aliases[n]; ++n) { - if (strlen(sv->s_aliases[n]) + sizeof "/" - + strlen(sv->s_proto) > sizeof kbuf) - continue; - key.size = SPRINTF((kbuf, "%s/%s", - sv->s_aliases[n], sv->s_proto))+1; - if ((r = db->put(db, &key, &data, R_NOOVERWRITE))) - if (r < 0) - errx(1, "failed to write %s", - key.data); - else - warnx("will not overwrite %s", - key.data); - } - - ports = (u_short *)kbuf; - ports[0] = 0; - ports[1] = sv->s_port; - strcpy((char *)(ports+2), sv->s_proto); - key.size = sizeof(u_short) * 2 + strlen((char *)(ports+2)) + 1; - - if (strlen(sv->s_name) + sizeof "/" + strlen(sv->s_proto) - > sizeof dbuf) - continue; - p = dbuf; - p += SPRINTF((p, "%s/%s", sv->s_name, sv->s_proto)) + 1; - if (sv->s_aliases != NULL) - for (n = 0; sv->s_aliases[n] != NULL; n++) - if ((p + strlen(sv->s_aliases[n]) + 1) - dbuf - <= sizeof dbuf) { - strcpy(p, sv->s_aliases[n]); - p += strlen(p) + 1; - } - data.size = p - dbuf; - - if ((r = db->put(db, &key, &data, R_NOOVERWRITE))) - if (r < 0) - errx(1, "failed to write %d/%s", - ntohs(sv->s_port), sv->s_proto); - else - warnx("will not overwrite %d/%s", - ntohs(sv->s_port), sv->s_proto); - } - db->close(db); - if (rename(tmpdatabase, database)) - err(1, "rename %s -> %s", tmpdatabase, database); - exit(0); -} - -#endif diff --git a/contrib/bind/bin/named-bootconf/Grot/named-bootconf.pl b/contrib/bind/bin/named-bootconf/Grot/named-bootconf.pl deleted file mode 100644 index ce1b368d2d704..0000000000000 --- a/contrib/bind/bin/named-bootconf/Grot/named-bootconf.pl +++ /dev/null @@ -1,324 +0,0 @@ -#!/usr/bin/perl - -## Copyright (c) 1996-1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -## $Id: named-bootconf.pl,v 1.2 1999/01/08 19:27:35 vixie Exp $ - -# This is a filter. Input is a named.boot. Output is a named.conf. - -$new_config = ""; - -$have_options = 0; -%options = (); -%options_comments = (); -@topology = (); -@topology_comments = (); -@bogus = (); -@bogus_comments = (); -@transfer_acl = (); -@transfer_comments = (); -$logging = ""; - -while(<>) { - next if /^$/; - - # skip comment-only lines - if (/^\s*;+\s*(.*)$/) { - $new_config .= "// $1\n"; - next; - } - - # handle continued lines - while (/\\$/) { - s/\\$/ /; - $_ .= <>; - } - - chop; - - # deal with lines ending in a coment - if (s/\s*;+\s*(.*)$//) { - $comment = "// $1"; - } else { - $comment = ""; - } - - ($directive, @rest) = split; - - $class = ""; - if ($directive =~ /^(.*)\/(.*)$/) { - $directive = $1; - $class = $2; - } - - if ($directive eq "primary") { - $zname = shift(@rest); - &maybe_print_comment("","\n"); - $new_config .= "zone \"$zname\" "; - if ($class ne "") { - $new_config .= "$class "; - } - $new_config .= "{\n"; - $new_config .= "\ttype master;\n"; - $filename = shift(@rest); - $new_config .= "\tfile \"$filename\";\n"; - $new_config .= "};\n\n"; - } elsif ($directive eq "secondary" || $directive eq "stub") { - if ($directive eq "secondary") { - $type = "slave"; - } else { - $type = "stub"; - } - $zname = shift(@rest); - &maybe_print_comment("","\n"); - $new_config .= "zone \"$zname\" "; - if ($class ne "") { - $new_config .= "$class "; - } - $new_config .= "{\n"; - $new_config .= "\ttype $type;\n"; - $filename = pop(@rest); - if ($filename =~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) { - push(@rest, $filename); - $filename = ""; - } else { - $new_config .= "\tfile \"$filename\";\n"; - } - $new_config .= "\tmasters {\n"; - foreach $master (@rest) { - $new_config .= "\t\t$master;\n"; - } - $new_config .= "\t};\n"; - $new_config .= "};\n\n"; - } elsif ($directive eq "cache") { - $zname = shift(@rest); - &maybe_print_comment("","\n"); - $new_config .= "zone \"$zname\" {\n"; - $new_config .= "\ttype hint;\n"; - $filename = shift(@rest); - $new_config .= "\tfile \"$filename\";\n"; - $new_config .= "};\n\n"; - } elsif ($directive eq "directory") { - $options{"directory"} = "\"$rest[0]\""; - $options_comments{"directory"} = $comment; - $have_options = 1; - } elsif ($directive eq "check-names") { - $type = shift(@rest); - if ($type eq "primary") { - $type = "master"; - } elsif ($type eq "secondary") { - $type = "slave"; - } - $action = shift(@rest); - $options{"check-names $type"} = $action; - $options_comments{"check-names $type"} = $comment; - $have_options = 1; - } elsif ($directive eq "forwarders") { - $options{"forwarders"}="{\n"; - foreach $forwarder (@rest) { - $options{"forwarders"} .= "\t\t$forwarder;\n"; - } - $options{"forwarders"} .= "\t}"; - $options_comments{"forwarders"} = $comment; - $have_options = 1; - } elsif ($directive eq "slave") { - &handle_options("forward-only"); - } elsif ($directive eq "options") { - &handle_options(@rest); - } elsif ($directive eq "limit") { - &handle_limit(@rest); - } elsif ($directive eq "include") { - $new_config .= - "// make sure your include is still in the right place\n"; - $comment = "\t" . $comment; - $new_config .= "include \"$rest[0]\";$comment\n\n"; - } elsif ($directive eq "xfrnets" || $directive eq "tcplist") { - if ($comment ne "") { - $comment = "\t$comment"; - } - foreach $elt (@rest) { - push(@transfer_acl, $elt); - push(@transfer_comments, $comment); - } - $have_options = 1; - } elsif ($directive eq "sortlist") { - if ($comment ne "") { - $comment = "\t$comment"; - } - foreach $elt (@rest) { - push(@topology, $elt); - push(@topology_comments, $comment); - } - } elsif ($directive eq "bogusns") { - if ($comment ne "") { - $comment = "\t$comment"; - } - foreach $elt (@rest) { - push(@bogus, $elt); - push(@bogus_comments, $comment); - } - } elsif ($directive eq "max-fetch") { - $options{"transfers-in"}=$rest[0]; - $options_comments{"transfers-in"}=$comment; - $have_options = 1; - } else { - $new_config .= "// NOTE: unconverted directive '$directive @rest'\n\n"; - } -} - -print "// generated by named-bootconf.pl\n\n"; -if ($have_options) { - print "options {\n"; - foreach $option (sort(keys(%options))) { - print "\t$option $options{$option};"; - if ($options_comments{$option} ne "") { - print "\t$options_comments{$option}"; - } - print "\n"; - } - if (@transfer_acl > 0) { - print "\tallow-transfer {\n"; - for ($i = 0; $i <= $#transfer_acl; $i++) { - &print_maybe_masked("\t\t", $transfer_acl[$i], - $transfer_comments[$i]); - } - print "\t};\n"; - } - print "\t/* -\t * If there is a firewall between you and nameservers you want -\t * to talk to, you might need to uncomment the query-source -\t * directive below. Previous versions of BIND always asked -\t * questions using port 53, but BIND 8.1 uses an unprivileged -\t * port by default. -\t */ -\t// query-source address * port 53; -"; - - print "};\n\n"; -} -if ($logging ne "") { - print "logging {\n$logging};\n\n"; -} -if (@topology > 0) { - print "// Note: the following will be supported in a future release.\n"; - print "/*\n"; - print "host { any; } {\n\ttopology {\n"; - for ($i = 0; $i <= $#topology; $i++) { - &print_maybe_masked("\t\t", $topology[$i], - $topology_comments[$i]); - } - print "\t};\n};\n"; - print "*/\n"; - print "\n"; -} -if (@bogus > 0) { - for ($i = 0; $i <= $#bogus; $i++) { - print "server $bogus[$i] { bogus yes; };$bogus_comments[$i]\n"; - } - print "\n"; -} -print $new_config; - -exit 0; - -sub maybe_print_comment { - $prefix = shift; - $suffix = shift; - if ($comment ne "") { - $new_config .= sprintf("%s%s%s", $prefix, $comment, $suffix); - } -} - -sub handle_options { - foreach $option (@_) { - if ($option eq "forward-only") { - $options{"forward"}="only"; - $options_comments{"forward"}=$comment; - $have_options = 1; - } elsif ($option eq "no-recursion") { - $options{"recursion"}="no"; - $options_comments{"recursion"}=$comment; - $have_options = 1; - } elsif ($option eq "no-fetch-glue") { - $options{"fetch-glue"}="no"; - $options_comments{"fetch-glue"}=$comment; - $have_options = 1; - } elsif ($option eq "fake-iquery") { - $options{"fake-iquery"}="yes"; - $options_comments{"fake-iquery"}=$comment; - $have_options = 1; - } elsif ($option eq "query-log") { - if ($comment ne "") { - $logging .= "\t$comment\n"; - } - $logging .= "\tcategory queries { default_syslog; };\n"; - } else { - $options{"// NOTE: unconverted option '$option'"}=""; - $options_comments{"// NOTE: unconverted option '$option'"}= - $comment; - $have_options = 1; - } - } -} - -sub handle_limit { - $limit = shift; - if ($limit eq "datasize" || $limit eq "transfers-in" - || $limit eq "transfers-per-ns" || $limit eq "files") { - $options{$limit}=$_[0]; - $options_comments{$limit}=$comment; - $have_options = 1; - } else { - $options{"// NOTE: unconverted limit '$limit @_'"}=""; - $options_comments{"// NOTE: unconverted limit '$limit @_'"}=$comment; - $have_options = 1; - } -} - -sub print_maybe_masked { - # this assumes a contiguous netmask starting at the MSB - $prefix = shift; - $elt = shift; - $elt_comment = shift; - if ($elt =~ /^(.*)&(.*)$/) { - $address = $1; - $mask = $2; - ($m1,$m2,$m3,$m4) = split(/\./, $mask); - $mask_val = ($m1 << 24) + ($m2 << 16) +($m3 << 8) + $m4; - $zero_bits = 0; - while (($mask_val % 2) == 0) { - $mask_val /= 2; - $zero_bits++; - } - $mask_bits = 32 - $zero_bits; - } else { - $address = $elt; - ($a1,$a2,$a3,$a4) = split(/\./, $address); - if ($a1 < 128) { - $mask_bits = 8; - } elsif ($a1 < 192) { - $mask_bits = 16; - } else { - $mask_bits = 24; - } - } - - print "$prefix$address"; - if ($mask_bits != 32) { - print "/$mask_bits"; - } - print ";$elt_comment\n"; -} diff --git a/contrib/bind/bin/named-bootconf/Makefile b/contrib/bind/bin/named-bootconf/Makefile deleted file mode 100644 index 35403e9b43655..0000000000000 --- a/contrib/bind/bin/named-bootconf/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -## Copyright (c) 1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 1.2 2000/07/11 06:41:33 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -PROG= named-bootconf - -all: ${PROG} - -${PROG}: ${PROG}.sh Makefile - cp ${PROG}.sh ${PROG} - chmod +x ${PROG} - -distclean: clean - -clean: FRC - rm -f ${PROG} - rm -f *.BAK *.CKP *~ *.orig - -depend: - -${DESTDIR}${DESTSBIN}: - mkdir -p ${DESTDIR}${DESTSBIN} - -install: ${DESTDIR}${DESTSBIN} ${PROG} - ${INSTALL} -c -m 755 ${PROG} ${DESTDIR}${DESTSBIN}/${PROG} - -links: FRC - @set -e; ln -s SRC/*.sh . - -tags: - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/named-bootconf/named-bootconf.sh b/contrib/bind/bin/named-bootconf/named-bootconf.sh deleted file mode 100644 index c1dfaad8c9a81..0000000000000 --- a/contrib/bind/bin/named-bootconf/named-bootconf.sh +++ /dev/null @@ -1,306 +0,0 @@ -#!/bin/sh -# -# $NetBSD: named-bootconf.sh,v 1.5 1998/12/15 01:00:53 tron Exp $ -# -# Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. -# All rights reserved. -# -# This code is derived from software contributed to The NetBSD Foundation -# by Matthias Scheler. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the NetBSD -# Foundation, Inc. and its contributors. -# 4. Neither the name of The NetBSD Foundation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -## Copyright (c) 1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -if [ ${OPTIONFILE-X} = X ]; then - OPTIONFILE=/tmp/.options.`date +%s`.$$ - ZONEFILE=/tmp/.zones.`date +%s`.$$ - COMMENTFILE=/tmp/.comments.`date +%s`.$$ - export OPTIONFILE ZONEFILE COMMENTFILE - touch $OPTIONFILE $ZONEFILE $COMMENTFILE - DUMP=1 -else - DUMP=0 -fi - -while read CMD ARGS; do - class= - CMD=`echo "${CMD}" | tr '[A-Z]' '[a-z]'` - case $CMD in - \; ) - echo \# $ARGS >>$COMMENTFILE - ;; - cache ) - set - X $ARGS - shift - if [ $# -eq 2 ]; then - (echo "" - cat $COMMENTFILE - echo "zone \"$1\" {" - echo " type hint;" - echo " file \"$2\";" - echo "};") >>$ZONEFILE - rm -f $COMMENTFILE - touch $COMMENTFILE - fi - ;; - directory ) - set - X $ARGS - shift - if [ $# -eq 1 ]; then - (cat $COMMENTFILE - echo " directory \"$1\";") >>$OPTIONFILE - rm -f $COMMENTFILE - touch $COMMENTFILE - - DIRECTORY=$1 - export DIRECTORY - fi - ;; - forwarders ) - (cat $COMMENTFILE - echo " forwarders {" - for ARG in $ARGS; do - echo " $ARG;" - done - echo " };") >>$OPTIONFILE - rm -f $COMMENTFILE - touch $COMMENTFILE - ;; - include ) - if [ "$ARGS" != "" ]; then - (cd ${DIRECTORY-.}; cat $ARGS) | $0 - fi - ;; - limit ) - ARGS=`echo "${ARGS}" | tr '[A-Z]' '[a-z]'` - set - X $ARGS - shift - if [ $# -eq 2 ]; then - cat $COMMENTFILE >>$OPTIONFILE - case $1 in - datasize | files | transfers-in | transfers-per-ns ) - echo " $1 $2;" >>$OPTIONFILE - ;; - esac - rm -f $COMMENTFILE - touch $COMMENTFILE - fi - ;; - options ) - ARGS=`echo "${ARGS}" | tr '[A-Z]' '[a-z]'` - cat $COMMENTFILE >>$OPTIONFILE - for ARG in $ARGS; do - case $ARG in - fake-iquery ) - echo " fake-iquery yes;" >>$OPTIONFILE - ;; - forward-only ) - echo " forward only;" >>$OPTIONFILE - ;; - no-fetch-glue ) - echo " fetch-glue no;" >>$OPTIONFILE - ;; - no-recursion ) - echo " recursion no;" >>$OPTIONFILE - ;; - esac - done - rm -f $COMMENTFILE - touch $COMMENTFILE - ;; - primary|primary/* ) - case $CMD in - primary/chaos ) - class="chaos " - ;; - primary/hs ) - class="hesiod " - ;; - esac - set - X $ARGS - shift - if [ $# -eq 2 ]; then - (echo "" - cat $COMMENTFILE - echo "zone \"$1\" ${class}{" - echo " type master;" - echo " file \"$2\";" - echo "};") >>$ZONEFILE - rm -f $COMMENTFILE - touch $COMMENTFILE - fi - ;; - secondary|secondary/* ) - case $CMD in - secondary/chaos ) - class="chaos " - ;; - secondary/hs ) - class="hesiod " - ;; - esac - set - X $ARGS - shift - if [ $# -gt 2 ]; then - ZONE=$1 - shift - PRIMARIES=$1 - while [ $# -gt 2 ]; do - shift - PRIMARIES="$PRIMARIES $1" - done - (echo "" - cat $COMMENTFILE - echo "zone \"$ZONE\" ${class}{" - echo " type slave;" - echo " file \"$2\";" - echo " masters {" - for PRIMARY in $PRIMARIES; do - echo " $PRIMARY;" - done - echo " };" - echo "};") >>$ZONEFILE - rm -f $COMMENTFILE - touch $COMMENTFILE - fi - ;; - stub|stub/* ) - case $CMD in - stub/chaos ) - class="chaos " - ;; - stub/hs ) - class="hesiod " - ;; - esac - set - X $ARGS - shift - if [ $# -gt 2 ]; then - ZONE=$1 - shift - PRIMARIES=$1 - while [ $# -gt 2 ]; do - shift - PRIMARIES="$PRIMARIES $1" - done - (echo "" - cat $COMMENTFILE - echo "zone \"$ZONE\" ${class}{" - echo " type stub;" - echo " file \"$2\";" - echo " masters {" - for PRIMARY in $PRIMARIES; do - echo " $PRIMARY;" - done - echo " };" - echo "};") >>$ZONEFILE - rm -f $COMMENTFILE - touch $COMMENTFILE - fi - ;; - slave ) - cat $COMMENTFILE >>$OPTIONFILE - echo " forward only;" >>$OPTIONFILE - rm -f $COMMENTFILE - touch $COMMENTFILE - ;; - sortlist ) - (cat $COMMENTFILE - echo " topology {" - for ARG in $ARGS; do - case $ARG in - *.0.0.0 ) - echo " $ARG/8;" - ;; - *.0.0 ) - echo " $ARG/16;" - ;; - *.0 ) - echo " $ARG/24;" - ;; - * ) - echo " $ARG;" - ;; - esac - done - echo " };") >>$OPTIONFILE - rm -f $COMMENTFILE - touch $COMMENTFILE - ;; - tcplist | xfrnets ) - (cat $COMMENTFILE - echo " allow-transfer {" - for ARG in $ARGS; do - case $ARG in - *.0.0.0 ) - echo " $ARG/8;" - ;; - *.0.0 ) - echo " $ARG/16;" - ;; - *.0 ) - echo " $ARG/24;" - ;; - * ) - echo " $ARG;" - ;; - esac - done - echo " };") >>$OPTIONFILE - rm -f $COMMENTFILE - touch $COMMENTFILE - ;; - esac -done - -if [ $DUMP -eq 1 ]; then - echo "" - echo "options {" - cat $OPTIONFILE - echo "};" - cat $ZONEFILE $COMMENTFILE - - rm -f $OPTIONFILE $ZONEFILE $COMMENTFILE -fi - -exit 0 diff --git a/contrib/bind/bin/named-xfer/Makefile b/contrib/bind/bin/named-xfer/Makefile deleted file mode 100644 index b85a4d54e4af1..0000000000000 --- a/contrib/bind/bin/named-xfer/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 8.30 2000/07/11 06:41:34 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -EXE= -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -AR= ar cru -INSTALL= install -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -PS=ps -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -NAMED_OBJS= \ - ../named/db_glue.${O} ../named/ns_glue.${O} ../named/tmp_version.${O} - -PROG= named-xfer -SRCS= ${PROG}.c -OBJS= ${PROG}.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${OBJS} ${NAMED_OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} ${NAMED_OBJS} \ - ${LIBBIND} ${SYSLIBS} -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${SRCS} - -${DESTDIR}${DESTEXEC}: - mkdir -p ${DESTDIR}${DESTEXEC} - -install: ${DESTDIR}${DESTEXEC} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTEXEC}/${PROG}${EXE} - -links: FRC - @set -e; ln -s SRC/*.[ch] . - -tags: FRC - ctags ${SRCS} *.h - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/named-xfer/named-xfer.c b/contrib/bind/bin/named-xfer/named-xfer.c deleted file mode 100644 index 3747526756ab9..0000000000000 --- a/contrib/bind/bin/named-xfer/named-xfer.c +++ /dev/null @@ -1,3198 +0,0 @@ -/* - * The original version of named-xfer by Kevin Dunlap. - * Completed and integrated with named by David Waitzman - * (dwaitzman@bbn.com) 3/14/88. - * Modified by M. Karels and O. Kure 10-88. - * Modified extensively since then by just about everybody. - */ - -/* - * Copyright (c) 1988, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1995 by International Business Machines, Inc. - * - * International Business Machines, Inc. (hereinafter called IBM) grants - * permission under its copyrights to use, copy, modify, and distribute this - * Software with or without fee, provided that the above copyright notice and - * all paragraphs of this notice appear in all copies, and that the name of IBM - * not be used in connection with the marketing of any product incorporating - * the Software or modifications thereof, without specific, written prior - * permission. - * - * To the extent it has a right to do so, IBM grants an immunity from suit - * under its patents, if any, for the use, sale or manufacture of products to - * the extent that such products are used for performing Domain Name System - * dynamic updates in TCP/IP networks by means of the Software. No immunity is - * granted for any product per se or for any other function of any product. - * - * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, - * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN - * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. - */ - -/* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1998 by MetaInfo, Incorporated. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of MetaInfo Incorporated not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND METAINFO INCORPORATED DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL METAINFO INCORPRATED - * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#if !defined(lint) && !defined(SABER) -char copyright[] = -"@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\ - portions Copyright (c) 1993 Digital Equipment Corporation\n\ - portions Copyright (c) 1998 MetaInfo, Inc.\n\ - portions Copyright (c) 1995, 1996 Internet Software Consorium\n\ - All rights reserved.\n"; -#endif /* not lint */ - -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)named-xfer.c 4.18 (Berkeley) 3/7/91"; -static const char rcsid[] = "$Id: named-xfer.c,v 8.94 2000/07/11 05:38:27 vixie Exp $"; -#endif /* not lint */ - -#include "port_before.h" -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <limits.h> -#include <ctype.h> -#include <errno.h> -#include <math.h> -#include <resolv.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <stdarg.h> - -#include <isc/eventlib.h> -#include <isc/list.h> -#include <isc/logging.h> -/* This still uses malloc/free, but the tsig routines allocate memory with - * memget, and we free it with memput. - */ -#include <isc/memcluster.h> - -#include <isc/dst.h> - -#include "port_after.h" - - -#define MAIN_PROGRAM -#include "../named/named.h" -#undef MAIN_PROGRAM - -#define MAX_XFER_RESTARTS 2 - -#define ENABLE_IXFR 1 - -# ifdef SHORT_FNAMES -extern long pathconf __P((const char *path, int name)); /* XXX */ -# endif - - -static struct zoneinfo zone; /* zone information */ - -static char *ddtfilename = NULL, - *ddtfile = NULL; - -static char *tmpname = NULL, - *tmpiname = NULL, /* temporary file name for ixfr transaction file */ - *domain; /* domain being xfered */ - -static int quiet = 0, - read_interrupted = 0, - curclass, - domain_len; /* strlen(domain) */ - -static FILE *fp = NULL, - *dbfp = NULL, - *ixfp = NULL; - -static char *ProgName; - -static void usage(const char *), - tsig_init(const char *); -static int getzone(struct zoneinfo *, u_int32_t, int), - print_output(struct zoneinfo *, u_int32_t, - u_char *, int, u_char *, int), - netread(int, char *, int, int), - writemsg(int, const u_char *, int); -static int ixfr_log(const u_char *msg, int len, int *delete, - FILE *file, struct sockaddr_in *sin, - char *domain, u_int32_t *serial_no, int *); -static SIG_FN read_alarm(void); -static SIG_FN term_handler(void); -static const char *soa_zinfo(struct zoneinfo *, u_char *, u_char*), - *tsig_rcode(int); - -struct zoneinfo zp_start, zp_finish; - -static int restarts = 0; -static int check_serial = 0; -static int xfr_qtype = T_AXFR; - -FILE *ddt = NULL; -int servermethode[NSMAX]; -char *soa_buf; - -typedef struct _tsig_node { - struct in_addr addr; - DST_KEY *dst_key; - LINK(struct _tsig_node) link; -} tsig_node; - -LIST(tsig_node) tsig_list; - -/* - * Debugging printf. - */ -void -dprintf(int level, const char *format, ...) { - va_list ap; - - va_start(ap, format); - if (ddt != NULL && debug >= level) - (void) vfprintf(ddt, format, ap); - va_end(ap); -} - -static int -init_xfer_logging() { - log_channel chan; - - if (log_new_context(ns_log_max_category, NULL, &log_ctx) < 0) { - perror("log_new_context"); - return (0); - } - log_option(log_ctx, LOG_OPTION_DEBUG, debug); - log_option(log_ctx, LOG_OPTION_LEVEL, debug); - - log_ctx_valid = 1; - - chan = log_new_syslog_channel(0, 0, LOG_DAEMON); - if (chan == NULL) - return (0); - if (log_add_channel(log_ctx, ns_log_default, chan) < 0) { - perror("log_add_channel syslog"); - return (0); - } - - if (debug) { - unsigned int flags = LOG_USE_CONTEXT_LEVEL|LOG_REQUIRE_DEBUG; - - chan = log_new_file_channel(flags, 0, NULL, ddt, 0, ULONG_MAX); - if (chan == NULL) - return (0); - if (log_add_channel(log_ctx, ns_log_default, chan) < 0) { - perror("log_add_channel debug"); - return (0); - } - } - - return (1); -} - -void cleanup_for_exit(void) { -#ifdef DEBUG - if (!debug) -#endif - { - (void) unlink(tmpname); - if (tmpiname != NULL) - (void) unlink(tmpiname); - } - if(tmpiname) - free(tmpiname); - tmpiname = NULL; - if (ddtfilename != NULL) { - free(ddtfilename); - if (ddtfilename == ddtfile) - ddtfile = NULL; - ddtfilename = NULL; - } - if(tmpname) - free(tmpname); - tmpname = NULL; - if(ddtfile) - free(ddtfile); - ddtfile = NULL; -} - - -int -main(int argc, char *argv[]) { - struct zoneinfo *zp; - struct hostent *hp; - struct in_addr axfr_src; - char *dbfile = NULL, *tracefile = NULL, *tm = NULL, *tsigfile = NULL; - char *ixfrfile = NULL; - u_int32_t new_serial_no = 0; - int dbfd, ddtd, result, c, fd, ixfd; - u_int32_t serial_no = 0; - u_int port = htons(NAMESERVER_PORT); - struct stat statbuf; - int stub_only = 0; - int class = C_IN; - int n; - long num_files; - -#ifdef _AUX_SOURCE - set42sig(); -#endif - memset(&axfr_src, 0, sizeof axfr_src); - ProgName = strrchr(argv[0], '/'); - if (ProgName != NULL) - ProgName++; - else - ProgName = argv[0]; - - (void) umask(022); - - ddtfilename = (char *)malloc(strlen(_PATH_TMPXFER) + 1); - strcpy(ddtfilename, _PATH_TMPXFER); - ddtfile = ddtfilename; - -#ifdef RENICE - nice(-40); /* this is the recommended procedure to */ - nice(20); /* reset the priority of the current process */ - nice(0); /* to "normal" (== 0) - see nice(3) */ -#endif - - n = LOG_PID; -#ifdef LOG_PERROR - n |= LOG_PERROR; -#endif -#if defined(LOG_CONS) && defined(USE_LOG_CONS) - n |= LOG_CONS; -#endif -#ifdef SYSLOG_42BSD - openlog(ProgName, n); -#else - openlog(ProgName, n, LOG_DAEMON); -#endif - while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:i:p:P:qx:ST:Z")) != -1) - switch (c) { - case 'C': - class = get_class(optarg); - break; - case 'd': -#ifdef DEBUG - debug = atoi(optarg); -#endif - break; - case 'l': - ddtfile = (char *)malloc(strlen(optarg) + - sizeof(".XXXXXX") + 1); - if (!ddtfile) - panic("malloc(ddtfile)", NULL); -#ifdef SHORT_FNAMES - filenamecpy(ddtfile, optarg); -#else - (void) strcpy(ddtfile, optarg); -#endif /* SHORT_FNAMES */ - (void) strcat(ddtfile, ".XXXXXX"); - break; - case 's': - serial_no = strtoul(optarg, (char **)NULL, 10); - check_serial++; - break; - case 't': - tracefile = optarg; - break; - case 'z': /* zone == domain */ - domain = optarg; - domain_len = strlen(domain); - while ((domain_len > 0) && - (domain[domain_len-1] == '.')) - domain[--domain_len] = '\0'; - break; - case 'f': - dbfile = optarg; - tmpname = (char *)malloc((unsigned)strlen(optarg) + - sizeof(".XXXXXX") + 1); - if (!tmpname) - panic("malloc(tmpname)", NULL); -#ifdef SHORT_FNAMES - filenamecpy(tmpname, optarg); -#else - (void) strcpy(tmpname, optarg); -#endif /* SHORT_FNAMES */ - break; - case 'i': -#if ENABLE_IXFR - ixfrfile = optarg; - tmpiname = (char *) malloc(strlen(optarg) + - sizeof(".XXXXXX") + 1); - if (!tmpiname) - panic("malloc(tmpiname)", NULL); -#ifdef SHORT_FNAMES - filenamecpy(tmpiname, optarg); -#else - (void) strcpy(tmpiname, optarg); -#endif /* SHORT_FNAMES */ -#endif /* ENABLE_IXFR */ - break; - case 'p': - port = htons((u_int16_t)atoi(optarg)); - break; - case 'P': - port = (u_int16_t)atoi(optarg); - break; - case 'S': - stub_only = 1; - break; - case 'q': - quiet++; - break; - case 'x': - if (!inet_aton(optarg, &axfr_src)) - panic("bad -x addr: %s", optarg); - break; - case 'T': - tsigfile = optarg; - break; - case 'Z': - xfr_qtype = ns_t_zxfr; - break; - case '?': - default: - usage("unrecognized argument"); - /* NOTREACHED */ - } - if (!domain || ((!dbfile) && (!ixfrfile)) || optind >= argc) { - if (!domain) - usage("no domain"); - if (!dbfile) - usage("no dbfile"); - if (optind >= argc) - usage("not enough arguments"); - /* NOTREACHED */ - } - if (stat(dbfile, &statbuf) != -1 && - !S_ISREG(statbuf.st_mode) && - !S_ISFIFO(statbuf.st_mode)) - usage("dbfile must be a regular file or FIFO"); - if (ixfrfile && (stat(ixfrfile, &statbuf) != -1 && - !S_ISREG(statbuf.st_mode) && - !S_ISFIFO(statbuf.st_mode))) - usage("ixfrfile must be a regular file or FIFO"); - if (tsigfile && stat(tsigfile, &statbuf) != -1 && - !S_ISREG(statbuf.st_mode) && - !S_ISFIFO(statbuf.st_mode)) - usage("tsigfile must be a regular file or FIFO"); - if (tracefile && (fp = fopen(tracefile, "w")) == NULL) - perror(tracefile); - (void) strcat(tmpname, ".XXXXXX"); - /* tmpname is now something like "/etc/named/named.bu.db.XXXXXX" */ - if ((dbfd = mkstemp(tmpname)) == -1) { - perror(tmpname); - if (!quiet) - syslog(LOG_ERR, "can't make tmpfile (%s): %s\n", - tmpname, strerror(errno)); - exit(XFER_FAIL); - } -#ifdef HAVE_FCHMOD /* XXX */ - if (fchmod(dbfd, 0644) == -1) -#else - if (chmod(tmpname, 0644) == -1) -#endif - { - perror(tmpname); - if (!quiet) - syslog(LOG_ERR, "can't [f]chmod tmpfile (%s): %s\n", - tmpname, strerror(errno)); - exit(XFER_FAIL); - } - if ((dbfp = fdopen(dbfd, "r+")) == NULL) { - perror(tmpname); - if (!quiet) - syslog(LOG_ERR, "can't fdopen tmpfile (%s)", tmpname); - exit(XFER_FAIL); - } - if (ixfrfile) { - (void) strcat(tmpiname, ".XXXXXX"); - if ((ixfd = mkstemp(tmpiname)) == -1) { - perror(tmpiname); - if (!quiet) - syslog(LOG_ERR, - "can't make tmpifile (%s): %s\n", - tmpiname, strerror(errno)); - (void) fclose(dbfp); - (void) close(dbfd); - exit(XFER_FAIL); - } -#ifdef HAVE_FCHMOD /* XXX */ - if (fchmod(ixfd, 0644) == -1) -#else - if (chmod(tmpiname, 0644) == -1) -#endif - { - perror(tmpiname); - if (!quiet) - syslog(LOG_ERR, - "can't [f]chmod tmpifile (%s): %s\n", - tmpiname, strerror(errno)); - (void) fclose(dbfp); - (void) close(dbfd); - (void) close(ixfd); - exit(XFER_FAIL); - } - close(ixfd); - } -#ifdef DEBUG - if (debug) { - /* ddtfile is now something like "/usr/tmp/xfer.ddt.XXXXXX" */ - if ((ddtd = mkstemp(ddtfile)) == -1) { - perror(ddtfile); - debug = 0; - } -#ifdef HAVE_FCHMOD - else if (fchmod(ddtd, 0644) == -1) -#else - else if (chmod(ddtfile, 0644) == -1) -#endif - { - perror(ddtfile); - debug = 0; - } else if ((ddt = fdopen(ddtd, "w")) == NULL) { - perror(ddtfile); - debug = 0; - } else - setvbuf(ddt, NULL, _IOLBF, 0); - } -#endif - if (!init_xfer_logging()) { - cleanup_for_exit(); - perror("init_xfer_logging"); - } - - /* - * Ignore many types of signals that named (assumed to be our parent) - * considers important- if not, the user controlling named with - * signals usually kills us. - */ - (void) signal(SIGHUP, SIG_IGN); -#ifdef SIGSYS - (void) signal(SIGSYS, SIG_IGN); -#endif -#ifdef DEBUG - if (debug == 0) -#endif - { - (void) signal(SIGINT, SIG_IGN); - (void) signal(SIGQUIT, SIG_IGN); - } - (void) signal(SIGILL, SIG_IGN); - -#if defined(SIGUSR1) && defined(SIGUSR2) - (void) signal(SIGUSR1, SIG_IGN); - (void) signal(SIGUSR2, SIG_IGN); -#else /* SIGUSR1&&SIGUSR2 */ - (void) signal(SIGEMT, SIG_IGN); - (void) signal(SIGFPE, SIG_IGN); -#endif /* SIGUSR1&&SIGUSR2 */ - - if (dbfile) - dprintf(1, "domain `%s'; file `%s'; serial %u\n", - domain, dbfile, serial_no); - - if (ixfrfile) - dprintf(1, "domain `%s'; ixfrfile `%s'; serial %u\n", - domain, ixfrfile, serial_no); - - buildservicelist(); - buildprotolist(); - - tsig_init(tsigfile); - - /* init zone data */ - - zp = &zone; - if (stub_only) - zp->z_type = Z_STUB; - else - zp->z_type = Z_SECONDARY; - zp->z_class = class; - zp->z_origin = domain; - zp->z_source = dbfile; - zp->z_axfr_src = axfr_src; - zp->z_addrcnt = 0; - dprintf(1, "zone found (%d): \"%s\", source = %s\n", - zp->z_type, - (zp->z_origin[0] == '\0') ? "." : zp->z_origin, - zp->z_source); - - for (; optind != argc; optind++) { - int tmpsupportixfr; - - tm = argv[optind]; - tmpsupportixfr = ISNOTIXFR; - if ((optind+1) != argc) { - if (strcasecmp("ixfr", argv[optind+1]) == 0) { -#if ENABLE_IXFR - tmpsupportixfr = ISIXFR; - servermethode[zp->z_addrcnt] = tmpsupportixfr; -#endif - optind++; - } else if (strcasecmp("axfr", argv[optind+1]) == 0) { - tmpsupportixfr = ISNOTIXFR; - optind++; - } - } - if (!inet_aton(tm, &zp->z_addr[zp->z_addrcnt])) { - if (strcmp("-ixfr",tm)==0) { -#if ENABLE_IXFR - tmpsupportixfr = ISIXFR; - servermethode[zp->z_addrcnt-1] = tmpsupportixfr; -#endif - continue; - } else - if (strcmp("-axfr",tm)==0) { - tmpsupportixfr = ISNOTIXFR; - continue; - } - hp = gethostbyname(tm); - if (hp == NULL) { - syslog(LOG_NOTICE, - "uninterpretable server (%s) for %s\n", - tm, zp->z_origin); - continue; - } - memcpy(&zp->z_addr[zp->z_addrcnt], - hp->h_addr, - INADDRSZ); - dprintf(1, "Arg: \"%s\" %s\n", tm,((tmpsupportixfr) ? "IXFR":"AXFR")); - } - if (++zp->z_addrcnt >= NSMAX) { - zp->z_addrcnt = NSMAX; - dprintf(1, "NSMAX reached\n"); - break; - } - } - dprintf(1, "addrcnt = %d\n", zp->z_addrcnt); - - res_ninit(&res); - res.options &= ~(RES_DEFNAMES | RES_DNSRCH | RES_RECURSE); - result = getzone(zp, serial_no, port); - (void) fclose(dbfp); - (void) close(dbfd); - - if (ixfp) - (void) my_fclose(ixfp); - else - close(ixfd); - - switch (result) { - - case XFER_SUCCESSAXFR: /* ok exit */ - if (tmpiname != NULL) - unlink(tmpiname); - if (ixfrfile) { - /* - * An IXFR was requested but we performed an - * AXFR. Rename the temporary file to the IXFR - * name, named will rename it again to the dbname. - */ - if (movefile(tmpname, ixfrfile) == -1) { - perror("movefile"); -#ifdef DEBUG - if (debug) - (void) unlink(ddtfile); -#endif - if (!quiet) - syslog(LOG_ERR, - "rename %s to %s: %s", - tmpname, ixfrfile, strerror(errno)); - cleanup_for_exit(); - exit(XFER_FAIL); - }; - exit(XFER_SUCCESSAXFRIXFRFILE); - } - if (movefile(tmpname, dbfile) == -1) { - perror("movefile"); - if (!quiet) - syslog(LOG_ERR, "movefile %s to %s: %m", - tmpname, dbfile); - cleanup_for_exit(); - exit(XFER_FAIL); - } - exit(XFER_SUCCESSAXFR); - - case XFER_SUCCESSIXFR: - unlink(tmpname); - if (movefile(tmpiname, ixfrfile) == -1) { - perror("movefile"); - if (!quiet) - syslog(LOG_ERR, "movefile %s to %s: %m", - tmpiname, ixfrfile); - cleanup_for_exit(); - exit(XFER_FAIL); - } - cleanup_for_exit(); - exit(XFER_SUCCESSIXFR); - - case XFER_UPTODATE: /* the zone was already uptodate */ - (void) unlink(tmpname); - if (tmpiname != NULL) - (void) unlink(tmpiname); - cleanup_for_exit(); - exit(XFER_UPTODATE); - - default: - result = XFER_FAIL; - /* fall through */ - case XFER_TIMEOUT: - case XFER_FAIL: - (void) unlink(tmpname); - cleanup_for_exit(); - exit(result); /* error or timeout */ - } - /*NOTREACHED*/ - return (0); /* Make gcc happy. */ -} - -static char *UsageText[] = { - "\t-z zone_to_transfer\n", - "\t-f db_file\n", - "\t[-i ixfr_file]\n", - "\t[-s serial_no]\n", - "\t[-d debug_level]\n", - "\t[-l debug_log_file]\n", - "\t[-t trace_file]\n", - "\t[-p port]\n", - "\t[-S] [-Z]\n", - "\t[-C class]\n", - "\t[-x axfr-src]\n", - "\t[-T tsig_info_file]\n", - "\tservers [-ixfr|-axfr]...\n", - NULL -}; - -static void -usage(const char *msg) { - char * const *line; - - fprintf(stderr, "Usage error: %s\n", msg); - fprintf(stderr, "Usage: %s\n", ProgName); - for (line = UsageText; *line; line++) - fputs(*line, stderr); - exit(XFER_FAIL); -} - -static void -tsig_init(const char *file) { - char buf[1024]; - int n; - FILE *fp; - char *s; - - if (file == NULL) - return; - fp = fopen(file, "r"); - if (fp == NULL) - return; - dst_init(); - INIT_LIST(tsig_list); - while (1) { - tsig_node *n = malloc(sizeof(tsig_node)); - int alg, secret_len; - char *address, *name; - char *cp; - u_char secret[128]; - - s = fgets(buf, sizeof(buf), fp); - if (s == NULL) - break; - buf[strlen(buf)-1] = 0; - inet_aton(buf, &n->addr); - - fgets(buf, sizeof(buf), fp); - buf[strlen(buf)-1] = 0; - name = strdup(buf); - - fscanf(fp, "%d", &alg); - fgets(buf, sizeof(buf), fp); - - fgets(buf, sizeof(buf), fp); - buf[strlen(buf)-1] = 0; - cp = buf; - while (isspace(*cp)) - cp++; - - secret_len = b64_pton(cp, secret, sizeof(secret)); - n->dst_key = dst_buffer_to_key(name, alg, 0, 0, - secret, secret_len); - - free(name); - APPEND(tsig_list, n, link); - } - fclose(fp); - unlink(file); -} - -#define DEF_DNAME '\001' /* '\0' means the root domain */ -/* XXX: The following variables should probably all be "static" */ -u_int32_t minimum_ttl = 0; -int soa_cnt = 0, scdsoa = 0, methode = ISNOTIXFR; -int delete_soa = 1; -u_int32_t final_serial = 0; -int ixfr_soa = 0; -int ns_cnt = 0; -int query_type = 0; -int prev_comment = 0; /* was previous record a comment? */ -char zone_top[MAXDNAME]; /* the top of the zone */ -char prev_origin[MAXDNAME]; /* from most recent $ORIGIN line */ -char prev_dname[MAXDNAME] = { DEF_DNAME }; /* from previous record */ -char prev_ns_dname[MAXDNAME] = { DEF_DNAME }; /* from most recent NS record */ - -static int -getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) { - HEADER *hp; - u_int len; - u_int32_t serial; - int s, n, l, error = 0; - int was_ixfr = 0; - u_int cnt; - u_char *cp, *nmp, *eom, *tmp ; - u_char *buf = NULL, *cpp = NULL; - u_char *bp; - u_int bufsize = 0; - char name[MAXDNAME], name2[MAXDNAME]; - struct sockaddr_in sin; - struct sockaddr_in local; - int locallen; -#ifdef POSIX_SIGNALS - struct sigaction sv, osv; -#else - struct sigvec sv, osv; -#endif - int qdcount, ancount, aucount, arcount, class, type; - int first_serial; - const char *badsoa_msg = "Nil"; - struct sockaddr_in my_addr; - char my_addr_text[30]; - int alen, ret, tsig_req; - DST_KEY *tsig_key; - ns_tcp_tsig_state tsig_state; - int tsig_signed = 0; - u_char sig[64]; - int siglen; - int ixfr_first = 1; - int loop_cnt = 0; - time_t timesigned; - u_int32_t query_serial = serial_no; - -#ifdef DEBUG - if (debug) { - (void)fprintf(ddt,"getzone() %s ", zp->z_origin); - switch (zp->z_type) { - case Z_STUB: - fprintf(ddt,"stub\n"); - break; - case Z_SECONDARY: - fprintf(ddt,"secondary\n"); - break; - default: - fprintf(ddt,"unknown type\n"); - } - } -#endif -#ifdef POSIX_SIGNALS - memset(&sv, 0, sizeof sv); - sv.sa_handler = (SIG_FN (*)()) read_alarm; - /* SA_ONSTACK isn't recommended for strict POSIX code */ - /* is it absolutely necessary? */ - /* sv.sa_flags = SA_ONSTACK; */ - sigfillset(&sv.sa_mask); - (void) sigaction(SIGALRM, &sv, &osv); - memset(&sv, 0, sizeof sv); - sv.sa_handler = (SIG_FN (*)()) term_handler; - sigfillset(&sv.sa_mask); - (void) sigaction(SIGTERM, &sv, &osv); -#else - memset(&sv, 0, sizeof sv); - sv.sv_handler = read_alarm; - sv.sv_mask = ~0; - (void) sigvec(SIGALRM, &sv, &osv); - memset(&sv, 0, sizeof sv); - sv.sv_handler = term_handler; - sv.sv_mask = ~0; - (void) sigvec(SIGTERM, &sv, &osv); -#endif - - strcpy(zone_top, zp->z_origin); - if ((l = strlen(zone_top)) != 0 && zone_top[l - 1] == '.') - zone_top[l - 1] = '\0'; - strcpy(prev_origin, zone_top); - for (cnt = 0; cnt < zp->z_addrcnt; cnt++) { - methode = servermethode[cnt]; - sin.sin_addr = zp->z_addr[cnt]; - dprintf(3, "address [%s] %s\n", - inet_ntoa(sin.sin_addr), - (methode == ISIXFR) ? "IXFR":"AXFR"); - - } - for (cnt = 0; cnt < zp->z_addrcnt; cnt++) { - methode = ISNOTIXFR; - curclass = zp->z_class; - /* - * If we have been given a serial number and a ixfr log - * file name then set methode. - */ - if (check_serial && tmpiname != NULL) - methode = servermethode[cnt]; - error = 0; - if (buf == NULL) { - if ((buf = (u_char *)malloc(2 * PACKETSZ)) == NULL) { - syslog(LOG_INFO, "malloc(%u) failed", - 2 * PACKETSZ); - error++; - break; - } - bufsize = 2 * PACKETSZ; - } - try_again: - if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) { - syslog(LOG_INFO, "socket: %m"); - error++; - break; - } - if (zp->z_axfr_src.s_addr != 0) { - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_port = 0; /* "ANY" */ - sin.sin_addr = zp->z_axfr_src; - dprintf(2, "binding to address [%s]\n", - inet_ntoa(sin.sin_addr)); - if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) - syslog(LOG_INFO, "warning: bind(%s) failed", - inet_ntoa(zp->z_axfr_src)); - } - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_port = port; - sin.sin_addr = zp->z_addr[cnt]; - dprintf(2, "connecting to server #%d [%s].%d\n", - cnt+1, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - if (zp->z_axfr_src.s_addr != 0) { - dprintf(2, "connect failed, trying w/o -x"); - zp->z_axfr_src.s_addr = 0; - (void) my_close(s); - goto try_again; - } - if (!quiet) - syslog(LOG_INFO, - "connect(%s) for zone %s failed: %s", - inet_ntoa(sin.sin_addr), zp->z_origin, strerror(errno)); - error++; - (void) my_close(s); - continue; - } - if (methode == ISIXFR && was_ixfr == 0) { - hp = (HEADER *) buf; - cpp = buf; - n = res_nmkquery(&res, QUERY, zp->z_origin, curclass, - T_IXFR, NULL, 0, NULL, buf, bufsize); - dprintf(1, "len = %d\n", n); - if (n < 0) { - if (!quiet) - syslog(LOG_INFO, - "zone %s: dn_comp for ixfr failed", - zp->z_origin); - (void) my_close(s); -#ifdef POSIX_SIGNALS - sigaction(SIGALRM, - &osv, - (struct sigaction*)0); -#else - sigvec(SIGALRM, - &osv, - (struct sigvec *)0); -#endif - return (XFER_FAIL); - } - hp->nscount = htons(1+ntohs(hp->nscount)); - cpp += n; - n = dn_comp(zp->z_origin, cpp, bufsize-(cpp-buf), - NULL, NULL); - if (n > 0) - cpp += n; - PUTSHORT(T_SOA, cpp); /* type */ - PUTSHORT(C_IN, cpp); /* class */ - PUTLONG(0, cpp); /* ttl */ - PUTSHORT(22, cpp); /* dlen */ - *cpp++ = 0; /* mname */ - *cpp++ = 0; /* rname */ - PUTLONG(serial_no, cpp); - PUTLONG(0xDEAD, cpp); /* Refresh */ - PUTLONG(0xBEEF, cpp); /* Retry */ - PUTLONG(0xABCD, cpp); /* Expire */ - PUTLONG(0x1776, cpp); /* Min TTL */ - n = cpp-buf; - dprintf(1, "len = %d\n", cpp-buf); - if (debug) - res_pquery(&res, buf, n, ddt); - } - else { - n = res_nmkquery(&res, QUERY, zp->z_origin, curclass, - T_SOA, NULL, 0, NULL, buf, bufsize); - if (n < 0) { - if (!quiet) - syslog(LOG_INFO, - "zone %s: res_nmkquery T_SOA failed", - zp->z_origin); - (void) my_close(s); -#ifdef POSIX_SIGNALS - (void) sigaction(SIGALRM, &osv, (struct sigaction *)0); -#else - (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); -#endif - return (XFER_FAIL); - } - } - /* - * Append TSIG to SOA query if desired - */ - tsig_key = tsig_key_from_addr(sin.sin_addr); - if (tsig_key != NULL) { - siglen = sizeof(sig); - ret = ns_sign(buf, &n, bufsize, NOERROR, tsig_key, - NULL, 0, sig, &siglen, timesigned); - if (ret == 0) - tsig_signed = 1; - } - - /* - * Send length & message for SOA query - */ - if (writemsg(s, buf, n) < 0) { - syslog(LOG_INFO, "writemsg: %m"); - error++; - (void) my_close(s); - continue; - } - /* - * Get out your butterfly net and catch the SOA - */ - - if (netread(s, (char *)buf, INT16SZ, - (soa_cnt == 0) ?400 :XFER_TIMER) < 0) { - (void) my_close(s); - error++; - continue; - } - if ((len = ns_get16(buf)) == 0) { - (void) my_close(s); - continue; - } - if (len > bufsize) { - if ((buf = (u_char *)realloc(buf, len)) == NULL) { - syslog(LOG_INFO, - "malloc(%u) failed for SOA from server [%s], zone %s\n", - len, - inet_ntoa(sin.sin_addr), - zp->z_origin); - (void) my_close(s); - continue; - } - bufsize = len; - } - if (netread(s, (char *)buf, len, XFER_TIMER) < 0) { - error++; - (void) my_close(s); - continue; - } - /* - * Verify the TSIG if expected - */ - if (tsig_signed != 0) { - ret = ns_verify(buf, (int *)&len, tsig_key, sig, siglen, - NULL, NULL, ×igned, 0); - if (ret != 0) { - syslog(LOG_NOTICE, - "SOA TSIG verification from server [%s], zone %s: %s (%d)\n", - inet_ntoa(sin.sin_addr), zp->z_origin, - tsig_rcode(ret), ret); - error++; - continue; - } - } - -#ifdef DEBUG - if (debug >= 3) { - (void)fprintf(ddt,"len = %d\n", len); - res_pquery(&res, buf, len, ddt); - } -#endif - if (((methode == ISIXFR) && (ixfp == NULL)) && was_ixfr == 0) { - delete_soa = 1; - ixfr_soa = 0; - if ((ixfp = fopen(tmpiname, "w+")) == NULL) { - perror(tmpiname); - if (!quiet) - syslog(LOG_ERR, - "can't fdopen ixfr log (%s)", - tmpname); - exit(XFER_FAIL); - } - } - - hp = (HEADER *) buf; - qdcount = ntohs(hp->qdcount); - ancount = ntohs(hp->ancount); - aucount = ntohs(hp->nscount); - arcount = ntohs(hp->arcount); - /* - * close socket if any of these apply: - * 1) rcode != NOERROR - * 2) not an authority response - * 3) not an answer to our question - * 4) both the number of answers and authority count < 1) - */ - if (hp->rcode != NOERROR || !hp->aa || qdcount != 1 || - (ancount < 1 && aucount < 1)) { -#ifndef SYSLOG_42BSD - syslog(LOG_NOTICE, - "[%s] %s for %s, SOA query got rcode %d, aa %d, ancount %d, aucount %d", - inet_ntoa(sin.sin_addr), - (hp->aa - ? (qdcount==1 ?"no SOA found" :"bad response") - : "not authoritative"), - zp->z_origin[0] != '\0' ? zp->z_origin : ".", - hp->rcode, hp->aa, ancount, aucount); -#endif - error++; - (void) my_close(s); - continue; - } - zp_start = *zp; - if ((int)len < HFIXEDSZ + QFIXEDSZ) { - badsoa_msg = "too short"; - badsoa: - syslog(LOG_INFO, - "malformed SOA from [%s], zone %s: %s", - inet_ntoa(sin.sin_addr), zp->z_origin, - badsoa_msg); - error++; - (void) my_close(s); - continue; - } - /* - * Step through response. - */ - tmp = buf + HFIXEDSZ; - eom = buf + len; - /* Query Section. */ - if (qdcount > 1) { - badsoa_msg = "question error"; - goto badsoa; - } - if (qdcount < 1) - goto no_question; - n = dn_expand(buf, eom, tmp, name2, sizeof name2); - if (n < 0) { - badsoa_msg = "qname error"; - goto badsoa; - } - tmp += n; - if (tmp + 2 * INT16SZ > eom) { - badsoa_msg = "query error"; - goto badsoa; - } - NS_GET16(type, tmp); - NS_GET16(class, tmp); - if (class != curclass || - ((type != T_SOA) && (type != T_IXFR) && (type != T_AXFR)) || - ns_samename(zp->z_origin, name2) != 1) - { - syslog(LOG_INFO, - "wrong query in resp from [%s], zone %s: [%s %s %s]\n", - inet_ntoa(sin.sin_addr), zp->z_origin, - name2, p_class(class), p_type(type)); - error++; - (void) my_close(s); - continue; - } - no_question: - /* ... Answer Section. - * We may have to loop a little, to bypass SIG SOA's in - * the response. - */ - loop_cnt = 0; - bp = NULL; - do { - u_char *cp4; - u_short type, class, dlen; - u_int32_t ttl; - n = dn_expand(buf, eom, tmp, name2, sizeof name2); - if (n < 0) { - badsoa_msg = "aname error"; - goto badsoa; - } - tmp += n; - - if (loop_cnt == 0) - bp = tmp; - - /* Are type, class, and ttl OK? */ - cp4 = tmp; /* Leave tmp pointing to type field */ - if (eom - cp4 < 3 * INT16SZ + INT32SZ) { - badsoa_msg = "zinfo too short"; - goto badsoa; - } - NS_GET16(type, cp4); - NS_GET16(class, cp4); - NS_GET32(ttl, cp4); - NS_GET16(dlen, cp4); - if (cp4 + dlen > eom) { - badsoa_msg = "zinfo dlen too big"; - goto badsoa; - } - if (type == T_SOA) { - if (was_ixfr) { - methode = ISNOTIXFR; - break; - } - if ((methode == ISIXFR) && (loop_cnt == 0)) { - soa_cnt++; - badsoa_msg = soa_zinfo(&zp_finish, tmp, eom); - if (badsoa_msg) - goto badsoa; - if (ixfp) - if (ixfr_log(buf, len, &delete_soa, ixfp, - &sin, domain, &serial_no, - &ixfr_first) < 0) { - error++; - break; - } - } else { - if (methode == ISIXFR) { - check_serial = 0; - soa_cnt++; - break; - } - break; - } - } - if ((loop_cnt >= 1) && (soa_cnt < 2)) { - dprintf(1, - "server %s %d rejected IXFR and responded with AXFR\n", - inet_ntoa(sin.sin_addr), soa_cnt); - methode = ISNOTIXFR; - check_serial = 0; - was_ixfr++; - tmp = bp; - break; - } - /* Skip to next record, if any. */ - dprintf(1, "skipping %s %s RR in response\n", - name2, p_type(type)); - tmp = cp4 + dlen; - loop_cnt++; - if (loop_cnt >= ancount) { - tmp = bp; - check_serial = 0; - break; - } - } while (1); - - if (ns_samename(zp->z_origin, name2) != 1) { - syslog(LOG_INFO, - "wrong answer in resp from [%s], zone %s: [%s %s %s]\n", - inet_ntoa(sin.sin_addr), zp->z_origin, - name2, p_class(class), p_type(type)); - error++; - (void) my_close(s); - continue; - } - badsoa_msg = soa_zinfo(&zp_start, tmp, eom); - if (badsoa_msg) - goto badsoa; - if (methode == ISNOTIXFR) { - if (SEQ_GT(zp_start.z_serial, serial_no) || !check_serial) { - const char *l, *nl, *t; - - if (soa_cnt) { - goto axfr_response; - } - dprintf(1, "need update, serial %u\n", - zp_start.z_serial); - soa_cnt = 0; - hp = (HEADER *) buf; - ns_cnt = 0; - gettime(&tt); - locallen = sizeof local; - if (getsockname(s, (struct sockaddr *)&local, - &locallen) < 0) { - memset(&local, 0, sizeof local); - } - for (l = Version; l; l = nl) { - size_t len; - if ((nl = strchr(l, '\n')) != NULL) { - len = nl - l; - nl = nl + 1; - } else { - len = strlen(l); - nl = NULL; - } - while (isspace((unsigned char) *l)) - l++; - if (*l) - fprintf(dbfp, "; BIND version %.*s\n", - (int)len, l); - } - fprintf(dbfp, check_serial? - "; zone '%s' last serial %u\n": - "; zone '%s' first transfer\n", - domain, serial_no); - t = strdup(inet_ntoa(sin.sin_addr)); - fprintf(dbfp, "; from %s:%d (local %s) using %s at %s", - t, ntohs(sin.sin_port), - inet_ntoa(local.sin_addr), - (methode == ISIXFR) ? "IXFR":"AXFR", - ctimel(tt.tv_sec)); - free((void *)t); - for (;;) { - if ((soa_cnt == 0) || (zp->z_type == Z_STUB)) { - if (zp->z_type == Z_STUB) { - if (soa_cnt == 1 && - ns_cnt == 0) - query_type = T_NS; - else - query_type = T_SOA; - } else if (methode == ISIXFR) - query_type = T_IXFR; - else - query_type = xfr_qtype; - n = res_nmkquery(&res, QUERY, - zp->z_origin, - curclass, query_type, - NULL, 0, - NULL, buf, bufsize); - syslog(LOG_INFO, - "send %s query %d to %s", - (query_type == T_IXFR) ? "IXFR" : - (query_type == T_AXFR) ? "AXFR" : - (query_type == ns_t_zxfr) ? "ZXFR" : - (query_type == T_SOA) ? "SOA" : "NS", - cnt, inet_ntoa(sin.sin_addr)); - dprintf(1, - "send %s query to %s\n", - (query_type == T_IXFR) ? "IXFR" : - (query_type == T_AXFR) ? "AXFR" : - (query_type == ns_t_zxfr) ? "ZXFR" : - (query_type == T_SOA) ? "SOA" : "NS", - inet_ntoa(sin.sin_addr)); - dprintf(1,"bufsize = %d\n", bufsize); - if (n < 0) { - if (!quiet) { - if (zp->z_type == Z_STUB) - syslog(LOG_INFO, - (query_type == T_SOA) - ? "zone %s: res_nmkquery T_SOA failed" - : "zone %s: res_nmkquery T_NS failed", - zp->z_origin); - else - syslog(LOG_INFO, - "zone %s: res_nmkquery %s failed", - zp->z_origin, - p_type(query_type)); - } - (void) my_close(s); -#ifdef POSIX_SIGNALS - sigaction(SIGALRM, &osv, - (struct sigaction *)0); -#else - sigvec(SIGALRM, &osv, - (struct sigvec *)0); -#endif - return (XFER_FAIL); - } - cpp = buf + n; - /* - * Append TSIG to AXFR query if desired - */ - if (tsig_signed != 0) { - siglen = sizeof(sig); - ns_sign(buf, &n, bufsize, - NOERROR, tsig_key, - NULL, 0, sig, &siglen, - timesigned); - cpp = buf + n; - ns_verify_tcp_init(tsig_key, - sig, siglen, - &tsig_state); - } - /* - * Send length & msg for zone transfer - */ - if (writemsg(s, buf, cpp - buf) < 0) { - syslog(LOG_INFO, - "writemsg: %m"); - error++; - (void) my_close(s); - break; - } - } -/*XXX ZXFR*/ -receive: - /* - * Receive length & response - */ - if (netread(s, (char *)buf, INT16SZ, - (soa_cnt == 0) ?300 :XFER_TIMER) - < 0) { - error++; - break; - } - if ((len = ns_get16(buf)) == 0) - break; - if (len > bufsize) { - buf = (u_char *)realloc(buf, len); - if (buf == NULL) { - syslog(LOG_INFO, - "malloc(%u) failed for packet from server [%s], zone %s\n", - len, - inet_ntoa(sin.sin_addr), - zp->z_origin); - error++; - break; - } - bufsize = len; - } - hp = (HEADER *)buf; - eom = buf + len; - if (netread(s, (char *)buf, len, XFER_TIMER) - < 0) { - error++; - break; - } -#ifdef DEBUG - if (debug >= 3) { - (void)fprintf(ddt,"len = %d\n", len); - res_pquery(&res, buf, len, ddt); - } - if (fp) - res_pquery(&res, buf, len, fp); -#endif - /* - * Verify the TSIG if expected - */ - if (tsig_signed != 0) { - tsig_req = (soa_cnt == 0); - ret = ns_verify_tcp(buf, (int *)&len, - &tsig_state, - tsig_req); - eom = buf + len; - - if (ret != 0) { - syslog(LOG_NOTICE, - "TSIG verification from server [%s], zone %s: %s (%d)\n", - inet_ntoa(sin.sin_addr), - zp->z_origin, - tsig_rcode(ret), ret); - error++; - break; - } - } - if (len < HFIXEDSZ) { - badrec: - error++; - alen = sizeof my_addr; - if (getsockname(s, (struct sockaddr *) - &my_addr, &alen) < 0) - sprintf(my_addr_text, - "[errno %d]", errno); - else - sprintf(my_addr_text, - "[%s].%u", - inet_ntoa(my_addr. - sin_addr), - ntohs(my_addr.sin_port) - ); - if ((hp->rcode == REFUSED) && - (len >= HFIXEDSZ)) { - syslog(LOG_INFO, - "[%s] transfer refused from [%s], zone %s\n", - my_addr_text, - inet_ntoa(sin.sin_addr), - zp->z_origin); - } else { - syslog(LOG_INFO, - "[%s] record too short from [%s], zone %s\n", - my_addr_text, - inet_ntoa(sin.sin_addr), - zp->z_origin); - } - break; - } -axfr_response: - if (query_type == T_IXFR) - if (hp->rcode != NOERROR) { - dprintf(1, - "server %s did not support IXFR\n", - inet_ntoa(sin.sin_addr)); - methode = ISNOTIXFR; - continue; - }; - cp = buf + HFIXEDSZ; - if (ntohs(hp->qdcount) == 1) { - if ((query_type == T_IXFR) && (methode == ISIXFR)) { - dprintf(1, - "server %s rejected IXFR and responded with AXFR\n", - inet_ntoa(sin.sin_addr)); - methode = ISNOTIXFR; - } - n = dn_skipname(cp, eom); - if ((n == -1) || - ((n + QFIXEDSZ) >= (eom - cp))) - goto badrec; - cp += n + QFIXEDSZ; - } - nmp = cp; - if ((n = dn_skipname(cp, eom)) == -1) - goto badrec; - tmp = cp + n; - if (zp->z_type == Z_STUB) { - ancount = ntohs(hp->ancount); - n = 0; - for (cnt = 0; - cnt < (u_int)ancount; - cnt++) { - n = print_output(zp, - serial_no, - buf, len, cp, - was_ixfr); - if (n < 0) - break; - cp += n; - } - /* - * If we've processed the answer - * section and didn't get any useful - * answers, bail out. - */ - if (query_type == T_SOA && - soa_cnt == 0) { - syslog(LOG_ERR, - "stubs: no SOA in answer"); - error++; - break; - } - if (query_type == T_NS && - ns_cnt == 0) { - syslog(LOG_ERR, - "stubs: no NS in answer"); - error++; - break; - } - if (n >= 0 && hp->nscount) { - ancount = ntohs(hp->nscount); - for (cnt = 0; - cnt < (u_int)ancount; - cnt++) { - n = print_output(zp, - serial_no, - buf, - len, - cp, - was_ixfr); - if (n < 0) - break; - cp += n; - } - } - ancount = ntohs(hp->arcount); - for (cnt = 0; - n > 0 && cnt < (u_int)ancount; - cnt++) { - n = print_output(zp, serial_no, - buf, len, cp, - was_ixfr); - cp += n; - } - if (n < 0) { - syslog(LOG_INFO, - "print_output: unparseable answer (%d), zone %s", - hp->rcode, - zp->z_origin); - error++; - break; - } - if (cp != eom) { - syslog(LOG_INFO, - "print_output: short answer (%d, %d), zone %s", - cp - buf, eom - buf, - zp->z_origin); - error++; - break; - } - } else { - ancount = ntohs(hp->ancount); - if (query_type == T_IXFR && - methode == ISIXFR) { - if (ixfr_log(buf, len, - &delete_soa, ixfp, - &sin, domain, - &serial_no, - &ixfr_first) < 0){ - error++; - break; - } - } - for (n = cnt = 0; - cnt < (u_int)ancount; - cnt++) { - n = print_output(zp, serial_no, - buf, len, cp, - was_ixfr); - if (n < 0) - break; - cp += n; - } - if (n < 0) { - syslog(LOG_INFO, - "print_output: unparseable answer (%d), zone %s", - hp->rcode, - zp->z_origin); - error++; - break; - } - if (cp != eom) { - syslog(LOG_INFO, - "print_output: short answer (%d, %d), zone %s", - cp - buf, eom - buf, - zp->z_origin); - error++; - break; - } - } - if ((soa_cnt >= 2) && (methode == ISNOTIXFR)) - break; - if ((soa_cnt == -1) && (methode == ISIXFR)) - break; - } - (void) my_close(s); - if (error == 0) { -#ifdef POSIX_SIGNALS - (void) sigaction(SIGALRM, &osv, - (struct sigaction *)0); -#else - (void) sigvec(SIGALRM, &osv, - (struct sigvec *)0); -#endif - if (ixfp) { - (void) fclose(ixfp); - ixfp = NULL; - } - return (XFER_SUCCESSAXFR); - } - if (ixfp) { - (void) fclose(ixfp); - ixfp = NULL; - } - dprintf(2, "error receiving zone transfer\n"); - } else if (zp_start.z_serial == serial_no) { - (void) my_close(s); - dprintf(1, "zone up-to-date, serial %u\n", - zp_start.z_serial); - if (ixfp) { - (void) unlink (tmpiname); - (void) fclose(ixfp); - ixfp = NULL; - } - return (XFER_UPTODATE); - } else { - (void) my_close(s); - if (!quiet) - syslog(LOG_NOTICE, - "serial from [%s], zone %s: %u lower than current: %u\n", - inet_ntoa(sin.sin_addr), zp->z_origin, - zp_start.z_serial, serial_no); - return (XFER_FAIL); - } - } else { - if (zp_finish.z_serial == query_serial) { - (void) my_close(s); - dprintf(1, "zone up-to-date, serial %u\n", - zp_start.z_serial); - if (ixfp) { - (void) unlink (tmpiname); - (void) fclose(ixfp); - ixfp = NULL; - } - return (XFER_UPTODATE); - } - if (SEQ_GT(query_serial, zp_finish.z_serial)) { - if (!quiet) - syslog(LOG_NOTICE, - "serial from [%s], zone %s: %u lower than current: %u\n", - inet_ntoa(sin.sin_addr), zp->z_origin, - zp_finish.z_serial, query_serial); - dprintf(1, - "serial from [%s], zone %s: %u lower than current: %u\n", - inet_ntoa(sin.sin_addr), zp->z_origin, - zp_finish.z_serial, query_serial); - if (ixfp) { - (void) fclose(ixfp); - ixfp = NULL; - (void) unlink (tmpiname); - } - if (was_ixfr == 0) { - was_ixfr++; - n = res_nmkquery(&res, QUERY, - zp->z_origin, - curclass, T_AXFR, - NULL, 0, - NULL, buf, bufsize); - if (n < 0) { - if (!quiet) - syslog(LOG_INFO, - "zone %s: res_nmkquery T_SOA failed", - zp->z_origin); - (void) my_close(s); -#ifdef POSIX_SIGNALS - (void) sigaction(SIGALRM, &osv, - (struct sigaction *)0); -#else - (void) sigvec(SIGALRM, &osv, - (struct sigvec *)0); -#endif - return (XFER_FAIL); - } - /* - * Append TSIG to SOA query if desired - */ - tsig_key = tsig_key_from_addr(sin.sin_addr); - if (tsig_key != NULL) { - siglen = sizeof(sig); - ret = ns_sign(buf, &n, bufsize, - NOERROR, - tsig_key, NULL, - 0, sig, &siglen, - timesigned); - if (ret == 0) - tsig_signed = 1; - } - - /* - * Send length & message for AXFR query - */ - if (writemsg(s, buf, n) < 0) - syslog(LOG_INFO, - "writemsg: %m"); - else { - methode = ISNOTIXFR; - check_serial = 0; - soa_cnt = 0; - was_ixfr = 0; - goto receive; - } - } - (void) my_close(s); - return (XFER_FAIL); - } - if (ancount == 1) { - methode = ISNOTIXFR; - check_serial = 0; - soa_cnt = 0; - goto axfr_response; - } - dprintf(1, "We have an IXFR\n"); - while (SEQ_GT(zp_finish.z_serial, serial_no)) { - /* - * Receive length & response - */ - if (netread(s, (char *)buf, INT16SZ, - (soa_cnt == 0) ?300 :XFER_TIMER) - < 0) { - error++; - break; - } - if ((len = ns_get16(buf)) == 0) - break; - if (len > bufsize) { - buf = (u_char *)realloc(buf, len); - if (buf == NULL) { - syslog(LOG_INFO, - "malloc(%u) failed for packet from server [%s], zone %s\n", - len, - inet_ntoa(sin.sin_addr), - zp->z_origin); - error++; - break; - } - bufsize = len; - } - hp = (HEADER *)buf; - eom = buf + len; - if (netread(s, (char *)buf, len, XFER_TIMER) - < 0) { - error++; - break; - } -#ifdef DEBUG - if (debug >= 3) { - (void)fprintf(ddt,"len = %d\n", len); - res_pquery(&res, buf, len, ddt); - } - if (fp) - res_pquery(&res, buf, len, fp); -#endif - /* - * Verify the TSIG if expected - */ - if (tsig_signed != 0) { - tsig_req = (soa_cnt == 0); - ret = ns_verify_tcp(buf, (int *)&len, - &tsig_state, - tsig_req); - eom = buf + len; - - if (ret != 0) { - syslog(LOG_NOTICE, - "TSIG verification from server [%s], zone %s: %s (%d)\n", - inet_ntoa(sin.sin_addr), - zp->z_origin, - tsig_rcode(ret), ret); - error++; - break; - } - } - if (len < HFIXEDSZ) { - error++; - alen = sizeof my_addr; - if (getsockname(s, (struct sockaddr *) - &my_addr, &alen) < 0) - sprintf(my_addr_text, "[errno %d]", errno); - else - sprintf(my_addr_text, "[%s].%u", - inet_ntoa(my_addr. sin_addr), - ntohs(my_addr.sin_port)); - if ((hp->rcode == REFUSED) && - (len >= HFIXEDSZ)) { - syslog(LOG_INFO, - "[%s] transfer refused from [%s], zone %s\n", - my_addr_text, - inet_ntoa(sin.sin_addr), - zp->z_origin); - } else { - syslog(LOG_INFO, - "[%s] record too short from [%s], zone %s\n", - my_addr_text, - inet_ntoa(sin.sin_addr), - zp->z_origin); - } - break; - } - if (ixfp) - if (ixfr_log(buf, len, &delete_soa, ixfp, - &sin, domain, &serial_no, - &ixfr_first) < 0) { - error++; - break; - } - } - (void) my_close(s); - if (!error) { - fprintf(ixfp, "update:\t{add} "); - if (soa_buf) - fputs(soa_buf, ixfp); - fprintf(ixfp, "[END_DELTA]\n"); - return (XFER_SUCCESSIXFR); - } - } - } -#ifdef POSIX_SIGNALS - (void) sigaction(SIGALRM, &osv, (struct sigaction *)0); -#else - (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); -#endif - if (ixfp) { - (void) unlink (tmpiname); - (void) my_fclose(ixfp); - ixfp = 0; - } - if (!error) - return (XFER_TIMEOUT); - return (XFER_FAIL); -} - -static SIG_FN -term_handler() { - cleanup_for_exit(); - _exit(XFER_FAIL); /* not safe to call exit() from a signal handler */ -} - -/* - * Set flag saying to read was interrupted - * used for a read timer - */ -static SIG_FN -read_alarm() { - read_interrupted = 1; -} - -static int -netread(int fd, char *buf, int len, int timeout) { - static const char setitimerStr[] = "setitimer: %m"; - struct itimerval ival, zeroival; - struct sockaddr_in sa; - int n, salen; -#if defined(NETREAD_BROKEN) - int retries = 0; -#endif - - memset(&zeroival, 0, sizeof zeroival); - ival = zeroival; - ival.it_value.tv_sec = timeout; - while (len > 0) { -#ifndef WINNT - if (setitimer(ITIMER_REAL, &ival, NULL) < 0) { - syslog(LOG_INFO, setitimerStr); - return (-1); - } -#endif - errno = 0; - salen = sizeof sa; - n = recvfrom(fd, buf, len, 0, (struct sockaddr *)&sa, &salen); - if (n == 0 && errno == 0) { -#if defined(NETREAD_BROKEN) - if (++retries < 42) /* doug adams */ - continue; -#endif - syslog(LOG_INFO, "premature EOF, fetching \"%s\"", - domain); - return (-1); - } - if (n < 0) { - if (errno == 0) { -#if defined(NETREAD_BROKEN) - if (++retries < 42) /* doug adams */ - continue; -#endif - syslog(LOG_INFO, - "recv(len=%d): n=%d && !errno", - len, n); - return (-1); - } - if (errno == EINTR) { - if (!read_interrupted) { - /* It wasn't a timeout; ignore it. */ - continue; - } - errno = ETIMEDOUT; - } - syslog(LOG_INFO, "recv(len=%d): %m", len); - return (-1); - } - buf += n; - len -= n; - } -#ifndef WINNT - if (setitimer(ITIMER_REAL, &zeroival, NULL) < 0) { - syslog(LOG_INFO, setitimerStr); - return (-1); - } -#endif - return (0); -} - -/* - * Write a counted buffer to a file descriptor preceded by a length word. - */ -static int -writemsg(int rfd, const u_char *msg, int msglen) { - struct iovec iov[2]; - u_char len[INT16SZ]; - int ret; - - __putshort(msglen, len); - iov[0].iov_base = (char *)len; - iov[0].iov_len = INT16SZ; - iov[1].iov_base = (char *)msg; - iov[1].iov_len = msglen; - ret = writev(rfd, iov, 2); - if (ret != INT16SZ + msglen) { - syslog(LOG_DEBUG, "writemsg(%d,%#x,%d) failed: %s", - rfd, msg, msglen, strerror(errno)); - return (-1); - } - return (ret); -} - -static const char * -soa_zinfo(struct zoneinfo *zp, u_char *cp, u_char *eom) { - int n, type, class; - u_int32_t ttl; - u_int16_t dlen; - u_char *rdatap; - - /* Are type, class, and ttl OK? */ - if (eom - cp < 3 * INT16SZ + INT32SZ) - return ("zinfo too short"); - NS_GET16(type, cp); - NS_GET16(class, cp); - NS_GET32(ttl, cp); - NS_GET16(dlen, cp); - rdatap = cp; - if (type != T_SOA || class != curclass) - return ("zinfo wrong typ/cla/ttl"); - /* Skip master name and contact name, we can't validate them. */ - if ((n = dn_skipname(cp, eom)) == -1) - return ("zinfo mname"); - cp += n; - if ((n = dn_skipname(cp, eom)) == -1) - return ("zinfo hname"); - cp += n; - /* Grab the data fields. */ - if (eom - cp < 5 * INT32SZ) - return ("zinfo dlen"); - NS_GET32(zp->z_serial, cp); - NS_GET32(zp->z_refresh, cp); - NS_GET32(zp->z_retry, cp); - NS_GET32(zp->z_expire, cp); - NS_GET32(zp->z_minimum, cp); - if (cp != rdatap + dlen) - return ("bad soa dlen"); - return (NULL); -} - -#define BOUNDS_CHECK(ptr, count) \ - do { \ - if ((ptr) + (count) > eom) { \ - hp->rcode = FORMERR; \ - return (-1); \ - } \ - } while (0) - -/* - * Parse the message, determine if it should be printed, and if so, print it - * in .db file form. Does minimal error checking on the message content. - * - * XXX why aren't we using ns_sprintrr() ? - */ -static int -print_output(struct zoneinfo *zp, u_int32_t serial_no, u_char *msg, - int msglen, u_char *rrp, int was_ixfr) { - u_char *cp; - HEADER *hp = (HEADER *) msg; - u_int32_t addr, ttl, tmpnum; - int i, j, tab, result, n1, n; - u_int class, type, dlen; - char data[MAXDATA]; - u_char *cp1, *cp2, *temp_ptr, *eom, *rr_type_ptr; - u_char *cdata, *rdatap; - char *origin, dname[MAXDNAME]; - const char *proto; - const char *ignore = ""; - const char *badsoa_msg; - int escaped = 0; - - eom = msg + msglen; - cp = rrp; - n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ); - rr_type_ptr = cp; - NS_GET16(type, cp); - NS_GET16(class, cp); - NS_GET32(ttl, cp); - /* - * Following the Clarification draft's direction, we treat TTLs with - * the MSB set as if they were 0. - */ - if (ttl > MAXIMUM_TTL) { - syslog(LOG_INFO, "%s: TTL > %u, converted to 0", dname, - MAXIMUM_TTL); - ttl = 0; - } - NS_GET16(dlen, cp); - BOUNDS_CHECK(cp, dlen); - rdatap = cp; - - origin = dname; - while (*origin) { - if (!escaped && *origin == '.') { - origin++; /* skip over '.' */ - break; - } - escaped = (*origin++ == '\\') && !escaped; - } - dprintf(3, "print_output: dname %s type %d class %d ttl %u\n", - dname, type, class, ttl); - /* - * Convert the resource record data into the internal database format. - * CP points to the raw resource record. - * After this switch: - * CP has been updated to point past the RR. - * CP1 points to the internal database version. - * N is the length of the internal database version. - */ - switch (type) { - case T_A: - case T_WKS: - case T_HINFO: - case T_TXT: - case T_X25: - case T_ISDN: - case T_LOC: - case T_NSAP: - case T_AAAA: - case T_KEY: - case ns_t_cert: - cp1 = cp; - n = dlen; - cp += n; - break; - - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - n = dn_expand(msg, msg + msglen, cp, data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 = (u_char *)data; - n = strlen(data) + 1; - break; - - case T_MINFO: - case T_SOA: - case T_RP: - n = dn_expand(msg, msg + msglen, cp, data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - n = strlen(data) + 1; - cp1 = (u_char *)data + n; - n1 = sizeof data - n; - if (type == T_SOA) - n1 -= 5 * INT32SZ; - n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 += strlen((char *) cp1) + 1; - if (type == T_SOA) { - BOUNDS_CHECK(cp, 5 * INT32SZ); - temp_ptr = cp + 4 * INT32SZ; - NS_GET32(minimum_ttl, temp_ptr); - /* - * Following the Clarification draft's direction, - * we treat TTLs with the MSB set as if they were 0. - */ - if (minimum_ttl > MAXIMUM_TTL) { - syslog(LOG_INFO, - "%s: SOA minimum TTL > %u, converted to 0", - dname, MAXIMUM_TTL); - minimum_ttl = 0; - } - n = 5 * INT32SZ; - memcpy(cp1, cp, n); - cp += n; - cp1 += n; - } - n = cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - - case T_NAPTR: - /* Grab weight and port. */ - BOUNDS_CHECK(cp, INT16SZ*2); - memcpy(data, cp, INT16SZ*2); - cp1 = (u_char *)data + INT16SZ*2; - cp += INT16SZ*2; - - /* Flags */ - BOUNDS_CHECK(cp, 1); - n = *cp++; - BOUNDS_CHECK(cp, n); - *cp1++ = n; - memcpy(cp1, cp, n); - cp += n; cp1 += n; - - /* Service */ - BOUNDS_CHECK(cp, 1); - n = *cp++; - BOUNDS_CHECK(cp, n); - *cp1++ = n; - memcpy(cp1, cp, n); - cp += n; cp1 += n; - - /* Regexp */ - BOUNDS_CHECK(cp, 1); - n = *cp++; - BOUNDS_CHECK(cp, n); - *cp1++ = n; - memcpy(cp1, cp, n); - cp += n; cp1 += n; - - /* Replacement */ - n = dn_expand(msg, msg + msglen, cp, (char *)cp1, - sizeof data - ((char *)cp1 - data)); - if (n < 0) - return (-1); - cp += n; - - /* compute end of data */ - cp1 += strlen((char *)cp1) + 1; - /* compute size of data */ - n = cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - - case T_MX: - case T_AFSDB: - case T_RT: - case T_SRV: - /* grab preference */ - BOUNDS_CHECK(cp, INT16SZ); - memcpy(data, cp, INT16SZ); - cp1 = (u_char *)data + INT16SZ; - cp += INT16SZ; - - if (type == T_SRV) { - BOUNDS_CHECK(cp, INT16SZ*2); - memcpy(cp1, cp, INT16SZ*2); - cp1 += INT16SZ*2; - cp += INT16SZ*2; - } - - /* get name */ - n = dn_expand(msg, msg + msglen, cp, - (char *)cp1, - sizeof data - (cp1 - (u_char *)data)); - if (n < 0) - return (-1); - cp += n; - - /* compute end of data */ - cp1 += strlen((char *) cp1) + 1; - /* compute size of data */ - n = cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - - case T_PX: - /* grab preference */ - BOUNDS_CHECK(cp, INT16SZ); - memcpy(data, cp, INT16SZ); - cp1 = (u_char *)data + INT16SZ; - cp += INT16SZ; - - /* get MAP822 name */ - n = dn_expand(msg, msg + msglen, cp, - (char *)cp1, sizeof data - INT16SZ); - if (n < 0) - return (-1); - cp += n; - cp1 += (n = (strlen((char *) cp1) + 1)); - n1 = sizeof data - n; - - /* get MAPX400 name */ - n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1); - if (n < 0) - return (-1); - cp += n; - cp1 += strlen((char *) cp1) + 1; - n = cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - - case T_SIG: - /* CP is the raw resource record as it arrived. - * CP1, after this switch, points to the internal database version. */ - cp1 = (u_char *)data; - - /* first just copy over the type_covered, algorithm, */ - /* labels, orig ttl, two timestamps, and the footprint */ - BOUNDS_CHECK(cp, NS_SIG_SIGNER); - memcpy(cp1, cp, NS_SIG_SIGNER); - cp += NS_SIG_SIGNER; - cp1 += NS_SIG_SIGNER; - - /* then the signer's name */ - n = dn_expand(msg, msg + msglen, cp, - (char *)cp1, (sizeof data) - 18); - if (n < 0) - return (-1); - cp += n; - cp1 += strlen((char*)cp1)+1; - - /* finally, we copy over the variable-length signature. - Its size is the total data length, minus what we copied. */ - n = dlen - (NS_SIG_SIGNER + n); - if (n > ((int)(sizeof data) - (int)(cp1 - (u_char *)data))) { - hp->rcode = FORMERR; - return (-1); /* out of room! */ - } - memcpy(cp1, cp, n); - cp += n; - cp1 += n; - - /* compute size of data */ - n = cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - - case T_NXT: - n = dn_expand(msg, msg + msglen, cp, - (char *)data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 = (u_char *)data + strlen(data) + 1; - n = dlen - n; - if (n > ((int)(sizeof data) - (int)(cp1 - (u_char *)data))) { - hp->rcode = FORMERR; - return (-1); /* out of room! */ - } - if (n > 0) { /* Actually, n should never be less than 4 */ - memcpy(cp1, cp, n); - cp += n; - } else { - hp->rcode = FORMERR; - return (-1); - } - n += cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - - default: - syslog(LOG_INFO, "\"%s %s %s\" - unknown type (%d)", - dname, p_class(class), p_type(type), type); - hp->rcode = NOTIMP; - return (-1); - } - - if (n > MAXDATA) { - dprintf(1, "update type %d: %d bytes is too much data\n", - type, n); - hp->rcode = FORMERR; - return (-1); - } - if (cp != rdatap + dlen) { - dprintf(1, - "encoded rdata length is %u, but actual length was %u\n", - dlen, (u_int)(cp - rdatap)); - hp->rcode = FORMERR; - return (-1); - } - - cdata = cp1; - result = cp - rrp; - - /* - * Special handling for SOA records. - */ - - if (type == T_SOA) { - if (ns_samename(dname, zp->z_origin) != 1) { - syslog(LOG_INFO, - "wrong zone name in XFR (wanted \"%s\", got \"%s\")", - zp->z_origin, dname); - hp->rcode = FORMERR; - return (-1); - } - if (soa_cnt == 0) { - badsoa_msg = soa_zinfo(&zp_start, rr_type_ptr, eom); - if (badsoa_msg) { - syslog(LOG_INFO, - "malformed SOA for zone %s: %s", - zp->z_origin, badsoa_msg); - hp->rcode = FORMERR; - return (-1); - } - if (SEQ_GT(zp_start.z_serial, serial_no) || - !check_serial) { - soa_cnt++; - } else { - syslog(LOG_INFO, - "serial went backwards after transfer started"); - return (-1); - } - } else if (soa_cnt == 1) { - badsoa_msg = soa_zinfo(&zp_finish, rr_type_ptr, eom); - if (badsoa_msg) { - syslog(LOG_INFO, - "malformed SOA for zone %s: %s", - zp->z_origin, badsoa_msg); - hp->rcode = FORMERR; - return (-1); - } - if (zp_start.z_serial == zp_finish.z_serial) { - methode = ISNOTIXFR; - } else if (zp_finish.z_serial != serial_no) { - syslog(LOG_INFO, - "Unexpected serial number for zone %s: %u", - zp->z_origin, zp_finish.z_serial); - } - soa_cnt++; - if (methode == ISIXFR) - return (result); - } else { - badsoa_msg = soa_zinfo(&zp_finish, rr_type_ptr, eom); - if (badsoa_msg) { - syslog(LOG_INFO, - "malformed SOA for zone %s: %s", - zp->z_origin, badsoa_msg); - hp->rcode = FORMERR; - return (-1); - } - if (methode == ISIXFR) { - if (zp_start.z_serial == zp_finish.z_serial) { - if (scdsoa) { - soa_cnt = -1; - return (result); - } else { - scdsoa = 1; - soa_cnt++; - }; - } else - soa_cnt++; - } else { - dprintf(2, "SOA, serial %u\n", - zp_finish.z_serial); - if (zp_start.z_serial != zp_finish.z_serial) { - dprintf(1, "serial changed, restart\n"); - restarts++; - if (restarts > MAX_XFER_RESTARTS) { - syslog(LOG_INFO, - "too many transfer restarts for zone %s", - zp->z_origin); - hp->rcode = FORMERR; - return (-1); - } - soa_cnt = 0; - ns_cnt = 0; - minimum_ttl = 0; - strcpy(prev_origin, zp->z_origin); - prev_dname[0] = DEF_DNAME; - /* - * Flush buffer, truncate file - * and seek to beginning to restart. - */ - fflush(dbfp); - if (ftruncate(fileno(dbfp), 0) != 0) { - if (!quiet) - syslog(LOG_INFO, - "ftruncate %s: %m\n", - tmpname); - return (-1); - } - fseek(dbfp, 0L, 0); - return (result); - } - soa_cnt++; - return (result); - } - } - if ((soa_cnt == 2) && (was_ixfr == 0)) - return (result); - - } - - if (zp->z_type == Z_STUB) { - if (query_type == T_NS && type == T_NS) - ns_cnt++; - /* - * If we're processing a response to an SOA query, we don't - * want to print anything from the response except for the SOA. - * We do want to check everything in the packet, which is - * why we do this check now instead of earlier. - */ - if (query_type == T_SOA && type != T_SOA) - return (result); - } - - if ((!soa_cnt || soa_cnt > 2) && methode == ISNOTIXFR) { - char *gripe; - - if (!soa_cnt) - gripe = "got RR before first SOA"; - else - gripe = "got RR after second SOA"; - syslog(LOG_INFO, "%s in zone %s", gripe, zp->z_origin); - hp->rcode = FORMERR; - return (-1); - } - - /* - * If they are trying to tell us info about something that is - * not in the zone that we are transfering, then ignore it! - * They don't have the authority to tell us this info. - * - * We have to do a bit of checking here - the name that we are - * checking is is fully qualified & may be in a subdomain of the - * zone in question. We also need to ignore any final dots. - * - * If a domain has both NS records and non-NS records, (for - * example, NS and MX records), then we should ignore the non-NS - * records (except that we should not ignore glue A records). - * XXX: It is difficult to do this properly, so we just compare - * the current dname with that in the most recent NS record. - * This defends against the most common error case, - * where the remote server sends MX records soon after the - * NS records for a particular domain. If sent earlier, we lose. XXX - */ - if (!ns_samedomain(dname, domain)) { - (void) fprintf(dbfp, "; Ignoring info about %s, not in zone %s.\n", - dname, domain); - ignore = "; "; - } else if (type != T_NS && type != T_A && - ns_samename(zone_top, dname) != 1 && - ns_samename(prev_ns_dname, dname) == 1) - { - (void) fprintf(dbfp, "; Ignoring extra info about %s, invalid after NS delegation.\n", - dname); - ignore = "; "; - } else if (class != zp->z_class) { - (void) fprintf(dbfp, "; Ignoring info about %s, not class %s\n", - dname, p_class(zp->z_class)); - ignore = "; "; - } - - /* - * If the current record is not being ignored, but the - * previous record was ignored, then we invalidate information - * that might have been altered by ignored records. - * (This means that we sometimes output unnecessary $ORIGIN - * lines, but that is harmless.) - * - * Also update prev_comment now. - */ - if (prev_comment && ignore[0] == '\0') { - prev_dname[0] = DEF_DNAME; - prev_origin[0] = DEF_DNAME; - } - prev_comment = (ignore[0] != '\0'); - - /* - * set prev_ns_dname if necessary - */ - if (type == T_NS) { - (void) strcpy(prev_ns_dname, dname); - } - - /* - * If the origin has changed, print the new origin - */ - if (ns_samename(prev_origin, origin) != 1) { - (void) strcpy(prev_origin, origin); - (void) fprintf(dbfp, "%s$ORIGIN %s.\n", ignore, origin); - } - tab = 0; - - if (ns_samename(prev_dname, dname) != 1) { - /* - * set the prev_dname to be the current dname, then cut off all - * characters of dname after (and including) the first '.' - */ - char *cutp; - - (void) strcpy(prev_dname, dname); - escaped = 0; - cutp = dname; - while (*cutp) { - if (!escaped && *cutp == '.') - break; - escaped = (*cutp++ == '\\') && !escaped; - } - *cutp = '\0'; - - if (dname[0] == 0) { - if (origin[0] == 0) - (void) fprintf(dbfp, "%s.\t", ignore); - else - (void) fprintf(dbfp, "%s.%s.\t", - ignore, origin); /* ??? */ - } else { - char *backslash; - backslash = (*dname == '@' || *dname == '$') ? - "\\" : ""; - (void) fprintf(dbfp, "%s%s%s\t", ignore, - backslash, dname); - } - if (strlen(dname) < (size_t)8) - tab = 1; - } else { - (void) fprintf(dbfp, "%s\t", ignore); - tab = 1; - } - - (void) fprintf(dbfp, "%d\t", (int) ttl); - - (void) fprintf(dbfp, "%s\t%s\t", p_class(class), p_type(type)); - cp = cdata; - - /* - * Print type specific data - */ - switch (type) { - - case T_A: - switch (class) { - case C_IN: - case C_HS: - fputs(inet_ntoa(ina_get(cp)), dbfp); - break; - } - (void) fprintf(dbfp, "\n"); - break; - - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_PTR: - if (cp[0] == '\0') - (void) fprintf(dbfp, ".\n"); - else - (void) fprintf(dbfp, "%s.\n", cp); - break; - - case T_NS: - cp = cdata; - if (cp[0] == '\0') - (void) fprintf(dbfp, ".\t"); - else - (void) fprintf(dbfp, "%s.", cp); - (void) fprintf(dbfp, "\n"); - break; - - case T_HINFO: - case T_ISDN: - cp2 = cp + n; - for (i = 0; i < 2; i++) { - if (i != 0) - (void) putc(' ', dbfp); - n = *cp++; - cp1 = cp + n; - if (cp1 > cp2) - cp1 = cp2; - (void) putc('"', dbfp); - j = 0; - while (cp < cp1) { - if (*cp == '\0') { - cp = cp1; - break; - } - if (strchr("\n\"\\", *cp)) - (void) putc('\\', dbfp); - (void) putc(*cp++, dbfp); - j++; - } - if (j == 0 && (type != T_ISDN || i == 0)) - (void) putc('?', dbfp); - (void) putc('"', dbfp); - } - (void) putc('\n', dbfp); - break; - - case T_SOA: - (void) fprintf(dbfp, "%s.", cp); - cp += strlen((char *) cp) + 1; - (void) fprintf(dbfp, " %s. (\n", cp); - cp += strlen((char *) cp) + 1; - NS_GET32(tmpnum, cp); - (void) fprintf(dbfp, "%s\t\t%u", ignore, tmpnum); - NS_GET32(tmpnum, cp); - (void) fprintf(dbfp, " %u", tmpnum); - NS_GET32(tmpnum, cp); - (void) fprintf(dbfp, " %u", tmpnum); - NS_GET32(tmpnum, cp); - (void) fprintf(dbfp, " %u", tmpnum); - NS_GET32(tmpnum, cp); - (void) fprintf(dbfp, " %u )\n", tmpnum); - break; - - case T_MX: - case T_AFSDB: - case T_RT: - NS_GET16(tmpnum, cp); - (void) fprintf(dbfp, "%u", tmpnum); - (void) fprintf(dbfp, " %s.\n", cp); - break; - - case T_PX: - NS_GET16(tmpnum, cp); - (void) fprintf(dbfp, "%u", tmpnum); - (void) fprintf(dbfp, " %s.", cp); - cp += strlen((char *) cp) + 1; - (void) fprintf(dbfp, " %s.\n", cp); - break; - - case T_TXT: - case T_X25: - cp1 = cp + n; - while (cp < cp1) { - (void) putc('"', dbfp); - if ((i = *cp++) != 0) { - for (j = i; j > 0 && cp < cp1; j--) { - if (strchr("\n\"\\", *cp)) - (void) putc('\\', dbfp); - (void) putc(*cp++, dbfp); - } - } - (void) putc('"', dbfp); - if (cp < cp1) - (void) putc(' ', dbfp); - } - (void) putc('\n', dbfp); - break; - - case T_NSAP: - fprintf(dbfp, "%s\n", inet_nsap_ntoa(n, cp, NULL)); - break; - - case T_AAAA: { - char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - - fprintf(dbfp, "%s\n", inet_ntop(AF_INET6, cp, t, sizeof t)); - break; - } - - case T_LOC: { - char t[255]; - - (void) fprintf(dbfp, "%s\n", loc_ntoa(cp, t)); - break; - } - - case T_NAPTR: { - u_int32_t order, preference; - - /* Order */ - NS_GET16(order, cp); - fprintf(dbfp, "%u", order); - - /* Preference */ - NS_GET16(preference, cp); - fprintf(dbfp, " %u", preference); - - /* Flags */ - if ((n = *cp++) != 0) { - fprintf(dbfp, " \"%.*s\"", (int)n, cp); - cp += n; - } - - /* Service */ - if ((n = *cp++) != 0) { - fprintf(dbfp, " \"%.*s\"", (int)n, cp); - cp += n; - } - - /* Regexp */ - if ((n = *cp++) != 0) { - fprintf(dbfp, " \"%.*s\"", (int)n, cp); - cp += n; - } - - /* Replacement */ - fprintf(dbfp, " %s.\n", cp); - - break; - } - case T_SRV: { - u_int priority, weight, port; - - NS_GET16(priority, cp); - NS_GET16(weight, cp); - NS_GET16(port, cp); - fprintf(dbfp, "\t%u %u %u %s.\n", - priority, weight, port, cp); - break; - } - - case T_WKS: - fputs(inet_ntoa(ina_get(cp)), dbfp); - cp += INADDRSZ; - fputc(' ', dbfp); - proto = protocolname(*cp); - cp += sizeof(char); - (void) fprintf(dbfp, "%s ", proto); - i = 0; - while (cp < cdata + n) { - j = *cp++; - do { - if (j & 0200) - (void) fprintf(dbfp, " %s", - servicename(i, proto)); - j <<= 1; - } while (++i & 07); - } - (void) fprintf(dbfp, "\n"); - break; - - case T_MINFO: - case T_RP: - (void) fprintf(dbfp, "%s.", cp); - cp += strlen((char *) cp) + 1; - (void) fprintf(dbfp, " %s.\n", cp); - break; - - case T_KEY: { - char databuf[16+NS_MD5RSA_MAX_BASE64]; /* 16 for slop */ - u_int keyflags; - - /* get & format key flags */ - keyflags = ns_get16(cp); - (void) fprintf(dbfp, "0x%04x ", keyflags); - cp += INT16SZ; - - /* protocol id */ - (void) fprintf(dbfp, " %u", *cp++); - - /* algorithm id */ - (void) fprintf(dbfp, " %u ", *cp++); - - /* key itself (which may have zero length) */ - n = b64_ntop(cp, (cp1 + n) - cp, databuf, sizeof databuf); - if (n < 0) - fprintf(dbfp, "; BAD BASE64\n"); - else - fprintf(dbfp, "%s\n", databuf); - break; - } - - case T_SIG: { - char databuf[16+NS_MD5RSA_MAX_BASE64]; /* 16 for slop */ - - /* get & format rr type which signature covers */ - (void) fprintf(dbfp,"%s", p_type(ns_get16((u_char*)cp))); - cp += INT16SZ; - - /* algorithm id */ - (void) fprintf(dbfp," %d",*cp++); - - /* labels (# of labels in name) */ - (void) fprintf(dbfp," %d",*cp++); - - /* orig time to live (TTL)) */ - (void) fprintf(dbfp," %u", (u_int32_t)ns_get32((u_char*)cp)); - cp += INT32SZ; - - /* expiration time */ - (void) fprintf(dbfp," %s", p_secstodate(ns_get32((u_char*)cp))); - cp += INT32SZ; - - /* time signed */ - (void) fprintf(dbfp," %s", p_secstodate(ns_get32((u_char*)cp))); - cp += INT32SZ; - - /* Key footprint */ - (void) fprintf(dbfp," %d", ns_get16((u_char*)cp)); - cp += INT16SZ; - - /* signer's name */ - (void) fprintf(dbfp, " %s. ", cp); - cp += strlen((char *) cp) + 1; - - /* signature itself */ - n = b64_ntop(cp, (cdata + n) - cp, databuf, sizeof databuf); - if (n < 0) - fprintf (dbfp, "; BAD BASE64\n"); - else - fprintf (dbfp, "%s\n", databuf); - break; - } - - case T_NXT: - fprintf(dbfp, "%s.", (char *)cp); - i = strlen((char *)cp)+1; - cp += i; - n -= i; - for (i=0; i < n*NS_NXT_BITS; i++) - if (NS_NXT_BIT_ISSET (i, cp)) - fprintf(dbfp, " %s", p_type(i)); - fprintf(dbfp,"\n"); - break; - - case ns_t_cert: { - int databufsize = n * 4 / 3 + 4; - char *databuf = malloc(databufsize); - - if (databuf == NULL) - panic("cert malloc failed", NULL); - - /* Object id */ - (void) fprintf(dbfp,"%d ", ns_get16((u_char*)cp)); - cp += INT16SZ; - - /* Key tag */ - (void) fprintf(dbfp,"%d ", ns_get16((u_char*)cp)); - cp += INT16SZ; - - /* Algorithm id */ - (void) fprintf(dbfp,"%d ", (u_char)*cp); - cp += 1; - - n = b64_ntop(cp, n - 2 * INT16SZ - 1, databuf, databufsize); - if (n < 0) - panic ("cert b64_ntop failed", NULL); - fprintf (dbfp, "%s\n", databuf); - free(databuf); - break; - } - - default: - cp1 = cp + n; - while (cp < cp1) - fprintf(dbfp, "0x%02.2X ", *cp++ & 0xFF); - (void) fprintf(dbfp, "???\n"); - } - if (ferror(dbfp)) { - syslog(LOG_ERR, "%s: %m", tmpname); - cleanup_for_exit(); - exit(XFER_FAIL); - } - return (result); -} - -#ifdef SHORT_FNAMES -/* -** This routine handles creating temporary files with mkstemp -** in the presence of a 14 char filename system. Pathconf() -** does not work over NFS. -*/ -filenamecpy(char *ddtfile, char *optarg) { - int namelen, extra, len; - char *dirname, *filename; - - /* determine the length of filename allowed */ - if((dirname = strrchr(optarg, '/')) == NULL){ - filename = optarg; - } else { - *dirname++ = '\0'; - filename = dirname; - } - namelen = pathconf(dirname == NULL? "." : optarg, _PC_NAME_MAX); - if(namelen <= 0) - namelen = 255; /* length could not be determined */ - if(dirname != NULL) - *--dirname = '/'; - - /* copy a shorter name if it will be longer than allowed */ - extra = (strlen(filename)+strlen(".XXXXXX")) - namelen; - if(extra > 0){ - len = strlen(optarg) - extra; - (void) strncpy(ddtfile, optarg, len); - ddtfile[len] = '\0'; - } else - (void) strcpy(ddtfile, optarg); -} -#endif /* SHORT_FNAMES */ - -DST_KEY * -tsig_key_from_addr(struct in_addr addr) { - tsig_node *n; - for (n = HEAD(tsig_list); n != NULL; n = NEXT(n, link)) - if (memcpy(&addr, &n->addr, sizeof(struct in_addr))) - return n->dst_key; - return NULL; -} - -static u_int32_t -do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file, int *delete) { - int n, sflag, rrnum; - char buf[2048]; /* XXX need to malloc */ - ns_opcode opcode; - ns_rr rr; - const unsigned char *cp; - const unsigned char *eom; - u_int32_t serial; - time_t now; - - time(&now); - - /* - * Print answer records. - */ - sflag = (_res.pfcode & pflag); - if (_res.pfcode && !sflag) - return (-1); - - opcode = (ns_opcode)ns_msg_getflag(*handle, ns_f_opcode); - rrnum = 0; - serial = -1; - for (;;) { - if (ns_parserr(handle, section, rrnum, &rr)) { - if (errno != ENODEV) { - fprintf(file, ";; ns_parserr: %s\n", - strerror(errno)); - return (-1); - } else if (rrnum > 0 && sflag != 0 && - (_res.pfcode & RES_PRF_HEAD1)) - putc('\n', file); - return (serial); - } - if (rrnum == 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1)) - fprintf(file, ";; %s SECTION:\n", - p_section(section, opcode)); - if (section == ns_s_qd) - fprintf(file, ";;\t%s, type = %s, class = %s\n", - ns_rr_name(rr), - p_type(ns_rr_type(rr)), - p_class(ns_rr_class(rr))); - else { - int print_record = 1; - if (rr.type == ns_t_soa) { - print_record = 0; - *delete = !*delete; - cp = ns_rr_rdata(rr); - eom = cp + ns_rr_rdlen(rr); - if ((n = dn_skipname(cp, eom)) < 0) { - rrnum++; - continue; - } - cp += n; - if ((n = dn_skipname(cp, eom)) < 0) { - rrnum++; - continue; - } - cp += n; - NS_GET32(serial, cp); - switch (++ixfr_soa) { - case 1: - final_serial = serial; - if (soa_buf == NULL) { - if ((soa_buf = (char *)malloc(2 * PACKETSZ)) == NULL) { - syslog(LOG_INFO, "malloc(%u) failed", 2 * PACKETSZ); - return(-1); - } - n = ns_sprintrr(handle, &rr, NULL, NULL, - soa_buf, 2*PACKETSZ); - if (n < 0) { - fprintf(file, ";; ns_sprintrr: %s\n", - strerror(errno)); - return (-1); - } - } - print_record = 0; - break; - case 2: - fprintf(file, - "zone:\torigin %s class %s serial %u\n", - ns_rr_name(rr), - p_class(ns_rr_class(rr)), - serial); - print_record = 0; - break; - default: - print_record = 0; - break; - } - - } - - if (print_record) { - if (rr.type != ns_t_soa) { - fprintf(file, "update:\t{%s} ", - *delete ? "delete" : "add"); - - n = ns_sprintrr(handle, &rr, NULL, NULL, - buf, sizeof buf); - if (n < 0) { - fprintf(file, ";; ns_sprintrr: %s\n", - strerror(errno)); - return(-1); - } - fputs(buf, file); - fputc('\n', file); - } - } - - } - rrnum++; - } - return (serial); -} - -static int -ixfr_log(const u_char *msg, int len, int *delete, FILE *file, - struct sockaddr_in *sin, char *domain, u_int32_t *serial_no, - int *first_rr) -{ - ns_msg handle; - ns_type type; - ns_class class; - ns_opcode opcode; - ns_rcode rcode; - u_int id, n; - char time[25]; - ns_rr rr; - char *cp; - HEADER *hp; - - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - dprintf(1, "ixfr_log() failed\n"); - return (-1); - } - - if (ns_initparse(msg, len, &handle) < 0) { - fprintf(file, ";; ns_initparse: %s\n", strerror(errno)); - dprintf(1, "ixfr_log() failed\n"); - return (-1); - } - opcode = (ns_opcode) ns_msg_getflag(handle, ns_f_opcode); - rcode = (ns_rcode) ns_msg_getflag(handle, ns_f_rcode); - id = ns_msg_id(handle); - - if (ns_parserr(&handle, ns_s_an, 0, &rr)) - { - - (void) fprintf(file,"ns_parserr() failed"); - dprintf(1, "ixfr_log() failed\n"); - return (-1); - } - type = (ns_type)rr.type; - class = (ns_class)rr.rr_class; - - if (*first_rr == 1) { - gettime(&tt); - (void) fprintf(file,"%s", LogSignature); - sprintf(time, "at %lu", (u_long)tt.tv_sec); - fprintf(file, - "[IXFR_UPDATE] id %u from [%s].%d %s (named-xfer pid %ld):\n", - id, inet_ntoa(sin->sin_addr), - ntohs(sin->sin_port), time, (long)getpid()); - (*first_rr)++; - } - *serial_no = do_section(&handle, ns_s_an, RES_PRF_ANS, file, delete); - return (1); -} - -static const char * -tsig_rcode(int rcode) { - static char buffer[64]; - - switch (rcode) { - case ns_r_badkey: - case ns_r_badsig: - case ns_r_badtime: - sprintf(buffer, "message had %s set", p_rcode(rcode)); - return (buffer); - case -ns_r_badkey: - case -ns_r_badsig: - case -ns_r_badtime: - return (p_rcode(-rcode)); - case NS_TSIG_ERROR_NO_TSIG: - return ("no TSIG present"); - default: - break; - } - return ("FORMERR"); -} - diff --git a/contrib/bind/bin/named/Makefile b/contrib/bind/bin/named/Makefile deleted file mode 100644 index fb5042796603d..0000000000000 --- a/contrib/bind/bin/named/Makefile +++ /dev/null @@ -1,133 +0,0 @@ -## Copyright (c) 1996-2000 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 8.50 2000/07/11 06:41:32 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -EXE= -YACC = yacc -d -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -DESTETC= /etc -DESTRUN= /var/run -AR= ar cru -INSTALL= install -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -PS=ps -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} ${DEFS} - -VER= LOCAL-`date +%y%m%d.%H%M%S` -HOSTNAMECMD= hostname || uname -n - -PROG= named -HDRS= db_defs.h db_glob.h ns_defs.h ns_glob.h named.h pathnames.h -SRCS= db_dump.c db_load.c db_lookup.c db_save.c db_update.c \ - db_glue.c db_ixfr.c db_sec.c db_tsig.c \ - ns_parser.c ns_lexer.c ns_parseutil.c ns_ctl.c \ - ns_forw.c ns_init.c ns_main.c ns_maint.c ns_req.c \ - ns_resp.c ns_stats.c ns_ncache.c ns_xfr.c ns_glue.c \ - ns_udp.c ns_config.c ns_update.c ns_ixfr.c ns_signal.c \ - ns_sort.c ns_notify.c -OBJS= db_dump.${O} db_load.${O} db_lookup.${O} db_save.${O} db_update.${O} \ - db_glue.${O} db_ixfr.${O} db_sec.${O} db_tsig.${O} \ - ns_parser.${O} ns_lexer.${O} ns_parseutil.${O} ns_ctl.${O} \ - ns_forw.${O} ns_init.${O} ns_main.${O} ns_maint.${O} ns_req.${O} \ - ns_resp.${O} ns_stats.${O} ns_ncache.${O} ns_xfr.${O} ns_glue.${O} \ - ns_udp.${O} ns_config.${O} ns_update.${O} ns_ixfr.${O} ns_signal.${O} \ - ns_sort.${O} ns_notify.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: pathnames.h ${OBJS} ${LIBBIND} Makefile tmp_version.${O} - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} \ - tmp_version.${O} ${LIBBIND} ${SYSLIBS} - -ns_parser.c ns_parser.h: ns_parser.y - ${YACC} ns_parser.y - mv y.tab.c ns_parser.c - mv y.tab.h ns_parser.h - -tmp_version.${O}: tmp_version.c - -tmp_version.c: version.c Makefile ../Makefile ${SRCS} ${HDRS} - (u=$${USER-root} d=`pwd` h=`${HOSTNAMECMD}` t=`date`; \ - sed -e "s|%WHEN%|$${t}|" -e "s|%VERSION%|"${VER}"|" \ - -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \ - < version.c > tmp_version.c); sleep 1 - -pathnames.h: ${TOP}/.settings Makefile pathtemplate.h - rm -f pathnames.h - sed -e "s|%DESTSBIN%|${DESTSBIN}|" \ - -e "s|%DESTEXEC%|${DESTEXEC}|" \ - -e "s|%DESTETC%|${DESTETC}|" \ - -e "s|%DESTRUN%|${DESTRUN}|" \ - < pathtemplate.h > pathnames.h - -ns_signal.${O}: ns_signal.c - ${CC} ${CPPFLAGS} ${CFLAGS} -c $*.c - -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - rm -f ns_parser.c ns_parser.h - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - rm -f tmp_version.c tmp_version.${O} - rm -f pathnames.h y.tab.h y.tab.c - -depend: ${SRCS} pathnames.h - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${DEFS} ${SRCS} - -${DESTDIR}${DESTSBIN}: - mkdir -p ${DESTDIR}${DESTSBIN} - -install: ${DESTDIR}${DESTSBIN} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTSBIN}/${PROG}${EXE} - -links: FRC - @ln -s SRC/*.[chy] SRC/test .; rm -f ns_parser.[ch] - -tags: FRC - ctags ${SRCS} *.h - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/named/db_defs.h b/contrib/bind/bin/named/db_defs.h deleted file mode 100644 index 6fad285ed9540..0000000000000 --- a/contrib/bind/bin/named/db_defs.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * from db.h 4.16 (Berkeley) 6/1/90 - * $Id: db_defs.h,v 8.38 2000/04/21 06:54:01 vixie Exp $ - */ - -/* - * Copyright (c) 1985, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Global definitions for data base routines. - */ - - /* max length of data in RR data field */ -#define MAXDATA (2*MAXDNAME + 5*INT32SZ) - - /* max length of data in a TXT RR segment */ -#define MAXCHARSTRING 255 - -#define DB_ROOT_TIMBUF 3600 -#define TIMBUF 300 - -#define DICT_INDEXBITS 24 -#define DICT_MAXLENGTH 127 -#define DICT_INSERT_P 0x0001 - -/* Average hash chain depths. */ -#define AVGCH_MARSHAL 5 -#define AVGCH_NLOOKUP 3 - -/* Nonstandard maximum class to force better packing. */ -#define ZONE_BITS 24 -#define CLASS_BITS 8 -#define ZONE_MAX ((1<<ZONE_BITS)-1) -#define CLASS_MAX ((1<<CLASS_BITS)-1) - -/* - * Hash table structures. - */ -struct databuf { - struct databuf *d_next; /* linked list */ - struct nameser *d_ns; /* NS from whence this came */ - u_int32_t d_ttl; /* time to live */ - /* if d_zone == DB_Z_CACHE, then - * d_ttl is actually the time when - * the record will expire. - * otherwise (for authoritative - * primary and secondary zones), - * d_ttl is the time to live. - */ - unsigned d_zone :ZONE_BITS; /* zone number or 0 for the cache */ - unsigned d_class :CLASS_BITS; /* class number (nonstandard limit) */ - unsigned d_flags :4; /* DB_F_{??????} */ - unsigned d_secure :2; /* DB_S_{??????} */ - unsigned d_cred :3; /* DB_C_{??????} */ - unsigned d_clev :6; - unsigned d_rcode :4; /* rcode for negative caching */ - unsigned d_mark :3; /* place to mark data */ - int16_t d_type; /* type number */ - int16_t d_size; /* size of data area */ - u_int32_t d_rcnt; - u_int16_t d_nstime; /* NS response time, milliseconds */ - u_char d_data[sizeof(void*)]; /* dynamic (padded) */ -}; -#define DATASIZE(n) (sizeof(struct databuf) - sizeof(void*) + n) - -#ifdef BIND_UPDATE -/* - * d_mark definitions - */ -#define D_MARK_DELETED 0x01 -#define D_MARK_ADDED 0x02 -#define D_MARK_FOUND 0x04 -#endif - -/* - * d_flags definitions - */ -#define DB_F_HINT 0x01 /* databuf belongs to fcachetab */ -#define DB_F_ACTIVE 0x02 /* databuf is linked into a cache */ -#define DB_F_FREE 0x04 /* databuf has been freed */ -#define DB_F_LAME 0x08 /* databuf may refer to lame server */ - -/* - * d_cred definitions - */ -#define DB_C_ZONE 4 /* authoritative zone - best */ -#define DB_C_AUTH 3 /* authoritative answer */ -#define DB_C_ANSWER 2 /* non-authoritative answer */ -#define DB_C_ADDITIONAL 1 /* additional data */ -#define DB_C_CACHE 0 /* cache - worst */ - -/* - * d_secure definitions - */ -#define DB_S_SECURE 2 /* secure (verified) data */ -#define DB_S_INSECURE 1 /* insecure data */ -#define DB_S_FAILED 0 /* data that failed a security check */ - -struct namebuf { - u_int n_hashval; /* hash value of _n_name */ - struct namebuf *n_next; /* linked list */ - struct databuf *n_data; /* data records */ - struct namebuf *n_parent; /* parent domain */ - struct hashbuf *n_hash; /* hash table for children */ - char _n_name[sizeof(void*)]; /* Counted str (dynamic). */ -}; -#define NAMESIZE(n) (sizeof(struct namebuf) - sizeof(void*) + 1 + n + 1) -#define NAMELEN(nb) (((u_char *)((nb)._n_name))[0]) -#define NAME(nb) ((nb)._n_name + 1) - -struct hashbuf { - int h_size; /* size of hash table */ - int h_cnt; /* number of entries */ - struct namebuf *h_tab[1]; /* allocated as needed */ -}; -#define HASHSIZE(s) (sizeof(struct hashbuf) + (s-1) * sizeof(struct namebuf *)) - -#define HASHSHIFT 3 -#define HASHMASK 0x1f -#define HASHROTATE(v) \ - (((v) << HASHSHIFT) | ((v) >> ((sizeof(v) * 8) - HASHSHIFT))) -#define HASHLOWER(c) ((isascii(c) && isupper(c)) ? tolower(c) : (c)) -#define HASHIMILATE(v,c) ((v) = (HASHROTATE(v)) + (HASHLOWER(c) & HASHMASK)) - -#define TSIG_BUF_SIZE 640 -#define TSIG_SIG_SIZE 20 - -struct tsig_record { - u_int8_t sig[TSIG_SIG_SIZE]; - struct dst_key *key; - int siglen; -}; - -struct sig_record { - u_int16_t sig_type_n; - u_int8_t sig_alg_n, sig_labels_n; - u_int32_t sig_ottl_n, sig_exp_n, sig_time_n; - u_int16_t sig_keyid_n; -}; - -/* This is the wire format size of "struct sig_record", i.e., no padding. */ -#define SIG_HDR_SIZE 18 - -struct dnode { - struct databuf *dp; - struct dnode *dn_next; - int line; - char *file; -}; - -typedef struct dnode * dlist; - -struct db_rrset { - dlist rr_list; - dlist rr_sigs; - char *rr_name; - int16_t rr_class; - int16_t rr_type; - struct db_rrset *rr_next; -}; -#define DBHASHSIZE(s) (sizeof(struct hashbuf) + \ - (s-1) * sizeof(struct db_rrset *)) - -#define SIG_COVERS(dp) (ns_get16(dp->d_data)) - -/* - * Flags to updatedb - */ -#define DB_NODATA 0x01 /* data should not exist */ -#define DB_MEXIST 0x02 /* data must exist */ -#define DB_DELETE 0x04 /* delete data if it exists */ -#define DB_NOTAUTH 0x08 /* must not update authoritative data */ -#define DB_NOHINTS 0x10 /* don't reflect update in fcachetab */ -#define DB_PRIMING 0x20 /* is this update the result of priming? */ -#define DB_MERGE 0x40 /* make no control on rr in db_update (for ixfr) */ -#define DB_REPLACE 0x80 /* replace data if it exists */ - -#define DB_Z_CACHE 0 /* cache-zone-only db_dump() */ -#define DB_Z_ALL 65535 /* normal db_dump() */ -#define DB_Z_SPECIAL(z) ((z) == DB_Z_CACHE || (z) == DB_Z_ALL) - -/* - * Error return codes - */ -#define OK 0 -#define NONAME (-1) -#define NOCLASS (-2) -#define NOTYPE (-3) -#define NODATA (-4) -#define DATAEXISTS (-5) -#define NODBFILE (-6) -#define TOOMANYZONES (-7) -#define GOODDB (-8) -#define NEWDB (-9) -#define AUTH (-10) -#ifdef BIND_UPDATE -#define SERIAL (-11) -#endif -#define CNAMEANDOTHER (-12) -#define DNSSECFAIL (-13) /* db_set_update */ - -/* - * getnum() options - */ -#define GETNUM_NONE 0x00 /* placeholder */ -#define GETNUM_SERIAL 0x01 /* treat as serial number */ -#define GETNUM_SCALED 0x02 /* permit "k", "m" suffixes, scale result */ - -/* - * db_load() options - */ -#define ISNOTIXFR 0 -#define ISIXFR 1 -#define ISAXFRIXFR 2 - -/* - * Database access abstractions. - */ -#define foreach_rr(dp, np, ty, cl, zn) \ - for ((dp) = (np)->n_data; (dp) != NULL; (dp) = (dp)->d_next) \ - if (!match(dp, (cl), (ty))) \ - continue; \ - else if (((zn) == DB_Z_CACHE) \ - ? stale(dp) \ - : (zn) != (dp)->d_zone) \ - continue; \ - else if ((dp)->d_rcode) \ - continue; \ - else \ - /* Caller code follows in sequence. */ - -#define DRCNTINC(x) \ - do { \ - if (++((x)->d_rcnt) == 0) \ - ns_panic(ns_log_db, 1, "++d_rcnt == 0"); \ - } while (0) - -#define DRCNTDEC(x) \ - do { \ - if (((x)->d_rcnt)-- == 0) \ - ns_panic(ns_log_db, 1, "d_rcnt-- == 0"); \ - } while (0) - -#define ISVALIDGLUE(xdp) ((xdp)->d_type == T_NS || (xdp)->d_type == T_A \ - || (xdp)->d_type == T_AAAA || (xdp)->d_type == ns_t_a6) - diff --git a/contrib/bind/bin/named/db_dict.c b/contrib/bind/bin/named/db_dict.c deleted file mode 100644 index a0b89216fd658..0000000000000 --- a/contrib/bind/bin/named/db_dict.c +++ /dev/null @@ -1,111 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static char rcsid[] = "$Id: db_dict.c,v 8.1 1997/09/26 17:55:40 halley Exp $"; -#endif /* not lint */ - -/* - * Portions Copyright (c) 1997 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/param.h> -#include <sys/stat.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <assert.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" - -#define DICT_BLOCKBITS 8 -#define DICT_BLOCKSHIFT 16 -#define DICT_BLOCKMAX (1 << DICT_BLOCKBITS) -#define DICT_OFFSETBITS 16 -#define DICT_OFFSETSHIFT 0 -#define DICT_OFFSETMAX (1 << DICT_OFFSETBITS) - -#define DICT_CONSUMED(Length) ((Length) + 1) -#define DICT_INDEX(Block,Offset) (((Block) << DICT_BLOCKSHIFT) | \ - ((Offset) << DICT_OFFSETSHIFT)) - -static int dict_new(const char *, int); - -static char * blocks[DICT_BLOCKMAX]; -static int offsets[DICT_BLOCKMAX]; -static int cur_block = 0; -static int cur_offset = -1; - -int -dict_lookup(const char *text, int length, int flags) { - int block, offset, ret; - - /* XXX this is a proof of concept, some kind of hash is needed. */ - for (block = 0; block <= cur_block; block++) { - const char *cur = &blocks[block][0]; - const char *end = &blocks[block][offsets[block]]; - - while (cur < end) { - int xlength = *cur; - - if (xlength == length && - memcmp(cur+1, text, length) == 0) - return (DICT_INDEX(block, offset)); - cur += DICT_CONSUMED(length); - } - } - if ((flags & DICT_INSERT_P) != 0) - return (dict_new(text, length)); - return (-ENOENT); -} - -static int -dict_new(const char *text, int length) { - int ret; - - if (length < 0 || length > DICT_MAXLENGTH) - return (-E2BIG); - if (cur_offset + DICT_CONSUMED(length) >= DICT_OFFSETMAX) { - if (cur_block + 1 == DICT_BLOCKMAX) - return (-ENOSPC); - cur_block++; - blocks[cur_block] = memget(DICT_OFFSETMAX); - if (blocks[cur_block] == NULL) - return (-ENOMEM); - cur_offset = 0; - } - assert(cur_offset >= 0); - assert(cur_offset + DICT_CONSUMED(length) < DICT_OFFSETMAX); - ret = DICT_INDEX(cur_block, cur_offset); - blocks[cur_block][cur_offset] = length; - memcpy(&blocks[cur_block][cur_offset+1], text, length); - cur_offset += DICT_CONSUMED(length); - offsets[cur_block] = cur_offset; - return (ret); -} diff --git a/contrib/bind/bin/named/db_dump.c b/contrib/bind/bin/named/db_dump.c deleted file mode 100644 index 10acb8c11aa71..0000000000000 --- a/contrib/bind/bin/named/db_dump.c +++ /dev/null @@ -1,677 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)db_dump.c 4.33 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: db_dump.c,v 8.43 2000/04/21 06:54:01 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1988, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1995 by International Business Machines, Inc. - * - * International Business Machines, Inc. (hereinafter called IBM) grants - * permission under its copyrights to use, copy, modify, and distribute this - * Software with or without fee, provided that the above copyright notice and - * all paragraphs of this notice appear in all copies, and that the name of IBM - * not be used in connection with the marketing of any product incorporating - * the Software or modifications thereof, without specific, written prior - * permission. - * - * To the extent it has a right to do so, IBM grants an immunity from suit - * under its patents, if any, for the use, sale or manufacture of products to - * the extent that such products are used for performing Domain Name System - * dynamic updates in TCP/IP networks by means of the Software. No immunity is - * granted for any product per se or for any other function of any product. - * - * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, - * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN - * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <netdb.h> -#include <resolv.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include "port_after.h" - -#include "named.h" - -static const char *MkCredStr(int); - -/* - * Dump current data base in a format similar to RFC 883. - */ - -void -doadump() -{ - FILE *fp; - - ns_notice(ns_log_db, "dumping nameserver data"); - - if ((fp = write_open(server_options->dump_filename)) == NULL) - return; - gettime(&tt); - fprintf(fp, "; Dumped at %s", ctimel(tt.tv_sec)); - if (zones != NULL && nzones != 0) - zt_dump(fp); - if (fwddata != NULL && fwddata_count != 0) - fwd_dump(fp); - fputs( -"; Note: Cr=(auth,answer,addtnl,cache) tag only shown for non-auth RR's\n", - fp); - fputs( -"; Note: NT=milliseconds for any A RR which we've used as a nameserver\n", - fp); - fprintf(fp, "; --- Cache & Data ---\n"); - if (hashtab != NULL) - (void) db_dump(hashtab, fp, DB_Z_ALL, ""); - fprintf(fp, "; --- Hints ---\n"); - if (fcachetab != NULL) - (void) db_dump(fcachetab, fp, DB_Z_ALL, ""); - (void) my_fclose(fp); - ns_notice(ns_log_db, "finished dumping nameserver data"); -} - -int -zt_dump(FILE *fp) { - struct zoneinfo *zp; - - fprintf(fp, ";; ++zone table++\n"); - for (zp = &zones[0]; zp < &zones[nzones]; zp++) { - char *pre, buf[64]; - u_int cnt; - - if (!zp->z_origin) - continue; - - fprintf(fp, "; %s (type %d, class %d, source %s)\n", - zp->z_origin - ? (*zp->z_origin ? zp->z_origin : ".") - : "Nil", - zp->z_type, zp->z_class, - zp->z_source ? zp->z_source : "Nil"); - fprintf(fp, ";\ttime=%lu, lastupdate=%lu, serial=%u,\n", - (u_long)zp->z_time, (u_long)zp->z_lastupdate, - zp->z_serial); - fprintf(fp, ";\trefresh=%u, retry=%u, expire=%u, minimum=%u\n", - zp->z_refresh, zp->z_retry, - zp->z_expire, zp->z_minimum); - fprintf(fp, ";\tftime=%lu, xaddrcnt=%d, state=%04x, pid=%d\n", - (u_long)zp->z_ftime, zp->z_xaddrcnt, - zp->z_flags, (int)zp->z_xferpid); - sprintf(buf, ";\tz_addr[%d]: ", zp->z_addrcnt); - pre = buf; - for (cnt = 0; cnt < zp->z_addrcnt; cnt++) { - fprintf(fp, "%s[%s]", pre, inet_ntoa(zp->z_addr[cnt])); - pre = ", "; - } - if (zp->z_addrcnt) - fputc('\n', fp); - if (zp->z_axfr_src.s_addr != 0) - fprintf(fp, ";\tupdate source [%s]\n", - inet_ntoa(zp->z_axfr_src)); - } - fprintf(fp, ";; --zone table--\n"); - return (0); -} -int -fwd_dump(FILE *fp) { - int i; - fprintf(fp, ";; ++forwarders table++\n"); - for (i=0;i<fwddata_count;i++) { - fprintf(fp,"; %s rtt=%d\n", - inet_ntoa(fwddata[i]->fwdaddr.sin_addr), - fwddata[i]->nsdata->d_nstime); - } - fprintf(fp, ";; --forwarders table--\n"); - return (0); -} - -int -db_dump(struct hashbuf *htp, FILE *fp, int zone, char *origin) { - struct databuf *dp = NULL; - struct namebuf *np; - struct namebuf **npp, **nppend; - char dname[MAXDNAME]; - u_int32_t n; - int j, i, found_data, tab, printed_origin; - u_char *cp, *end; - const char *proto, *sep; - int16_t type; - u_int16_t keyflags; - u_char *sigdata, *certdata; - u_char *savecp; - char temp_base64[NS_MD5RSA_MAX_BASE64]; - - found_data = 0; - printed_origin = 0; - npp = htp->h_tab; - nppend = npp + htp->h_size; - while (npp < nppend) { - for (np = *npp++; np != NULL; np = np->n_next) { - if (np->n_data == NULL) - continue; - /* Blecch - can't tell if there is data here for the - * right zone, so can't print name yet - */ - found_data = 0; - /* we want a snapshot in time... */ - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - /* Is the data for this zone? */ - if (zone != DB_Z_ALL && dp->d_zone != zone) - continue; - /* XXX why are we not calling stale() here? */ - if (dp->d_zone == DB_Z_CACHE && - dp->d_ttl <= (u_int32_t)tt.tv_sec && - (dp->d_flags & DB_F_HINT) == 0) - continue; - if (!printed_origin) { - fprintf(fp, "$ORIGIN %s.\n", origin); - printed_origin++; - } - tab = 0; - if (dp->d_rcode == NXDOMAIN || - dp->d_rcode == NOERROR_NODATA) { - fputc(';', fp); - } else if (found_data == 0 || found_data == 1) { - found_data = 2; - } - if (found_data == 0 || found_data == 2) { - if (NAME(*np)[0] == '\0') { - if (origin[0] == '\0') - fprintf(fp, ".\t"); - else - fprintf(fp, ".%s.\t", origin); /* ??? */ - } else - fprintf(fp, "%s\t", NAME(*np)); - if (NAMELEN(*np) < (unsigned)8) - tab = 1; - found_data++; - } else { - (void) putc('\t', fp); - tab = 1; - } - if (dp->d_zone == DB_Z_CACHE) { - if (dp->d_flags & DB_F_HINT && - (int32_t)(dp->d_ttl - tt.tv_sec) - < DB_ROOT_TIMBUF) - fprintf(fp, "%d\t", DB_ROOT_TIMBUF); - else - fprintf(fp, "%d\t", - (int)(dp->d_ttl - tt.tv_sec)); - } else if (dp->d_ttl != USE_MINIMUM) - fprintf(fp, "%u\t", dp->d_ttl); - else - fprintf(fp, "%u\t", - zones[dp->d_zone].z_minimum); - fprintf(fp, "%s\t%s\t", - p_class(dp->d_class), - p_type(dp->d_type)); - cp = (u_char *)dp->d_data; - sep = "\t;"; - type = dp->d_type; - if (dp->d_rcode == NXDOMAIN || - dp->d_rcode == NOERROR_NODATA) { -#ifdef RETURNSOA - if (dp->d_size == 0) { -#endif - - fprintf(fp, "%s%s-$", - (dp->d_rcode == NXDOMAIN) - ?"NXDOMAIN" :"NODATA", - sep); - goto eoln; -#ifdef RETURNSOA - } else { - type = T_SOA; - } -#endif - } - /* - * Print type specific data - */ - /* XXX why are we not using ns_sprintrr() here? */ - switch (type) { - case T_A: - switch (dp->d_class) { - case C_IN: - case C_HS: - fputs(inet_ntoa(ina_get(cp)), fp); - break; - } - if (dp->d_nstime) { - fprintf(fp, "%sNT=%d", - sep, dp->d_nstime); - sep = " "; - } - break; - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_PTR: - fprintf(fp, "%s.", cp); - break; - - case T_NS: - cp = (u_char *)dp->d_data; - if (cp[0] == '\0') - fprintf(fp, ".\t"); - else - fprintf(fp, "%s.", cp); - break; - - case T_HINFO: - case T_ISDN: { - char buf[256]; - - if ((n = *cp++) != '\0') { - memcpy(buf, cp, n); buf[n] = '\0'; - fprintf(fp, "\"%.*s\"", (int)n, buf); - cp += n; - } else - fprintf(fp, "\"\""); - if ((n = *cp++) != '\0') { - memcpy(buf, cp, n); buf[n] = '\0'; - fprintf(fp, " \"%.*s\"", (int)n, buf); - } else - fprintf(fp, " \"\""); - break; - } - - case T_SOA: - fprintf(fp, "%s.", cp); - cp += strlen((char *)cp) + 1; - fprintf(fp, " %s. (\n", cp); -#if defined(RETURNSOA) - if (dp->d_rcode) - fputs(";", fp); -#endif - cp += strlen((char *)cp) + 1; - NS_GET32(n, cp); - fprintf(fp, "\t\t%u", n); - NS_GET32(n, cp); - fprintf(fp, " %u", n); - NS_GET32(n, cp); - fprintf(fp, " %u", n); - NS_GET32(n, cp); - fprintf(fp, " %u", n); - NS_GET32(n, cp); - fprintf(fp, " %u )", n); -#if defined(RETURNSOA) - if (dp->d_rcode) { - fprintf(fp,";%s.;%s%s-$",cp, - (dp->d_rcode == NXDOMAIN) ? - "NXDOMAIN" : "NODATA", - sep); - } -#endif - break; - - case T_MX: - case T_AFSDB: - case T_RT: - NS_GET16(n, cp); - fprintf(fp, "%u", n); - fprintf(fp, " %s.", cp); - break; - - case T_PX: - NS_GET16(n, cp); - fprintf(fp, "%u", n); - fprintf(fp, " %s.", cp); - cp += strlen((char *)cp) + 1; - fprintf(fp, " %s.", cp); - break; - - case T_X25: - if ((n = *cp++) != '\0') - fprintf(fp, " \"%.*s\"", (int)n, cp); - else - fprintf(fp, " \"\""); - break; - - case T_TXT: - end = (u_char *)dp->d_data + dp->d_size; - while (cp < end) { - (void) putc('"', fp); - if ((n = *cp++) != '\0') { - for (j = n ; j > 0 && cp < end ; j--) { - if (*cp == '\n' || *cp == '"' || *cp == '\\') - (void) putc('\\', fp); - (void) putc(*cp++, fp); - } - } - (void) putc('"', fp); - if (cp < end) - (void) putc(' ', fp); - } - break; - - case T_NSAP: - (void) fputs(inet_nsap_ntoa(dp->d_size, - dp->d_data, NULL), - fp); - break; - - case T_AAAA: { - char t[sizeof - "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255" - ]; - - (void) fputs(inet_ntop(AF_INET6, dp->d_data, - t, sizeof t), - fp); - break; - } - - case T_LOC: { - char t[256]; - - (void) fputs(loc_ntoa(dp->d_data, t), fp); - break; - } - - case T_NAPTR: { - u_int32_t order, preference; - - NS_GET16(order, cp); - fprintf(fp, "%u", order); - - NS_GET16(preference, cp); - fprintf(fp, "%u", preference); - - if ((n = *cp++) != 0) { - fprintf(fp, "\"%.*s\"", (int)n, cp); - cp += n; - } - if ((n = *cp++) != 0) { - fprintf(fp, "\"%.*s\"", (int)n, cp); - cp += n; - } - if ((n = *cp++) != 0) { - fprintf(fp, " \"%.*s\"", (int)n, cp); - cp += n; - } - fprintf(fp, " %s.", cp); - - break; - } - - case T_SRV: { - u_int priority, weight, port; - - NS_GET16(priority, cp); - NS_GET16(weight, cp); - NS_GET16(port, cp); - fprintf(fp, "\t%u %u %u %s.", - priority, weight, port, cp); - break; - } - - case T_WKS: - fputs(inet_ntoa(ina_get(cp)), fp); - cp += INADDRSZ; - proto = protocolname(*cp); - cp += sizeof(char); - fprintf(fp, " %s ", proto); - i = 0; - while(cp < (u_char *)dp->d_data + dp->d_size) { - j = *cp++; - do { - if (j & 0200) - fprintf(fp, " %s", - servicename(i, proto)); - j <<= 1; - } while (++i & 07); - } - break; - - case T_MINFO: - case T_RP: - fprintf(fp, "%s.", cp); - cp += strlen((char *)cp) + 1; - fprintf(fp, " %s.", cp); - break; - - case T_KEY: - savecp = cp; /* save the beginning */ - /*>>> Flags (unsigned_16) */ - NS_GET16(keyflags,cp); - fprintf(fp, "0x%04x ", keyflags); - /*>>> Protocol (8-bit decimal) */ - fprintf(fp, "%3u ", *cp++); - /*>>> Algorithm id (8-bit decimal) */ - fprintf(fp, "%3u ", *cp++); - - /*>>> Public-Key Data (multidigit BASE64) */ - /* containing ExponentLen, Exponent, and Modulus */ - i = b64_ntop(cp, dp->d_size - (cp - savecp), - temp_base64, - sizeof temp_base64); - if (i < 0) - fprintf(fp, "; BAD BASE64"); - else - fprintf(fp, "%s", temp_base64); - break; - - case T_SIG: - sigdata = cp; - /* RRtype (char *) */ - NS_GET16(n,cp); - fprintf(fp, "%s ", p_type(n)); - /* Algorithm id (8-bit decimal) */ - fprintf(fp, "%d ", *cp++); - /* Labels (8-bit decimal) */ - fprintf(fp, "%d ", *cp++); - /* OTTL (u_long) */ - NS_GET32(n, cp); - fprintf(fp, "%u ", n); - /* Texp (u_long) */ - NS_GET32(n, cp); - fprintf(fp, "%s ", p_secstodate (n)); - /* Tsig (u_long) */ - NS_GET32(n, cp); - fprintf(fp, "%s ", p_secstodate (n)); - /* Kfootprint (unsigned_16) */ - NS_GET16(n, cp); - fprintf(fp, "%u ", n); - /* Signer's Name (char *) */ - fprintf(fp, "%s ", cp); - cp += strlen((char *)cp) + 1; - /* Signature (base64 of any length) */ - i = b64_ntop(cp, dp->d_size - (cp - sigdata), - temp_base64, - sizeof temp_base64); - if (i < 0) - fprintf(fp, "; BAD BASE64"); - else - fprintf(fp, "%s", temp_base64); - break; - - case T_NXT: - fprintf(fp, "%s.", cp); - n = strlen ((char *)cp) + 1; - cp += n; - i = 8 * (dp->d_size - n); /* How many bits? */ - for (n = 0; n < (u_int32_t)i; n++) { - if (NS_NXT_BIT_ISSET(n, cp)) - fprintf(fp," %s", p_type(n)); - } - break; - - case ns_t_cert: - certdata = cp; - NS_GET16(n,cp); - fprintf(fp, "%d ", n); /* cert type */ - - NS_GET16(n,cp); - fprintf(fp, "%d %d ", n, *cp++); /* tag & alg */ - - /* Certificate (base64 of any length) */ - i = b64_ntop(cp, - dp->d_size - (cp - certdata), - temp_base64, sizeof(temp_base64)); - if (i < 0) - fprintf(fp, "; BAD BASE64"); - else - fprintf(fp, "%s", temp_base64); - break; - - default: - fprintf(fp, "%s?d_type=%d?", - sep, dp->d_type); - sep = " "; - } - if (dp->d_cred < DB_C_ZONE) { - fprintf(fp, "%sCr=%s", - sep, MkCredStr(dp->d_cred)); - sep = " "; - } else { - fprintf(fp, "%sCl=%d", - sep, dp->d_clev); - sep = " "; - } - if ((dp->d_flags & DB_F_LAME) != 0) { - time_t when; - getname(np, dname, sizeof(dname)); - when = db_lame_find(dname, dp); - if (when != 0 && when > tt.tv_sec) { - fprintf(fp, "%sLAME=%d", - sep, when - tt.tv_sec); - sep = " "; - } - } - - eoln: - if (dp->d_ns != NULL){ - fprintf(fp, "%s[%s]", - sep, inet_ntoa(dp->d_ns->addr)); - sep = " "; - } - putc('\n', fp); - } - } - } - if (ferror(fp)) - return (NODBFILE); - - npp = htp->h_tab; - nppend = npp + htp->h_size; - while (npp < nppend) { - for (np = *npp++; np != NULL; np = np->n_next) { - if (np->n_hash == NULL) - continue; - getname(np, dname, sizeof(dname)); - if (db_dump(np->n_hash, fp, zone, dname) == NODBFILE) - return (NODBFILE); - } - } - return (OK); -} - -static const char * -MkCredStr(int cred) { - static char badness[20]; - - switch (cred) { - case DB_C_ZONE: return "zone"; - case DB_C_AUTH: return "auth"; - case DB_C_ANSWER: return "answer"; - case DB_C_ADDITIONAL: return "addtnl"; - case DB_C_CACHE: return "cache"; - default: break; - } - sprintf(badness, "?%d?", cred); - return (badness); -} diff --git a/contrib/bind/bin/named/db_func.h b/contrib/bind/bin/named/db_func.h deleted file mode 100644 index cb83beb1ea510..0000000000000 --- a/contrib/bind/bin/named/db_func.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 1985, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Check Point Software Technologies Incorporated not be used - * in advertising or publicity pertaining to distribution of the document - * or software without specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND CHECK POINT SOFTWARE TECHNOLOGIES - * INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL CHECK POINT SOFTWARE TECHNOLOGIES INCORPRATED - * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* db_proc.h - prototypes for functions in db_*.c - * - * $Id: db_func.h,v 8.42 2000/04/21 06:54:02 vixie Exp $ - */ - -/* ++from db_update.c++ */ -extern int db_update(const char *name, - struct databuf *odp, - struct databuf *newdp, - struct databuf **savedpp, - int flags, - struct hashbuf *htp, - struct sockaddr_in from), - db_cmp(const struct databuf *, const struct databuf *), - findMyZone(struct namebuf *np, int class); -void fixttl(struct databuf *dp); -/* --from db_update.c-- */ - -/* ++from db_save.c++ */ -extern struct namebuf *savename(const char *, int); -extern struct databuf *savedata(int, int, u_int32_t, u_char *, int); -extern struct hashbuf *savehash(struct hashbuf *); -/* --from db_save.c-- */ - -/* ++from db_dump.c++ */ -extern int db_dump(struct hashbuf *, FILE *, int, char *), - zt_dump(FILE *); -extern void doadump(void); -/* --from db_dump.c-- */ - -/* ++from db_load.c++ */ -extern int makename_ok(char *name, const char *origin, int class, - struct zoneinfo *zp, - enum transport transport, - enum context context, - const char *owner, const char *filename, - int lineno, int size); -extern void endline(FILE *); -extern int getword(char *, size_t, FILE *, int), - getttl(FILE *, const char *, int, u_int32_t *, int *), - getnum(FILE *, const char *, int), - db_load(const char *, const char *, struct zoneinfo *, - const char *, int); -extern int getnonblank(FILE *, const char *), - getservices(int, char *, FILE *, const char *); -extern char getprotocol(FILE *, const char *); -extern int makename(char *, const char *, int); -extern void db_err(int, char *, int, const char *, int); -extern int parse_sec_rdata(char *inp, int inp_len, int inp_full, - u_char *data, int data_len, - FILE *fp, struct zoneinfo *zp, - char *domain, u_int32_t ttl, - int type, enum context context, - enum transport transport, - char **errmsg); -/* --from db_load.c-- */ - -/* ++from db_glue.c++ */ -extern void buildservicelist(void), - destroyservicelist(void), - buildprotolist(void), - destroyprotolist(void), - getname(struct namebuf *, char *, int); -extern int servicenumber(const char *), - protocolnumber(const char *), - get_class(const char *); -extern u_int nhash(const char *); -extern const char *protocolname(int), - *servicename(u_int16_t, const char *); -#ifndef BSD -extern int getdtablesize(void); -#endif -extern struct databuf *rm_datum(struct databuf *, - struct namebuf *, - struct databuf *, - struct databuf **); -extern struct namebuf *rm_name(struct namebuf *, - struct namebuf **, - struct namebuf *); -extern void rm_hash(struct hashbuf *); -extern void db_freedata(struct databuf *); -extern void db_lame_add(char *zone, char *server, time_t when); -extern time_t db_lame_find(char *zone, struct databuf *dp); -extern void db_lame_clean(void); -extern void db_lame_destroy(void); -/* --from db_glue.c-- */ - -/* ++from db_lookup.c++ */ -extern struct namebuf *nlookup(const char *, struct hashbuf **, - const char **, int); -extern struct namebuf *np_parent __P((struct namebuf *)); -extern int match(struct databuf *, int, int), - nxtmatch(const char *, struct databuf *, - struct databuf *), - rrmatch(const char *, struct databuf *, - struct databuf *); -/* --from db_lookup.c-- */ - -/* ++from db_ixfr.c++ */ -extern ns_deltalist * ixfr_get_change_list(struct zoneinfo *, u_int32_t, - u_int32_t); -int ixfr_have_log(struct zoneinfo *, u_int32_t, - u_int32_t); -/* --from db_ixfr.c++ */ - -/* ++from db_sec.c++ */ -int add_trusted_key(const char *name, const int flags, - const int proto, const int alg, - const char *str); -int db_set_update(char *name, struct databuf *dp, - void **state, int flags, - struct hashbuf **htp, - struct sockaddr_in from, - int *rrcount, int line, - const char *file); -/* --from db_sec.c-- */ -/* ++from db_tsig.c++ */ -char * tsig_alg_name(int value); -int tsig_alg_value(char *name); -struct dst_key * tsig_key_from_addr(struct in_addr addr); -struct tsig_record * new_tsig(struct dst_key *key, u_char *sig, int siglen); -void free_tsig(struct tsig_record *tsig); -/* --from db_tsig.c-- */ diff --git a/contrib/bind/bin/named/db_glob.h b/contrib/bind/bin/named/db_glob.h deleted file mode 100644 index cfd7abb3696ba..0000000000000 --- a/contrib/bind/bin/named/db_glob.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * from db.h 4.16 (Berkeley) 6/1/90 - * $Id: db_glob.h,v 8.14 2000/04/21 06:54:02 vixie Exp $ - */ - -/* - * Copyright (c) 1985, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Global variables for data base routines. - */ - - /* ONE_WEEK maximum ttl */ -DECL u_int max_cache_ttl INIT(7*24*60*60); - - /* no minimum ttl */ -DECL u_int min_cache_ttl INIT(0); - - /* current line number */ -DECL int lineno INIT(0); - - /* root hash table */ -DECL struct hashbuf *hashtab INIT(NULL); - - /* hash table of cache read from file */ -DECL struct hashbuf *fcachetab INIT(NULL); - - /* state of ns_reload() and ns_reconfig(). */ -DECL int reloading INIT(0); -DECL int reconfiging INIT(0); -DECL int noexpired INIT(0); - -DECL const int hashsizes[] -#ifdef MAIN_PROGRAM - = { 2, 11, 113, 337, 977, 2053, 4073, 8011, 16001, 99887, 0 } -#endif - ; diff --git a/contrib/bind/bin/named/db_glue.c b/contrib/bind/bin/named/db_glue.c deleted file mode 100644 index 8c484654af69f..0000000000000 --- a/contrib/bind/bin/named/db_glue.c +++ /dev/null @@ -1,656 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)db_glue.c 4.4 (Berkeley) 6/1/90"; -static const char rcsid[] = "$Id: db_glue.c,v 8.40 2000/04/21 06:54:02 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1988 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <ctype.h> -#include <errno.h> -#include <netdb.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" - -struct valuelist { - struct valuelist * next; - struct valuelist * prev; - char * name; - char * proto; - int port; -}; -static struct valuelist *servicelist, *protolist; - -void -buildservicelist() { - struct servent *sp; - struct valuelist *slp; - -#ifdef MAYBE_HESIOD - setservent(0); -#else - setservent(1); -#endif - while ((sp = getservent()) != NULL) { - slp = (struct valuelist *)memget(sizeof(struct valuelist)); - if (!slp) - panic("memget(servent)", NULL); - slp->name = savestr(sp->s_name, 1); - slp->proto = savestr(sp->s_proto, 1); - slp->port = ntohs((u_int16_t)sp->s_port); /* host byt order */ - slp->next = servicelist; - slp->prev = NULL; - if (servicelist) - servicelist->prev = slp; - servicelist = slp; - } - endservent(); -} - -void -destroyservicelist() { - struct valuelist *slp, *slp_next; - - for (slp = servicelist; slp != NULL; slp = slp_next) { - slp_next = slp->next; - freestr(slp->name); - freestr(slp->proto); - memput(slp, sizeof *slp); - } - servicelist = NULL; -} - -void -buildprotolist() { - struct protoent *pp; - struct valuelist *slp; - -#ifdef MAYBE_HESIOD - setprotoent(0); -#else - setprotoent(1); -#endif - while ((pp = getprotoent()) != NULL) { - slp = (struct valuelist *)memget(sizeof(struct valuelist)); - if (!slp) - panic("memget(protoent)", NULL); - slp->name = savestr(pp->p_name, 1); - slp->port = pp->p_proto; /* host byte order */ - slp->next = protolist; - slp->prev = NULL; - if (protolist) - protolist->prev = slp; - protolist = slp; - } - endprotoent(); -} - -void -destroyprotolist() { - struct valuelist *plp, *plp_next; - - for (plp = protolist; plp != NULL; plp = plp_next) { - plp_next = plp->next; - freestr(plp->name); - memput(plp, sizeof *plp); - } - protolist = NULL; -} - -static int -findservice(const char *s, struct valuelist **list) { - struct valuelist *lp = *list; - int n; - - for (; lp != NULL; lp = lp->next) - if (strcasecmp(lp->name, s) == 0) { - if (lp != *list) { - lp->prev->next = lp->next; - if (lp->next) - lp->next->prev = lp->prev; - (*list)->prev = lp; - lp->next = *list; - *list = lp; - } - return (lp->port); /* host byte order */ - } - if (sscanf(s, "%d", &n) != 1 || n <= 0) - n = -1; - return (n); -} - -/* - * Convert service name or (ascii) number to int. - */ -int -servicenumber(const char *p) { - return (findservice(p, &servicelist)); -} - -/* - * Convert protocol name or (ascii) number to int. - */ -int -protocolnumber(const char *p) { - return (findservice(p, &protolist)); -} - -static struct servent * -cgetservbyport(u_int16_t port, const char *proto) { /* Host byte order. */ - struct valuelist **list = &servicelist; - struct valuelist *lp = *list; - static struct servent serv; - - port = ntohs(port); - for (; lp != NULL; lp = lp->next) { - if (port != (u_int16_t)lp->port) /* Host byte order. */ - continue; - if (strcasecmp(lp->proto, proto) == 0) { - if (lp != *list) { - lp->prev->next = lp->next; - if (lp->next) - lp->next->prev = lp->prev; - (*list)->prev = lp; - lp->next = *list; - *list = lp; - } - serv.s_name = lp->name; - serv.s_port = htons((u_int16_t)lp->port); - serv.s_proto = lp->proto; - return (&serv); - } - } - return (0); -} - -static struct protoent * -cgetprotobynumber(int proto) { /* Host byte order. */ - struct valuelist **list = &protolist; - struct valuelist *lp = *list; - static struct protoent prot; - - for (; lp != NULL; lp = lp->next) - if (lp->port == proto) { /* Host byte order. */ - if (lp != *list) { - lp->prev->next = lp->next; - if (lp->next) - lp->next->prev = lp->prev; - (*list)->prev = lp; - lp->next = *list; - *list = lp; - } - prot.p_name = lp->name; - prot.p_proto = lp->port; /* Host byte order. */ - return (&prot); - } - return (0); -} - -const char * -protocolname(int num) { - static char number[8]; - struct protoent *pp; - - pp = cgetprotobynumber(num); - if (pp == 0) { - (void) sprintf(number, "%d", num); - return (number); - } - return (pp->p_name); -} - -const char * -servicename(u_int16_t port, const char *proto) { /* Host byte order. */ - static char number[8]; - struct servent *ss; - - ss = cgetservbyport(htons(port), proto); - if (ss == 0) { - (void) sprintf(number, "%d", port); - return (number); - } - return (ss->s_name); -} - -static struct map map_class[] = { - { "in", C_IN }, - { "chaos", C_CHAOS }, - { "hs", C_HS }, - { NULL, 0 } -}; - -int -get_class(const char *class) { - const struct map *mp; - - if (isdigit(*class)) - return (atoi(class)); - for (mp = map_class; mp->token != NULL; mp++) - if (strcasecmp(class, mp->token) == 0) - return (mp->val); - return (C_IN); -} - -/* rm_datum(dp, np, pdp, savedpp) - * remove datum 'dp' from name 'np'. pdp is previous data pointer. - * if savedpp is not NULL, and compiled with BIND_UPDATE, save - * datum dp there rather than freeing the memory (caller will take - * care of freeing it) - * return value: - * "next" field from removed datum, suitable for relinking - */ -struct databuf * -rm_datum(struct databuf *dp, struct namebuf *np, struct databuf *pdp, - struct databuf **savedpp) { - struct databuf *ndp = dp->d_next; - - ns_debug(ns_log_db, 3, "rm_datum(%lx, %lx, %lx, %lx) -> %lx", - (u_long)dp, (u_long)np->n_data, (u_long)pdp, - (u_long)savedpp, (u_long)ndp); - if ((dp->d_flags & DB_F_ACTIVE) == 0) - panic("rm_datum: DB_F_ACTIVE not set", NULL); - if (pdp == NULL) - np->n_data = ndp; - else - pdp->d_next = ndp; -#ifdef BIND_UPDATE - if (savedpp != NULL) { - /* mark deleted or pending deletion */ - dp->d_mark |= D_MARK_DELETED; - dp->d_next = *savedpp; - *savedpp = dp; - } else - dp->d_next = NULL; -#else - dp->d_next = NULL; -#endif - dp->d_flags &= ~DB_F_ACTIVE; - DRCNTDEC(dp); - if (dp->d_rcnt) { -#ifdef DEBUG - int32_t ii; -#endif - - switch(dp->d_type) { - case T_NS: - ns_debug(ns_log_db, 3, "rm_datum: %s rcnt = %d", - dp->d_data, dp->d_rcnt); - break; -#ifdef DEBUG - case T_A: - memcpy(&ii, dp->d_data, sizeof ii); - ns_debug(ns_log_db, 3, - "rm_datum: %08.8X rcnt = %d", - ii, dp->d_rcnt); - break; -#endif - default: - ns_debug(ns_log_db, 3, - "rm_datum: rcnt = %d", dp->d_rcnt); - } - } else -#ifdef BIND_UPDATE - if (savedpp == NULL) -#endif - db_freedata(dp); - return (ndp); -} - -/* rm_name(np, he, pnp) - * remove name 'np' from parent 'pp'. pnp is previous name pointer. - * return value: - * "next" field from removed name, suitable for relinking. - */ -struct namebuf * -rm_name(struct namebuf *np, struct namebuf **pp, struct namebuf *pnp) { - struct namebuf *nnp = np->n_next; - const char *msg; - - /* verify */ - if ( (np->n_data && (msg = "data")) - || (np->n_hash && (msg = "hash")) - ) { - ns_panic(ns_log_db, 1, "rm_name(%#x(%s)): non-nil %s pointer", - np, NAME(*np), msg); - } - - /* unlink */ - if (pnp) - pnp->n_next = nnp; - else - *pp = nnp; - - /* deallocate */ - memput(np, NAMESIZE(NAMELEN(*np))); - - /* done */ - return (nnp); -} - -void -rm_hash(struct hashbuf *htp) { - REQUIRE(htp != NULL); - REQUIRE(htp->h_cnt == 0); - - memput(htp, HASHSIZE(htp->h_size)); -} - -/* - * Get the domain name of 'np' and put in 'buf'. Bounds checking is done. - */ -void -getname(struct namebuf *np, char *buf, int buflen) { - char *cp; - int i; - - cp = buf; - while (np != NULL) { - i = (int) NAMELEN(*np); - if (i + 1 >= buflen) { - *cp = '\0'; - ns_info(ns_log_db, - "domain name too long: %s...", buf); - strcpy(buf, "Name_Too_Long"); - return; - } - if (cp != buf) - *cp++ = '.'; - memcpy(cp, NAME(*np), i); - cp += i; - buflen -= i + 1; - np = np->n_parent; - } - *cp = '\0'; -} - -/* u_int - * nhash(name) - * compute hash for this name and return it; ignore case differences - * note: - * this logic is intended to produce the same result as nlookup()'s. - */ -u_int -nhash(const char *name) { - u_char ch; - u_int hval; - - hval = 0; - while ((ch = (u_char)*name++) != (u_char)'\0') - HASHIMILATE(hval, ch); - return (hval); -} - -void -db_freedata(struct databuf *dp) { - int bytes = DATASIZE(dp->d_size); - - if (dp->d_rcnt != 0) - panic("db_freedata: d_rcnt != 0", NULL); - if ((dp->d_flags & (DB_F_ACTIVE|DB_F_FREE)) != 0) - panic("db_freedata: %s set", - (dp->d_flags & DB_F_FREE) != 0 ? "DB_F_FREE" : - "DB_F_ACTIVE"); - if (dp->d_next != NULL) - panic("db_free: d_next != NULL", NULL); - dp->d_flags |= DB_F_FREE; - memput(dp, bytes); -} - -struct lame_hash { - struct lame_hash *next; - char *zone; - char *server; - time_t when; - unsigned int hval; -} **lame_hash = NULL; - -static int lame_hash_size = 0; -static int lame_hash_cnt = 0; - -void -db_lame_add(char *zone, char *server, time_t when) { - unsigned int hval = nhash(zone); - struct lame_hash *last, *this; - struct lame_hash **new; - int n; - int newsize; - - db_lame_clean(); - - /* grow / initalise hash table */ - if (lame_hash_cnt >= lame_hash_size) { - if (lame_hash_size == 0) - newsize = hashsizes[0]; - else { - for (n = 0; (newsize = hashsizes[n++]) != 0; (void)NULL) - if (lame_hash_size == newsize) { - newsize = hashsizes[n]; - break; - } - if (newsize == 0) - newsize = lame_hash_size * 2 + 1; - } - new = memget(newsize * sizeof this); - if (new == NULL) - return; - memset(new, 0, newsize * sizeof this); - for (n = 0 ; n < lame_hash_size; n++) { - this = lame_hash[n]; - while (this) { - last = this; - this = this->next; - last->next = new[hval%newsize]; - new[hval%newsize] = last; - } - } - if (lame_hash != NULL) - memput(lame_hash, lame_hash_size * sizeof this); - lame_hash = new; - lame_hash_size = newsize; - } - - last = NULL; - this = lame_hash[hval%lame_hash_size]; - while (this) { - if ((ns_samename(this->server, server) == 1) && - (ns_samename(this->zone, zone) == 1)) { - this->when = when; - return; - } - last = this; - this = this->next; - } - this = memget(sizeof *this); - if (this == NULL) - return; - this->server = savestr(server, 0); - this->zone = savestr(zone, 0); - if (this->server == NULL || this->zone == NULL) { - if (this->server != NULL) - freestr(this->server); - if (this->zone != NULL) - freestr(this->zone); - memput(this, sizeof *this); - return; - } - this->when = when; - this->hval = hval; - this->next = NULL; - if (last != NULL) - last->next = this; - else - lame_hash[hval%lame_hash_size] = this; - lame_hash_cnt++; -} - -time_t -db_lame_find(char *zone, struct databuf *dp) { - unsigned int hval = nhash(zone); - struct lame_hash *this; - - if (lame_hash_size == 0) { - /* db_lame_destroy() must have been called. */ - dp->d_flags &= ~DB_F_LAME; - return (0); - } - - db_lame_clean(); /* Remove expired record so that we can - * clear DB_F_LAME when there are no - * additions. */ - - this = lame_hash[hval % lame_hash_size]; - while (this) { - if ((ns_samename(this->server, (char*)dp->d_data) == 1) && - (ns_samename(this->zone, zone) == 1)) - return (this->when); - this = this->next; - } - dp->d_flags &= ~DB_F_LAME; - return (0); -} - -void -db_lame_clean(void) { - int i; - struct lame_hash *last, *this; - - for (i = 0 ; i < lame_hash_size; i++) { - last = NULL; - this = lame_hash[i]; - while (this != NULL) { - if (this->when < tt.tv_sec) { - freestr(this->zone); - freestr(this->server); - if (last != NULL) { - last->next = this->next; - memput(this, sizeof *this); - this = last->next; - } else { - lame_hash[i] = this->next; - memput(this, sizeof *this); - this = lame_hash[i]; - } - lame_hash_cnt--; - } else { - last = this; - this = this->next; - } - } - } -} - -void -db_lame_destroy(void) { - int i; - struct lame_hash *last, *this; - - if (lame_hash_size == 0) - return; - - for (i = 0 ; i < lame_hash_size; i++) { - this = lame_hash[i]; - while (this != NULL) { - last = this; - this = this->next; - freestr(last->zone); - freestr(last->server); - memput(last, sizeof *this); - } - } - memput(lame_hash, lame_hash_size * sizeof this); - lame_hash_cnt = 0; - lame_hash_size = 0; - lame_hash = NULL; -} diff --git a/contrib/bind/bin/named/db_ixfr.c b/contrib/bind/bin/named/db_ixfr.c deleted file mode 100644 index 7a50618f2ff91..0000000000000 --- a/contrib/bind/bin/named/db_ixfr.c +++ /dev/null @@ -1,925 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static char rcsid[] = "$Id: db_ixfr.c,v 8.20 2000/02/29 05:15:03 vixie Exp $"; -#endif - -/* - * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Check Point Software Technologies Incorporated not be used - * in advertising or publicity pertaining to distribution of the document - * or software without specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND CHECK POINT SOFTWARE TECHNOLOGIES - * INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL CHECK POINT SOFTWARE TECHNOLOGIES INCORPRATED - * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Manage ixfr transaction log - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <netdb.h> -#include <resolv.h> -#include <res_update.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" - -#define DBIXFR_ERROR (-1) -#define DBIXFR_FOUND_RR 2 -#define DBIXFR_END 3 - -static int ixfr_getdelta(struct zoneinfo *, FILE *, const char *, char *, - ns_updque *, u_int32_t *, u_int32_t *); - -ns_deltalist * -ixfr_get_change_list(struct zoneinfo *zp, - u_int32_t from_serial, u_int32_t to_serial) -{ - FILE * fp = NULL; - u_int32_t old_serial, new_serial; - char origin[MAXDNAME]; - ns_deltalist *dlhead = NULL; - int ret; - ns_updrec *uprec; - ns_delta *dl; - - if (SEQ_GT(from_serial, to_serial)) - return (NULL); - - dlhead = memget(sizeof(*dlhead)); - if (dlhead == NULL) - return (NULL); - INIT_LIST(*dlhead); - - if ((fp = fopen(zp->z_ixfr_base, "r")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - goto cleanup; - } - strcpy(origin, zp->z_origin); - lineno = 1; - old_serial = new_serial = 0; - - for (;;) { - dl = memget(sizeof *dl); - if (dl == NULL) { - ns_warning(ns_log_db, - "ixfr_get_change_list: out of memory"); - goto cleanup; - } - INIT_LINK(dl, d_link); - INIT_LIST(dl->d_changes); - ret = ixfr_getdelta(zp, fp, zp->z_ixfr_base, origin, &dl->d_changes, - &old_serial, &new_serial); - switch (ret) { - case DBIXFR_ERROR: - ns_warning(ns_log_db, "Logical error in %s: unlinking", - zp->z_ixfr_base); - unlink(zp->z_ixfr_base); - goto cleanup; - - case DBIXFR_FOUND_RR: - ns_debug(ns_log_default, 4, "ixfr_getdelta DBIXFR_FOUND_RR (%s)", - zp->z_origin); - if (EMPTY(*dlhead)) { - /* skip updates prior to the one we want */ - uprec = HEAD(dl->d_changes); - INSIST(uprec != NULL); - if ((uprec->r_zone < from_serial) || - (uprec->r_zone > to_serial)) - { - while ((uprec = HEAD(dl->d_changes)) != NULL) { - UNLINK(dl->d_changes, uprec, r_link); - - if (uprec->r_dp != NULL) - db_freedata(uprec->r_dp); - uprec->r_dp = NULL; - res_freeupdrec(uprec); - } - memput(dl, sizeof *dl); - break; - } - else if (uprec->r_zone > from_serial) { - /* missed the boat */ - ns_debug(ns_log_default, 3, - "ixfr_getdelta first SOA is %d, asked for %d (%s)", - uprec->r_zone, - from_serial, - zp->z_origin); - goto cleanup; - } - } - ns_debug(ns_log_default, 4, - "adding to change list (%s)", - zp->z_origin); - APPEND(*dlhead, dl, d_link); - break; - - case DBIXFR_END: - ns_debug(ns_log_default, 4, - "ixfr_getdelta DBIXFR_END (%s)", - zp->z_origin); - (void) my_fclose(fp); - memput(dl, sizeof *dl); - return (dlhead); - - default: - (void) my_fclose(fp); - if (dl != NULL) - memput(dl, sizeof *dl); - return (NULL); - } - } - - cleanup: - if (fp != NULL) - (void) my_fclose(fp); - - while ((dl = HEAD(*dlhead)) != NULL) { - UNLINK(*dlhead, dl, d_link); - while ((uprec = HEAD(dl->d_changes)) != NULL) { - UNLINK(dl->d_changes, uprec, r_link); - - if (uprec->r_dp != NULL) - db_freedata(uprec->r_dp); - uprec->r_dp = NULL; - res_freeupdrec(uprec); - } - memput(dl, sizeof *dl); - } - memput(dlhead, sizeof *dlhead); - return (NULL); -} - -/* - * int ixfr_have_log(struct zoneinfo *zp,u_int32_t from_serial, - * u_int32_t to_serial) - * - * verify that ixfr transaction log contains changes - * from from_serial to to_serial - * - * returns: - * 0 = serial number is up to date - * 1 = transmission is possible - * -1 = error while opening the ixfr transaction log - * -2 = error in parameters - * -3 = logical error in the history file - */ -int -ixfr_have_log(struct zoneinfo *zp, u_int32_t from_serial, u_int32_t to_serial) -{ - FILE *fp; - u_int32_t old_serial = 0, new_serial = 0; - u_int32_t last_serial = 0; - u_int32_t first_serial = 0; - char buf[BUFSIZ]; - char *cp; - struct stat st; - int nonempty_lineno = -1, prev_pktdone = 0, cont = 0, - inside_next = 0; - int err; - int first = 0; - int rval = 0; - int id, rcode = NOERROR; - if (SEQ_GT(from_serial, to_serial)) - return (-2); - if (from_serial == to_serial) - return (0); - /* If there is no log file, just return. */ - if (zp->z_ixfr_base == NULL || zp->z_updatelog == NULL) - return (-1); - if (zp->z_serial_ixfr_start > 0) { - if (from_serial >= zp->z_serial_ixfr_start) - return (1); - } - if (stat(zp->z_ixfr_base, &st) < 0) { - if (errno != ENOENT) - ns_error(ns_log_db, - "unexpected stat(%s) failure: %s", - zp->z_ixfr_base, strerror(errno)); - return (-1); - } - if ((fp = fopen(zp->z_ixfr_base, "r")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - return (-1); - } - if (fgets(buf, sizeof(buf), fp) == NULL) { - ns_error(ns_log_update, "fgets() from %s failed: %s", - zp->z_ixfr_base, strerror(errno)); - fclose(fp); - return (-1); - } - if (strcmp(buf, LogSignature) != 0) { - ns_error(ns_log_update, "invalid log file %s", - zp->z_ixfr_base); - fclose(fp); - return (-3); - } - lineno = 1; - first = 1; - for (;;) { - if (getword(buf, sizeof buf, fp, 0)) { - nonempty_lineno = lineno; - } else { - if (lineno == (nonempty_lineno + 1)) - continue; - inside_next = 0; - prev_pktdone = 1; - cont = 1; - } - if (!strcasecmp(buf, "[DYNAMIC_UPDATE]") || - !strcasecmp(buf, "[IXFR_UPDATE]")) { - err = 0; - rcode = NOERROR; - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || !sscanf((char *) cp, "id %d", &id)) - id = -1; - inside_next = 1; - prev_pktdone = 1; - cont = 1; - } else if (!strcasecmp(buf, "serial")) { - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (sscanf((char *) cp, "%u", &old_serial)) { - if (first == 1) { - first = 0; - first_serial = old_serial; - } - last_serial = old_serial; - if (from_serial >= old_serial) { - rval = 1; - } - } - prev_pktdone = 1; - cont = 1; - } else if (!strcasecmp(buf, "[INCR_SERIAL]")) { - /* XXXRTH not enough error checking here */ - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || - sscanf((char *) cp, "from %u to %u", - &old_serial, &new_serial) != 2) { - rval = -3; - break; - } else if (from_serial >= old_serial) { - if (first == 1) { - first = 0; - first_serial = old_serial; - } - last_serial = old_serial; - rval = 1; - } - } - if (prev_pktdone) { - prev_pktdone = 0; - if (feof(fp)) - break; - } - } - fclose(fp); - if (last_serial +1 < zp->z_serial) { - ns_warning(ns_log_db, - "%s: File Deleted. Found gap between serial:" - " %d and current serial: %d", - zp->z_ixfr_base, last_serial, zp->z_serial); - (void) unlink(zp->z_ixfr_base); - rval = -3; - } - if (from_serial < first_serial || from_serial > last_serial) - rval = -3; - if (rval == 1) - zp->z_serial_ixfr_start = first_serial; - return (rval); -} - -/* from db_load.c */ - -static struct map m_section[] = { - {"zone", S_ZONE}, - {"prereq", S_PREREQ}, - {"update", S_UPDATE}, - {"reserved", S_ADDT}, -}; -#define M_SECTION_CNT (sizeof(m_section) / sizeof(struct map)) - -/* from ns_req.c */ - -static struct map m_opcode[] = { - {"nxdomain", NXDOMAIN}, - {"yxdomain", YXDOMAIN}, - {"nxrrset", NXRRSET}, - {"yxrrset", YXRRSET}, - {"delete", DELETE}, - {"add", ADD}, -}; -#define M_OPCODE_CNT (sizeof(m_opcode) / sizeof(struct map)) - -/* XXXRTH workaround map difficulties */ -#define M_CLASS_CNT m_class_cnt -#define M_TYPE_CNT m_type_cnt - -/* - * read a line from the history of a zone. - * - * returns: - * - * DBIXFR_ERROR = an error occured - * DBIXFR_FOUND_RR = a rr encountered - * DBIXFR_END = end of file - */ -static int -ixfr_getdelta(struct zoneinfo *zp, FILE *fp, const char *filename, char *origin, - ns_updque *listuprec, u_int32_t *old_serial, - u_int32_t *new_serial) -{ - static int read_soa, read_ns, rrcount; - - char data[MAXDATA], dnbuf[MAXDNAME], sclass[3]; - const char *errtype = "Database"; - char *dname, *cp, *cp1; - char buf[MAXDATA]; - u_int32_t serial, ttl; - int nonempty_lineno = -1, prev_pktdone = 0, cont = 0, - inside_next = 0; - int id; - int i, c, section, opcode, matches, zonenum, err, multiline; - int type, class; - u_int32_t n; - enum transport transport; - struct map *mp; - int zonelist[MAXDNAME]; - struct databuf *dp; - struct in_addr ina; - struct sockaddr_in empty_from; - int datasize; - ns_updrec * rrecp; - u_long l; - -#define ERRTO(msg) if (1) { errtype = msg; goto err; } else (void)NULL - - err = 0; - transport = primary_trans; - lineno = 1; - for (;;) { - if (!getword(buf, sizeof buf, fp, 0)) { - if (lineno == (nonempty_lineno + 1) && !(feof(fp))) { - /* - * End of a nonempty line inside an update - * packet or not inside an update packet. - */ - continue; - } - /* - * Empty line or EOF. - */ - if (feof(fp)) - break; - inside_next = 0; - cont = 1; - } else { - nonempty_lineno = lineno; - } - - if (!strcasecmp(buf, "[DYNAMIC_UPDATE]") || - !strcasecmp(buf, "[IXFR_UPDATE]")) { - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || !sscanf((char *) cp, "id %d", &id)) - id = -1; - inside_next = 1; - cont = 1; - } else if (!strcasecmp(buf, "[INCR_SERIAL]")) { - /* XXXRTH not enough error checking here */ - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || - sscanf((char *) cp, "from %u to %u", - old_serial, new_serial) != 2) { - ns_error(ns_log_update, - "incr_serial problem with %s", - zp->z_updatelog); - } else { - serial = get_serial(zp); - } - cont = 1; - } else if (!strcasecmp(buf, "[END_DELTA]")) { - prev_pktdone = 1; - cont = 1; - lineno++; - } - if (prev_pktdone) { - if (!EMPTY(*listuprec)) { - n++; - return (DBIXFR_FOUND_RR); - } - prev_pktdone = 0; - } - if (cont) { - cont = 0; - continue; - } - if (!inside_next) - continue; - /* - * inside the same update packet, continue accumulating - * records. - */ - section = -1; - n = strlen(buf); - if (buf[n - 1] == ':') - buf[--n] = '\0'; - for (mp = m_section; mp < m_section + M_SECTION_CNT; mp++) - if (!strcasecmp(buf, mp->token)) { - section = mp->val; - break; - } - ttl = 0; - type = -1; - class = zp->z_class; - n = 0; - data[0] = '\0'; - switch (section) { - case S_ZONE: - cp = fgets(buf, sizeof buf, fp); - if (!cp) - *buf = '\0'; - n = sscanf(cp, "origin %s class %s serial %ul", - origin, sclass, &serial); - if (n != 3 || ns_samename(origin, zp->z_origin) != 1) - err++; - if (cp) - lineno++; - if (!err && inside_next) { - int success; - - dname = origin; - type = T_SOA; - class = sym_ston(__p_class_syms, sclass, - &success); - if (!success) { - err++; - break; - } - matches = findzone(dname, class, 0, - zonelist, MAXDNAME); - if (matches) - zonenum = zonelist[0]; - else - err++; - } - break; - case S_PREREQ: - case S_UPDATE: - /* Operation code. */ - if (!getword(buf, sizeof buf, fp, 0)) { - err++; - break; - } - opcode = -1; - if (buf[0] == '{') { - n = strlen(buf); - for (i = 0; (u_int32_t) i < n; i++) - buf[i] = buf[i + 1]; - if (buf[n - 2] == '}') - buf[n - 2] = '\0'; - } - for (mp = m_opcode; mp < m_opcode + M_OPCODE_CNT; mp++) - if (!strcasecmp(buf, mp->token)) { - opcode = mp->val; - break; - } - if (opcode == -1) { - err++; - break; - } - /* Owner's domain name. */ - if (!getword((char *) dnbuf, sizeof dnbuf, fp, 0)) { - err++; - break; - } - n = strlen((char *) dnbuf) - 1; - if (dnbuf[n] == '.') - dnbuf[n] = '\0'; - dname = dnbuf; - ttl = 0; - type = -1; - class = zp->z_class; - n = 0; - data[0] = '\0'; - (void) getword(buf, sizeof buf, fp, 1); - if (isdigit(buf[0])) { /* ttl */ - if (ns_parse_ttl(buf, &l) < 0) { - err++; - break; - } - ttl = l; - (void) getword(buf, sizeof buf, fp, 1); - } - /* possibly class */ - if (buf[0] != '\0') { - int success; - int maybe_class; - - maybe_class = sym_ston(__p_class_syms, - buf, &success); - if (success) { - class = maybe_class; - (void) getword(buf, sizeof buf, fp, 1); - } - } - /* possibly type */ - if (buf[0] != '\0') { - int success; - int maybe_type; - - maybe_type = sym_ston(__p_type_syms, - buf, &success); - - if (success) { - type = maybe_type; - (void) getword(buf, sizeof buf, fp, 1); - } - } - if (buf[0] != '\0') /* possibly rdata */ - /* - * Convert the ascii data 'buf' to the proper - * format based on the type and pack into - * 'data'. - * - * XXX - same as in db_load(), consolidation - * needed - */ - switch (type) { - case T_A: - if (!inet_aton(buf, &ina)) { - err++; - break; - } - n = ntohl(ina.s_addr); - cp = data; - PUTLONG(n, cp); - n = INT32SZ; - break; - case T_HINFO: - case T_ISDN: - n = strlen(buf); - data[0] = n; - memcpy(data + 1, buf, n); - n++; - if (!getword(buf, sizeof buf, fp, 0)) { - i = 0; - } else { - endline(fp); - i = strlen(buf); - } - data[n] = i; - n++; - memcpy(data + n + 1, buf, i); - n += i; - break; - case T_SOA: - case T_MINFO: - case T_RP: - (void) strcpy(data, buf); - cp = data + strlen(data) + 1; - if (!getword((char *) cp, - sizeof data - (cp - data), - fp, 1)) { - err++; - break; - } - cp += strlen((char *) cp) + 1; - if (type != T_SOA) { - n = cp - data; - break; - } - if (class != zp->z_class || - ns_samename(dname, zp->z_origin) != 1) { - err++; - break; - } - c = getnonblank(fp, zp->z_updatelog); - if (c == '(') { - multiline = 1; - } else { - multiline = 0; - ungetc(c, fp); - } - n = getnum(fp, zp->z_updatelog, GETNUM_SERIAL); - if (getnum_error) { - err++; - break; - } - if (opcode == ADD && i == 0) - *new_serial = n; - PUTLONG(n, cp); - for (i = 0; i < 4; i++) { - if (!getword(buf, sizeof buf, fp, 1)) { - err++; - break; - } - if (ns_parse_ttl(buf, &l) < 0) { - err++; - break; - } - n = l; - PUTLONG(n, cp); - } - if (multiline && - getnonblank(fp, zp->z_updatelog) != ')') - { - err++; - break; - } - endline(fp); - n = cp - data; - break; - case T_WKS: - if (!inet_aton(buf, &ina)) { - err++; - break; - } - n = ntohl(ina.s_addr); - cp = data; - PUTLONG(n, cp); - *cp = (char) getprotocol(fp, zp->z_updatelog); - n = INT32SZ + sizeof(char); - n = getservices((int) n, data, - fp, zp->z_updatelog); - break; - case T_NS: - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_PTR: - (void) strcpy(data, buf); - if (makename(data, origin, - sizeof(data)) == -1) { - err++; - break; - } - n = strlen(data) + 1; - break; - case T_MX: - case T_AFSDB: - case T_RT: - n = 0; - cp = buf; - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - /* catch bad values */ - cp = data; - PUTSHORT((u_int16_t) n, cp); - if (!getword(buf, sizeof(buf), fp, 1)) { - err++; - break; - } - (void) strcpy((char *) cp, buf); - if (makename((char *) cp, origin, - sizeof(data) - (cp - data)) == -1) - { - err++; - break; - } - /* advance pointer to end of data */ - cp += strlen((char *) cp) + 1; - /* now save length */ - n = (cp - data); - break; - case T_PX: - n = 0; - data[0] = '\0'; - cp = buf; - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - cp = data; - PUTSHORT((u_int16_t) n, cp); - for (i = 0; i < 2; i++) { - if (!getword(buf, sizeof(buf), fp, 0)) - { - err++; - break; - } - (void) strcpy((char *) cp, buf); - cp += strlen((char *) cp) + 1; - } - n = cp - data; - break; - case T_TXT: - case T_X25: - i = strlen(buf); - cp = data; - datasize = sizeof data; - cp1 = buf; - while (i > MAXCHARSTRING) { - if (datasize <= MAXCHARSTRING) { - ns_error(ns_log_update, - "record too big"); - return (-1); - } - datasize -= MAXCHARSTRING; - *cp++ = (char)MAXCHARSTRING; - memcpy(cp, cp1, MAXCHARSTRING); - cp += MAXCHARSTRING; - cp1 += MAXCHARSTRING; - i -= MAXCHARSTRING; - } - if (datasize < i + 1) { - ns_error(ns_log_update, - "record too big"); - return (-1); - } - *cp++ = i; - memcpy(cp, cp1, i); - cp += i; - n = cp - data; - endline(fp); - /* XXXVIX: segmented texts 4.9.5 */ - break; - case T_NSAP: - n = inet_nsap_addr(buf, (u_char *) data, - sizeof data); - endline(fp); - break; - case T_LOC: - cp = buf + (n = strlen(buf)); - *cp = ' '; - cp++; - while ((i = getc(fp), *cp = i, i != EOF) - && *cp != '\n' && (n < MAXDATA)) - { - cp++; - n++; - } - if (*cp == '\n') - ungetc(*cp, fp); - *cp = '\0'; - n = loc_aton(buf, (u_char *) data); - if (n == 0) { - err++; - break; - } - endline(fp); - break; - case ns_t_sig: - case ns_t_nxt: - case ns_t_key: - case ns_t_cert:{ - char *errmsg = NULL; - - n = parse_sec_rdata(buf, sizeof(buf), 1, - (u_char *) data, - sizeof(data), - fp, zp, dname, ttl, - type, domain_ctx, - transport, &errmsg); - if (errmsg) { - err++; - endline(fp); - n = 0; - } - break; - } - default: - err++; - } - if (section == S_PREREQ) { - ttl = 0; - if (opcode == NXDOMAIN) { - class = C_NONE; - type = T_ANY; - n = 0; - } else if (opcode == YXDOMAIN) { - class = C_ANY; - type = T_ANY; - n = 0; - } else if (opcode == NXRRSET) { - class = C_NONE; - n = 0; - } else if (opcode == YXRRSET) { - if (n == 0) - class = C_ANY; - } - } else {/* section == S_UPDATE */ - if (opcode == DELETE) { - if (n == 0) { - class = C_ANY; - if (type == -1) - type = T_ANY; - } else { - class = zp->z_class; - } - } - } - break; - case S_ADDT: - default: - ns_debug(ns_log_update, 1, - "cannot interpret section: %d", section); - inside_next = 0; - err++; - } - if (err) { - inside_next = 0; - ns_debug(ns_log_update, 1, - "merge of update id %d failed due to error at line %d", - id, lineno); - return (DBIXFR_ERROR); - } - rrecp = res_mkupdrec(section, dname, class, type, ttl); - if (section != S_ZONE) { - dp = savedata(class, type, ttl, (u_char *) data, n); - dp->d_zone = zonenum; - dp->d_cred = DB_C_ZONE; - dp->d_clev = nlabels(zp->z_origin); - rrecp->r_dp = dp; - rrecp->r_opcode = opcode; - } else { - rrecp->r_zone = zonenum; - rrecp->r_opcode = opcode; - } - - /* remove add/delete pairs */ - if (section == S_UPDATE) { - ns_updrec *arp; - int foundmatch; - - arp = TAIL(*listuprec); - foundmatch = 0; - while (arp) { - if (arp->r_section == S_UPDATE && - ((arp->r_opcode == DELETE && - opcode == ADD) || - (opcode == DELETE && - arp->r_opcode == ADD)) && - arp->r_dp->d_type == dp->d_type && - arp->r_dp->d_class == dp->d_class && - arp->r_dp->d_ttl == dp->d_ttl && - ns_samename(arp->r_dname, dname) == 1 && - db_cmp(arp->r_dp, dp) == 0) { - db_freedata(dp); - db_freedata(arp->r_dp); - UNLINK(*listuprec, arp, r_link); - res_freeupdrec(arp); - res_freeupdrec(rrecp); - foundmatch = 1; - break; - } - arp = PREV(arp, r_link); - } - if (foundmatch) - continue; - } - - APPEND(*listuprec, rrecp, r_link); - /* Override zone number with current zone serial number */ - rrecp->r_zone = serial; - } - - if (err) - return (DBIXFR_ERROR); - - return (DBIXFR_END); -} - diff --git a/contrib/bind/bin/named/db_load.c b/contrib/bind/bin/named/db_load.c deleted file mode 100644 index 305944c6e4d82..0000000000000 --- a/contrib/bind/bin/named/db_load.c +++ /dev/null @@ -1,2614 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)db_load.c 4.38 (Berkeley) 3/2/91"; -static const char rcsid[] = "$Id: db_load.c,v 8.104 2000/07/17 07:48:09 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1988, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1995 by International Business Machines, Inc. - * - * International Business Machines, Inc. (hereinafter called IBM) grants - * permission under its copyrights to use, copy, modify, and distribute this - * Software with or without fee, provided that the above copyright notice and - * all paragraphs of this notice appear in all copies, and that the name of IBM - * not be used in connection with the marketing of any product incorporating - * the Software or modifications thereof, without specific, written prior - * permission. - * - * To the extent it has a right to do so, IBM grants an immunity from suit - * under its patents, if any, for the use, sale or manufacture of products to - * the extent that such products are used for performing Domain Name System - * dynamic updates in TCP/IP networks by means of the Software. No immunity is - * granted for any product per se or for any other function of any product. - * - * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, - * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN - * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Load zone from ASCII file on local host. Format similar to RFC 883. - */ - -/* Import. */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <netdb.h> -#include <resolv.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" - -/* Forward. */ - -static int gettoken(FILE *, const char *); -static int getcharstring(char *, char *, int, int, int, FILE *, - const char *); -static int genname(char *, int, const char *, char *, int); -static int getmlword(char *, size_t, FILE *, int); -static int getallwords(char *, size_t, FILE *, int); -static u_int32_t wordtouint32(char *); -static void fixup_soa(const char *fn, struct zoneinfo *zp); -static int get_nxt_types(u_char *, FILE *, const char *); - -static int parse_sig_rr(char *, int, u_char *, int, FILE *, - struct zoneinfo *, char *, u_int32_t , - enum context , enum transport , char **); -static int parse_key_rr(char *, int, u_char *, int, FILE *, - struct zoneinfo *, char *, enum context, - enum transport, char **); - -static int parse_cert_rr(char *, int, u_char *, int, FILE *, char **); -static int parse_nxt_rr(char *, int, u_char *, int, FILE *, - struct zoneinfo *, char *, enum context, - enum transport, char **); - - -static int wordtouint32_error = 0; -static int empty_token = 0; -static int getmlword_nesting = 0; - -/* Global. */ - -static int clev; /* a zone deeper in a hierarchy has more credibility */ - -/* - * Parser token values - */ -#define CURRENT 1 -#define DOT 2 -#define AT 3 -#define DNAME 4 -#define INCLUDE 5 -#define ORIGIN 6 -#define GENERATE 7 -#define DEFAULTTTL 8 -#define ERRTOK 9 - -#define MAKENAME_OK(N) \ - do { \ - if (!makename_ok(N, origin, class, zp, \ - transport, context, \ - domain, filename, lineno, \ - data_size - ((u_char*)N - data))) { \ - errs++; \ - sprintf(buf, "bad name \"%s\"", N); \ - goto err; \ - } \ - } while (0) - -#define MAKENAME_OKZP(N, SI) \ - do { \ - if (!makename_ok(N, zp->z_origin, zp->z_class, zp, \ - transport, context, \ - domain, zp->z_source, lineno, \ - SI - ((u_char*)N - data))) { \ - errs++; \ - sprintf(buf, "bad name \"%s\"", N); \ - goto err; \ - } \ - } while (0) - -#define RANGE(x, min, max) \ - (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x))) - -/* Public. */ - -/* int - * db_load(filename, in_origin, zp, def_domain, isixfr) - * load a database from `filename' into zone `zp'. append `in_origin' - * to all nonterminal domain names in the file. `def_domain' is the - * default domain for include files or NULL for zone base files. - * returns: - * -1 = can't open file - * 0 = success - * >0 = number of errors encountered - */ -int -db_load(const char *filename, const char *in_origin, - struct zoneinfo *zp, const char *def_domain, int isixfr) -{ - static int read_soa, read_ns, rrcount; - static u_int32_t default_ttl, default_warn; - static struct filenames { - struct filenames *next; - char *name; - } *filenames, *fn; - - const char *errtype = "Database"; - char *cp; - char domain[MAXDNAME], origin[MAXDNAME], tmporigin[MAXDNAME]; - char buf[MAXDATA]; - char genlhs[MAXDNAME], genrhs[MAXDNAME]; - u_char data[MAXDATA]; - int data_size = sizeof(data); - int c, someclass, class, type, dbflags, dataflags, multiline = 0; - int slineno, i, errs, didinclude, ininclude, escape, success; - u_int32_t ttl, n, serial; - u_long tmplong; - struct databuf *dp; - FILE *fp; - struct stat sb; - struct in_addr ina; - enum transport transport; - enum context context; - struct sockaddr_in empty_from; - int genstart, genend, genstep; - char *thisfile; - void *state = NULL; - - empty_from.sin_family = AF_INET; - empty_from.sin_addr.s_addr = htonl(INADDR_ANY); - empty_from.sin_port = htons(0); - -/* - * We use an 'if' inside of the 'do' below because otherwise the Solaris - * compiler detects that the 'while' is never executed because of the 'goto' - * and complains. - */ -#define ERRTO(msg) do { if (1) { errtype = msg; goto err; } } while (0) -#define ERRTOZ(msg) do { if (1) { errtype = msg; buf[0] = '\0'; goto err; } } while (0) - - switch (zp->z_type) { - case Z_PRIMARY: - /* Any updates should be saved before we attempt to reload. */ - INSIST((zp->z_flags & (Z_NEED_DUMP|Z_NEED_SOAUPDATE)) == 0); - case Z_HINT: - transport = primary_trans; - break; - case Z_SECONDARY: - case Z_STUB: - transport = secondary_trans; - break; - case Z_CACHE: - transport = response_trans; - break; - default: - transport = response_trans; /*guessing*/ - break; - } - errs = 0; - didinclude = 0; - ininclude = (def_domain != NULL); - if (!ininclude) { - rrcount = 0; - read_soa = 0; - read_ns = 0; - default_ttl = USE_MINIMUM; - default_warn = 1; - clev = nlabels(in_origin); - filenames = NULL; - zp->z_minimum = USE_MINIMUM; - } - ttl = default_ttl; - - ns_debug(ns_log_load, 1, "db_load(%s, %s, %d, %s, %s)", - filename, in_origin, zp - zones, - def_domain ? def_domain : "Nil", isixfr ? "IXFR" : "Normal"); - - fn = (struct filenames *)memget(sizeof *filenames); - if (fn == NULL) - ns_panic(ns_log_db, 0, "db_load: memget failed"); - thisfile = fn->name = savestr(filename, 1); - fn->next = filenames; - filenames = fn; - - strcpy(origin, in_origin); - if ((fp = fopen(filename, "r")) == NULL) { - ns_warning(ns_log_load, "db_load could not open: %s: %s", - filename, strerror(errno)); - zp->z_ftime = 0; - return (-1); - } - if (zp->z_type == Z_HINT) { - dbflags = DB_NODATA | DB_NOHINTS; - dataflags = DB_F_HINT; -#ifdef STUBS - } else if (zp->z_type == Z_STUB && clev == 0) { - dbflags = DB_NODATA | DB_NOHINTS; - dataflags = DB_F_HINT; -#endif - } else { - dbflags = DB_NODATA; - dataflags = 0; - } - gettime(&tt); - if (fstat(fileno(fp), &sb) < 0) { - ns_warning(ns_log_load, "fstat failed: %s: %s", - filename, strerror(errno)); - sb.st_mtime = (int)tt.tv_sec; - } - slineno = lineno; - lineno = 1; - if (def_domain) - strcpy(domain, def_domain); - else - domain[0] = '\0'; - class = zp->z_class; - zp->z_flags &= ~(Z_INCLUDE|Z_DB_BAD); - while ((c = gettoken(fp, filename)) != EOF) { - switch (c) { - case INCLUDE: - if (isixfr) { - c = ERRTOK; - break; - } - if (!getword(buf, sizeof buf, fp, 0)) - /* file name*/ - break; - if (!getword(tmporigin, sizeof(tmporigin), fp, 1)) - strcpy(tmporigin, origin); - else { - if (makename(tmporigin, origin, - sizeof(tmporigin)) == -1) - ERRTO("$INCLUDE makename failed"); - endline(fp); - } - didinclude = 1; - i = db_load(buf, tmporigin, zp, domain, ISNOTIXFR); - errs += (i == -1) ? 1 : i; - continue; - - case ORIGIN: - (void) strcpy(buf, origin); - if (!getword(origin, sizeof(origin), fp, 1)) - break; - ns_debug(ns_log_load, 3, "db_load: origin %s, buf %s", - origin, buf); - if (makename(origin, buf, sizeof(origin)) == -1) - ERRTO("$ORIGIN makename failed"); - ns_debug(ns_log_load, 3, "db_load: origin now %s", - origin); - continue; - - case GENERATE: - if (!getword(buf, sizeof(buf), fp, 0)) - ERRTOZ("$GENERATE missing RANGE"); - n = sscanf(buf, "%d-%d/%d", &genstart, &genend, - &genstep); - if (n != 2 && n != 3) - ERRTO("$GENERATE invalid range"); - if (n == 2) - genstep = 1; - if ((genend < genstart) || (genstart < 0) || - (genstep < 0)) - ERRTO("$GENERATE invalid range"); - if (!getword(genlhs, sizeof(genlhs), fp, 2)) - ERRTOZ("$GENERATE missing LHS"); - if (!getword(buf, sizeof(buf), fp, 0)) - ERRTOZ("GENERATE missing TYPE"); - type = sym_ston(__p_type_syms, buf, &success); - if (success == 0 || type == ns_t_any) { - ns_info(ns_log_load, - "%s: Line %d: $GENERATE unknown type: %s.", - filename, lineno, buf); - errs++; - endline(fp); - continue; - } - switch (type) { - case ns_t_ns: - case ns_t_ptr: - case ns_t_cname: - case ns_t_a: - case ns_t_aaaa: - break; - default: - ERRTO("$GENERATE unsupported type"); - } - if (!getword(genrhs, sizeof(genrhs), fp, 2)) - ERRTOZ("$GENERATE missing RHS"); - for (i = genstart; i <= genend; i += genstep) { - if (genname(genlhs, i, origin, domain, - sizeof domain) == -1) - ERRTOZ("$GENERATE genname LHS failed"); - context = ns_ownercontext(type, transport); - if (!ns_nameok(NULL, domain, class, zp, transport, - context, domain, inaddr_any)) { - strcpy(buf, domain); - ERRTO("$GENERATE owner name error"); - } - switch (type) { - case ns_t_ns: - case ns_t_ptr: - case ns_t_cname: - if (genname(genrhs, i, origin, (char *)data, - sizeof data) == -1) - ERRTOZ("$GENERATE genname RHS failed"); - switch (type) { - case ns_t_ns: - context = hostname_ctx; - break; - case ns_t_ptr: - context = ns_ptrcontext(domain); - break; - case ns_t_cname: - context = domain_ctx; - break; - } - if (!ns_nameok(NULL, (char *)data, class, zp, - transport, context, - domain, inaddr_any)) { - strncpy(buf, domain, sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - ERRTO("$GENERATE name error"); - } - n = strlen((char *)data) + 1; - break; - case ns_t_a: - case ns_t_aaaa: - if (genname(genrhs, i, NULL, (char *)data, - sizeof data) == -1) - ERRTOZ("$GENERATE genname RHS failed"); - strncpy(buf, (char*)data, sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - switch (type) { - case ns_t_a: - if (!inet_aton(buf, &ina)) - ERRTO("IP Address"); - (void) ina_put(ina, data); - n = NS_INT32SZ; - break; - case ns_t_aaaa: - if (inet_pton(AF_INET6, buf, data) <= 0) - ERRTO("IPv6 Address"); - n = NS_IN6ADDRSZ; - break; - } - break; - default: - ERRTOZ("$GENERATE unsupported context"); - } - dp = savedata(class, type, (u_int32_t)ttl, - (u_char *)data, (int)n); - dp->d_zone = zp - zones; - dp->d_flags = dataflags; - dp->d_cred = DB_C_ZONE; - dp->d_clev = clev; - c = db_set_update(domain, dp, &state, dbflags, - (dataflags & DB_F_HINT) != 0 ? - &fcachetab : &hashtab, - empty_from, &rrcount, lineno, - filename); - if (c != OK) { - if (c == CNAMEANDOTHER) - errs++; - } - } - endline(fp); - continue; - - case DNAME: - if (!getword(domain, sizeof(domain), fp, 1)) - break; - if (makename(domain, origin, sizeof(domain)) == -1) - ERRTO("ownername makename failed"); - goto gotdomain; - - case DEFAULTTTL: - if (getttl(fp, filename, lineno, &n, - &multiline) <= 0 || n > MAXIMUM_TTL) { - ERRTO("$TTL bad TTL value"); - } - ttl = default_ttl = n; - continue; - - case AT: - (void) strcpy(domain, origin); - goto gotdomain; - - case DOT: - domain[0] = '\0'; - /* FALLTHROUGH */ - case CURRENT: - gotdomain: - if (!getword(buf, sizeof buf, fp, 0)) { - if (c == CURRENT) - continue; - break; - } - if (ns_parse_ttl(buf, &tmplong) < 0) { - if (zp->z_type == z_master && - default_warn && - (default_ttl == USE_MINIMUM)) { - ns_warning(ns_log_load, - "Zone \"%s\" (file %s): %s", - zp->z_origin, filename, - "No default TTL ($TTL <value>) set, using SOA minimum instead"); - default_warn = 0; - } - ttl = (u_int32_t)default_ttl; - } else { - ttl = tmplong; - if (ttl > MAXIMUM_TTL) { - ns_info(ns_log_load, - "%s: Line %d: TTL > %u; converted to 0", - filename, lineno, MAXIMUM_TTL); - ttl = 0; - } - if (zp->z_type == Z_CACHE) { - /* - * This allows the cache entry to age - * while sitting on disk (powered off). - */ - if (ttl > max_cache_ttl) - ttl = max_cache_ttl; - ttl += sb.st_mtime; - } - if (!getword(buf, sizeof buf, fp, 0)) - break; - } - - /* Parse class (IN, etc) */ - someclass = sym_ston(__p_class_syms, buf, &success); - if (success && someclass != zp->z_class) { - ns_info(ns_log_load, - "%s: Line %d: wrong class: %s.", - filename, lineno, - p_class(someclass)); - errs++; - break; - } - if (success && someclass != C_ANY) { - class = someclass; - (void) getword(buf, sizeof buf, fp, 0); - } - - /* Parse RR type (A, MX, etc) */ - type = sym_ston(__p_type_syms, buf, &success); - if (success == 0 || type == ns_t_any) { - ns_info(ns_log_load, - "%s: Line %d: Unknown type: %s.", - filename, lineno, buf); - errs++; - break; - } - if (ttl == USE_MINIMUM) - ttl = zp->z_minimum; - context = ns_ownercontext(type, transport); - if (!ns_nameok(NULL, domain, class, zp, transport, context, - domain, inaddr_any)) { - errs++; - ns_notice(ns_log_load, - "%s:%d: owner name error", - filename, lineno); - break; - } - context = domain_ctx; - switch (type) { - case ns_t_key: - case ns_t_sig: - case ns_t_nxt: - case ns_t_cert: - /* - * Don't do anything here for these types -- - * they read their own input separately later. - */ - goto dont_get_word; - - case ns_t_soa: - case ns_t_minfo: - case ns_t_rp: - case ns_t_ns: - case ns_t_cname: - case ns_t_mb: - case ns_t_mg: - case ns_t_mr: - case ns_t_ptr: - escape = 1; - break; - default: - escape = 0; - } - if (!getword(buf, sizeof buf, fp, escape)) - break; - ns_debug(ns_log_load, 3, - "d='%s', c=%d, t=%d, ttl=%u, data='%s'", - domain, class, type, ttl, buf); - /* - * Convert the ascii data 'buf' to the proper format - * based on the type and pack into 'data'. - */ - dont_get_word: - switch (type) { - case ns_t_a: - if (!inet_aton(buf, &ina)) - ERRTO("IP Address"); - (void) ina_put(ina, data); - n = NS_INT32SZ; - break; - - case ns_t_soa: - context = hostname_ctx; - goto soa_rp_minfo; - case ns_t_rp: - case ns_t_minfo: - context = mailname_ctx; - /* FALLTHROUGH */ - soa_rp_minfo: - (void) strcpy((char *)data, buf); - - MAKENAME_OK((char *)data); - cp = (char *)(data + strlen((char *)data) + 1); - if (!getword(cp, - (sizeof data) - - (cp - (char*)data), - fp, 1)) - ERRTO("Domain Name"); - if (type == ns_t_rp) - context = domain_ctx; - else - context = mailname_ctx; - MAKENAME_OK(cp); - cp += strlen((char *)cp) + 1; - if (type != ns_t_soa) { - n = cp - (char *)data; - break; - } - if (ns_samename(zp->z_origin, domain) != 1) { - errs++; - ns_error(ns_log_load, - "%s:%d: SOA for \"%s\" not at zone top \"%s\"", - filename, lineno, domain, - zp->z_origin); - } - c = getnonblank(fp, filename); - if (c == '(') { - multiline = 1; - } else { - multiline = 0; - ungetc(c, fp); - } - serial = zp->z_serial; - zp->z_serial = getnum(fp, filename, - GETNUM_SERIAL); - if (getnum_error) - errs++; - n = (u_int32_t) zp->z_serial; - PUTLONG(n, cp); - if (serial != 0 && - SEQ_GT(serial, zp->z_serial)) { - ns_notice(ns_log_load, - "%s:%d: WARNING: new serial number < old (%lu < %lu)", - filename , lineno, - zp->z_serial, serial); - } - if (getttl(fp, filename, lineno, &n, - &multiline) <= 0) { - errs++; - n = INIT_REFRESH; - } - PUTLONG(n, cp); - zp->z_refresh = RANGE(n, MIN_REFRESH, - MAX_REFRESH); - if (zp->z_type == Z_SECONDARY -#if defined(STUBS) - || zp->z_type == Z_STUB -#endif - ) { - ns_refreshtime(zp, MIN(sb.st_mtime, - tt.tv_sec)); - sched_zone_maint(zp); - } -#ifdef BIND_UPDATE - if ((zp->z_type == Z_PRIMARY) && - (zp->z_flags & Z_DYNAMIC)) - if ((u_int32_t)zp->z_soaincrintvl > - zp->z_refresh/3) { - ns_info(ns_log_load, - "zone soa update time truncated to 1/3rd of refresh time"); - zp->z_soaincrintvl = - zp->z_refresh / 3; - } -#endif - - if (getttl(fp, filename, lineno, &n, - &multiline) <= 0) { - errs++; - n = INIT_REFRESH; - } - PUTLONG(n, cp); - zp->z_retry = RANGE(n, MIN_RETRY, MAX_RETRY); - if (getttl(fp, filename, lineno, - &n, &multiline) <= 0) { - errs++; - n = INIT_REFRESH; - } - PUTLONG(n, cp); - zp->z_expire = RANGE(n, zp->z_refresh, - MAX_EXPIRE); - if (getttl(fp, filename, lineno, &n, - &multiline) <= 0) { - errs++; - n = 120; - } - PUTLONG(n, cp); - if (n > MAXIMUM_TTL) { - ns_info(ns_log_load, - "%s: Line %d: SOA minimum TTL > %u; converted to 0", - filename, lineno, MAXIMUM_TTL); - zp->z_minimum = 0; - } else - zp->z_minimum = n; - if (ttl == USE_MINIMUM) - ttl = n; - n = cp - (char *)data; - if (multiline) { - buf[0] = getnonblank(fp, filename); - buf[1] = '\0'; - if (buf[0] != ')') - ERRTO("SOA \")\""); - multiline = 0; - endline(fp); - } - read_soa++; - if (zp->z_type == Z_PRIMARY) - fixup_soa(filename, zp); - break; - - case ns_t_wks: - /* Address */ - if (!inet_aton(buf, &ina)) - ERRTO("WKS IP Address"); - (void) ina_put(ina, data); - /* Protocol */ - data[INADDRSZ] = getprotocol(fp, filename); - /* Services */ - n = getservices(NS_INT32SZ + sizeof(char), - (char *)data, fp, filename); - break; - - case ns_t_ns: - if (ns_samename(zp->z_origin, domain) == 1) - read_ns++; - context = hostname_ctx; - goto cname_etc; - case ns_t_cname: - case ns_t_mb: - case ns_t_mg: - case ns_t_mr: - context = domain_ctx; - goto cname_etc; - case ns_t_ptr: - context = ns_ptrcontext(domain); - cname_etc: - (void) strcpy((char *)data, buf); - MAKENAME_OK((char *)data); - n = strlen((char *)data) + 1; - break; - - case ns_t_naptr: - /* Order Preference Flags Service Replacement Regexp */ - n = 0; - cp = buf; - /* Order */ - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - /* catch bad values */ - if (cp == buf || n > 65535) - ERRTO("NAPTR Order"); - cp = (char *)data; - PUTSHORT((u_int16_t)n, cp); - - /* Preference */ - n = getnum(fp, filename, GETNUM_NONE); - if (getnum_error || n > 65536) - ERRTO("NAPTR Preference"); - PUTSHORT((u_int16_t)n, cp); - - /* Flags */ - if (!getword(buf, sizeof buf, fp, 0)) - ERRTO("NAPTR Flags"); - n = strlen(buf); - if (n > 255) - ERRTO("NAPTR Flags too big"); - *cp++ = n; - memcpy(cp, buf, (int)n); - cp += n; - - /* Service Classes */ - if (!getword(buf, sizeof buf, fp, 0)) - ERRTO("NAPTR Service Classes"); - n = strlen(buf); - if (n > 255) - ERRTO("NAPTR Service Classes too big"); - *cp++ = n; - memcpy(cp, buf, (int)n); - cp += n; - - /* Pattern */ - if (!getword(buf, sizeof buf, fp, 0)) - ERRTO("NAPTR Pattern"); - n = strlen(buf); - if (n > 255) - ERRTO("NAPTR Pattern too big"); - *cp++ = n; - memcpy(cp, buf, (int)n); - cp += n; - - /* Replacement */ - if (!getword(buf, sizeof buf, fp, 1)) - ERRTO("NAPTR Replacement"); - n = strlen(buf); - if (n > data_size - ((u_char *)cp - data)) - ERRTO("NAPTR Replacement too big"); - (void) strcpy((char *)cp, buf); - context = domain_ctx; - MAKENAME_OK(cp); - /* advance pointer to end of data */ - cp += strlen((char *)cp) +1; - - /* now save length */ - n = (cp - (char *)data); - break; - - - case ns_t_mx: - case ns_t_afsdb: - case ns_t_rt: - case ns_t_srv: - n = 0; - cp = buf; - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - /* catch bad values */ - if ((cp == buf) || (n > 65535)) - ERRTO("Priority"); - cp = (char *)data; - PUTSHORT((u_int16_t)n, cp); - - if (type == ns_t_srv) { - n = getnum(fp, filename, GETNUM_NONE); - if (getnum_error || n > 65536) - ERRTO("SRV RR"); - PUTSHORT((u_int16_t)n, cp); - - n = getnum(fp, filename, GETNUM_NONE); - if (getnum_error || n > 65536) - ERRTO("SRV RR"); - PUTSHORT((u_int16_t)n, cp); - } - - if (!getword(buf, sizeof buf, fp, 1)) - ERRTO("Domain Name"); - (void) strcpy((char *)cp, buf); - context = hostname_ctx; - MAKENAME_OK(cp); - /* advance pointer to end of data */ - cp += strlen((char *)cp) +1; - - /* now save length */ - n = (cp - (char *)data); - break; - - case ns_t_px: - context = domain_ctx; - n = 0; - data[0] = '\0'; - cp = buf; - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - /* catch bad values */ - if ((cp == buf) || (n > 65535)) - ERRTO("PX Priority"); - cp = (char *)data; - PUTSHORT((u_int16_t)n, cp); - - if (!getword(buf, sizeof buf, fp, 0)) - ERRTO("PX Domain1"); - (void) strcpy((char *)cp, buf); - MAKENAME_OK(cp); - /* advance pointer to next field */ - cp += strlen((char *)cp) + 1; - if (!getword(buf, sizeof buf, fp, 0)) - ERRTO("PX Domain2"); - (void) strcpy((char *)cp, buf); - MAKENAME_OK(cp); - /* advance pointer to end of data */ - cp += strlen((char *)cp) + 1; - - /* now save length */ - n = (cp - (char *)data); - break; - - case ns_t_hinfo: - n = getcharstring(buf, (char *)data, type, - 2, 2, fp, filename); - if (n == 0) - ERRTO("HINFO RR"); - break; - - case ns_t_isdn: - n = getcharstring(buf, (char *)data, type, - 1, 2, fp, filename); - if (n == 0) - ERRTO("ISDN RR"); - break; - - case ns_t_txt: - n = getcharstring(buf, (char *)data, type, - 1, 0, fp, filename); - if (n == 0) - ERRTO("TXT RR"); - break; - - - case ns_t_x25: - n = getcharstring(buf, (char *)data, type, - 1, 1, fp, filename); - if (n == 0) - ERRTO("X25 RR"); - break; - - case ns_t_nsap: - n = inet_nsap_addr(buf, (u_char *)data, - sizeof data); - if (n == 0) - ERRTO("NSAP RR"); - endline(fp); - break; - - case ns_t_aaaa: - if (inet_pton(AF_INET6, buf, data) <= 0) - ERRTO("IPv4 Address"); - n = NS_IN6ADDRSZ; - endline(fp); - break; - - case ns_t_nxt: - case ns_t_key: - case ns_t_cert: - case ns_t_sig: { - char *errmsg = NULL; - int ret; - if (ttl == USE_MINIMUM) /* no ttl set */ - ttl = 0; - ret = parse_sec_rdata(buf, sizeof(buf), 0, - data, sizeof(data), - fp, zp, domain, ttl, - type, domain_ctx, - transport, &errmsg); - if (ret < 0) { - errtype = errmsg; - goto err; - } - else - n = ret; - break; - } - - - case ns_t_loc: - cp = buf + (n = strlen(buf)); - *cp = ' '; - cp++; - n++; - while ((i = getc(fp), *cp = i, i != EOF) - && *cp != '\n' - && (n < MAXDATA)) { - cp++; n++; - } - if (*cp == '\n') /* leave \n for getword */ - ungetc(*cp, fp); - *cp = '\0'; - /* now process the whole line */ - n = loc_aton(buf, (u_char *)data); - if (n == 0) - goto err; - endline(fp); - break; - - - default: - goto err; - } - /* - * Ignore data outside the zone. - */ - if (zp->z_type != Z_CACHE && - !ns_samedomain(domain, zp->z_origin)) - { - ns_info(ns_log_load, - "%s:%d: data \"%s\" outside zone \"%s\" (ignored)", - filename, lineno, domain, - zp->z_origin); - continue; - } - if (ttl == USE_MINIMUM) /* no ttl set */ - ttl = 0; - dp = savedata(class, type, (u_int32_t)ttl, - (u_char *)data, (int)n); - dp->d_zone = zp - zones; - dp->d_flags = dataflags; - dp->d_cred = DB_C_ZONE; - dp->d_clev = clev; - c = db_set_update(domain, dp, &state, dbflags, - (dataflags & DB_F_HINT) != 0 ? - &fcachetab : &hashtab, - empty_from, &rrcount, lineno, - filename); - if (c == CNAMEANDOTHER) - errs++; - continue; - - case ERRTOK: - break; - } - err: - errs++; - ns_notice(ns_log_load, "%s:%d: %s error near (%s)", - filename, empty_token ? (lineno - 1) : lineno, - errtype, buf); - if (!empty_token) - endline(fp); - } - c = db_set_update(NULL, NULL, &state, dbflags, - (dataflags & DB_F_HINT) ? &fcachetab : &hashtab, - empty_from, &rrcount, lineno, filename); - if (c != OK) { - if (c == CNAMEANDOTHER) - errs++; - } - - (void) my_fclose(fp); - lineno = slineno; - if (!ininclude) { - if (didinclude) { - zp->z_flags |= Z_INCLUDE; - zp->z_ftime = 0; - } else - zp->z_ftime = sb.st_mtime; - zp->z_lastupdate = sb.st_mtime; - if (zp->z_type != Z_CACHE && zp->z_type != Z_HINT) { - const char *msg = NULL; - - if (read_soa == 0) - msg = "no SOA RR found"; - else if (read_soa != 1) - msg = "multiple SOA RRs found"; - else if (read_ns == 0) - msg = "no NS RRs found at zone top"; - else if (!rrcount) - msg = "no relevant RRs found"; - if (msg != NULL) { - errs++; - ns_warning(ns_log_load, - "Zone \"%s\" (file %s): %s", - zp->z_origin, filename, msg); - } - } - errs += purge_nonglue(zp->z_origin, - (dataflags & DB_F_HINT) ? fcachetab : - hashtab, zp->z_class); - while (filenames) { - fn = filenames; - filenames = filenames->next; - freestr(fn->name); - memput(fn, sizeof *fn); - } - if (errs != 0) - ns_warning(ns_log_load, - "%s zone \"%s\" (%s) rejected due to errors (serial %u)", - zoneTypeString(zp->z_type), zp->z_origin, - p_class(zp->z_class), zp->z_serial); - else - ns_info(ns_log_load, - "%s zone \"%s\" (%s) loaded (serial %u)", - zoneTypeString(zp->z_type), zp->z_origin, - p_class(zp->z_class), zp->z_serial); - } - if (errs != 0) { - zp->z_flags |= Z_DB_BAD; - zp->z_ftime = 0; - } -#ifdef BIND_NOTIFY - if (errs == 0 && (!ininclude) && - (zp->z_type == z_master || zp->z_type == z_slave)) - ns_notify(zp->z_origin, zp->z_class, ns_t_soa); -#endif - return (errs); -} - -void -db_err(int err, char *domain, int type, const char *filename, int lineno) { - if (filename != NULL && err == CNAMEANDOTHER) - ns_warning(ns_log_load, "%s:%d:%s: CNAME and OTHER data error", - filename, lineno, domain); - if (err != DATAEXISTS) - ns_debug(ns_log_load, 1, "update failed %s %d", - domain, type); -} - -static int -gettoken(FILE *fp, const char *src) { - int c; - char op[32]; - - for (;;) { - c = getc(fp); - top: - switch (c) { - case EOF: - return (EOF); - - case '$': - if (getword(op, sizeof op, fp, 0)) { - if (!strcasecmp("include", op)) - return (INCLUDE); - if (!strcasecmp("origin", op)) - return (ORIGIN); - if (!strcasecmp("generate", op)) - return (GENERATE); - if (!strcasecmp("ttl", op)) - return (DEFAULTTTL); - } - ns_notice(ns_log_db, - "%s:%d: Unknown $ option: $%s", - src, lineno, op); - return (ERRTOK); - - case ';': - while ((c = getc(fp)) != EOF && c != '\n') - ; - goto top; - - case ' ': - case '\t': - return (CURRENT); - - case '.': - return (DOT); - - case '@': - return (AT); - - case '\n': - lineno++; - continue; - - case '\r': - if (NS_OPTION_P(OPTION_TREAT_CR_AS_SPACE) != 0) - return (CURRENT); - - default: - (void) ungetc(c, fp); - return (DNAME); - } - } -} - -/* int - * getword(buf, size, fp, preserve) - * get next word, skipping blanks & comments. - * '\' '\n' outside of "quotes" is considered a blank. - * parameters: - * buf - destination - * size - of destination - * fp - file to read from - * preserve - should we preserve \ before \\ and \.? - * if preserve == 2, then keep all \ - * return value: - * 0 = no word; perhaps EOL or EOF; lineno was incremented. - * 1 = word was read - */ -int -getword(char *buf, size_t size, FILE *fp, int preserve) { - char *cp = buf; - int c, spaceok, once; - - empty_token = 0; /* XXX global side effect. */ - once = 0; - while ((c = getc(fp)) != EOF) { - once++; - if (c == ';') { - /* Comment. Skip to end of line. */ - while ((c = getc(fp)) != EOF && c != '\n') - (void)NULL; - c = '\n'; - } - if (c == '\n') { - /* - * Unescaped newline. It's a terminator unless we're - * already midway into a token. - */ - if (cp != buf) - ungetc(c, fp); - else - lineno++; - break; - } - if (c == '"') { - /* "Quoted string." Gather the whole string here. */ - while ((c = getc(fp)) != EOF && c!='"' && c!='\n') { - if (c == '\\') { - if ((c = getc(fp)) == EOF) - c = '\\'; - if (preserve) - switch (c) { - default: - if (preserve == 1) - break; - case '\\': - case '.': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (cp >= buf+size-1) - break; - *cp++ = '\\'; - } - if (c == '\n') - lineno++; - } - if (cp >= buf+size-1) - break; - *cp++ = c; - } - /* - * Newline string terminators are - * not token terminators. - */ - if (c == '\n') { - lineno++; - break; - } - /* Sample following character, check for terminator. */ - if ((c = getc(fp)) != EOF) - ungetc(c, fp); - if (c == EOF || isspace(c)) { - *cp = '\0'; - return (1); - } - continue; - } - spaceok = 0; - if (c == '\\') { - /* Do escape processing. */ - if ((c = getc(fp)) == EOF) - c = '\\'; - if (preserve) - switch (c) { - default: - if (preserve == 1) - break; - case '\\': - case '.': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (cp >= buf+size-1) - break; - *cp++ = '\\'; - } - if (c == ' ' || c == '\t') - spaceok++; - } - if (isspace(c) && !spaceok) { - /* Blank of some kind. Skip run. */ - while (isspace(c = getc(fp)) && c != '\n') - (void)NULL; - ungetc(c, fp); - /* Blank means terminator if the token is nonempty. */ - if (cp != buf) /* Trailing whitespace */ - break; - continue; /* Leading whitespace */ - } - if (cp >= buf + size - 1) - break; - *cp++ = (char)c; - } - *cp = '\0'; - if (cp == buf) - empty_token = 1; - if (!once) - lineno++; - return (cp != buf); -} - -/* - * int - * getttl(fp, fn, ln, ttl, multiline) - * read a word from the file and parse it as a TTL. - * return: - * 1 ttl found - * 0 word not read (EOF or EOL?) - * -1 word read but it wasn't a ttl - * side effects: - * *ttl is written if the return value is to be 1. - */ -int -getttl(FILE *fp, const char *fn, int lineno, u_int32_t *ttl, int *multiline) { - char buf[MAXDATA]; - u_long tmp; - int ch; - int len; - - while (!feof(fp) && !getword(buf, sizeof buf, fp, 0) && *multiline) - (void)NULL; - len = strlen(buf); - if (*multiline && len && buf[len-1] == ')') { - buf[len-1] = '\0'; - *multiline = 0; - } - if (ns_parse_ttl(buf, &tmp) < 0) { - ns_notice(ns_log_db, "%s:%d: expected a TTL, got \"%s\"", - fn, lineno, buf); - return (-1); - } - if (*multiline) { - ch = getnonblank(fp, fn); - if (ch == EOF) - return (-1); - if (ch == ';') - endline(fp); - else - ungetc(ch, fp); - } - *ttl = (u_int32_t)tmp; - return (1); -} - -/* Get multiline words. Same parameters as getword. Handles any - number of leading ('s or )'s in the words it sees. - FIXME: We kludge recognition of ( and ) for multiline input. - Each paren must appear at the start of a (blank-separated) word, - which is particularly counter-intuitive for ). Good enough for now, - until Paul rewrites the parser. (gnu@toad.com, oct96) -*/ -static int -getmlword(char *buf, size_t size, FILE *fp, int preserve) { - char *p; - - do { - while (!getword (buf, size, fp, preserve)) { - /* No more words on this line. See if doing the - multiline thing. */ - if (!getmlword_nesting) { /* Nope... */ - ungetc('\n', fp); /* Push back newline */ - lineno--; /* Unbump the lineno */ - empty_token = 0; /* Undo this botch */ - return 0; - } - if (feof(fp) || ferror(fp)) - return 0; /* Error, no terminating ')' */ - /* Continue reading til we get a word... */ - } - while ('(' == *buf) { - /* Word starts with paren. Multiline mode. - Move the rest of the word down over the paren. */ - getmlword_nesting++; - p = buf; - while (0 != (p[0]=p[1])) p++; - } - while (')' == *buf) { - getmlword_nesting--; - p = buf; - while (0 != (p[0]=p[1])) p++; - } - } while (buf[0] == 0); /* loop til we get a non-( non-) word */ - - return 1; /* Got a word... */ -} - -/* Get all the remaining words on a line, concatenated into one big - long (not too long!) string, with the whitespace squeezed out. - This routine, like getword(), does not swallow the newline if words seen. - This routine, unlike getword(), never swallows the newline if no words. - Parameters are the same as getword(). Result is: - 0 got no words at all - 1 got one or more words - -1 got too many words, they don't all fit; or missing close paren -*/ -static int -getallwords(char *buf, size_t size, FILE *fp, int preserve) { - char *runningbuf = buf; - int runningsize = size; - int len; - - while (runningsize > 0) { - if (!getmlword (runningbuf, runningsize, fp, preserve)) { - return runningbuf!=buf; /* 1 or 0 */ - } - len = strlen(runningbuf); - runningbuf += len; - runningsize -= len; - } - return -1; /* Error, String too long */ -} - -int -getnum(FILE *fp, const char *src, int opt) { - int c, n; - int seendigit = 0; - int seendecimal = 0; - int m = 0; - int allow_dots = 0; - - getnum_error = 0; -#ifdef DOTTED_SERIAL - if (opt & GETNUM_SERIAL) - allow_dots++; -#endif - for (n = 0; (c = getc(fp)) != EOF; ) { - if (isspace(c)) { - if (c == '\n') - lineno++; - if (seendigit) - break; - continue; - } - if (c == ';') { - while ((c = getc(fp)) != EOF && c != '\n') - ; - if (c == '\n') - lineno++; - if (seendigit) - break; - continue; - } - if (getnum_error) - continue; - if (!isdigit(c)) { - if (c == ')' && seendigit) { - (void) ungetc(c, fp); - break; - } - if (seendigit && (opt & GETNUM_SCALED) && - strchr("KkMmGg", c) != NULL) { - switch (c) { - case 'K': case 'k': - n *= 1024; - break; - case 'M': case 'm': - n *= (1024 * 1024); - break; - case 'G': case 'g': - n *= (1024 * 1024 * 1024); - break; - } - break; - } - if (seendecimal || c != '.' || !allow_dots) { - ns_notice(ns_log_db, - "%s:%d: expected a number", - src, lineno); - getnum_error = 1; - } else { - if (!seendigit) - n = 1; -#ifdef SENSIBLE_DOTS - n *= 10000; -#else - n *= 1000; -#endif - seendigit = 1; - seendecimal = 1; - } - continue; - } -#ifdef SENSIBLE_DOTS - if (seendecimal) - m = m * 10 + (c - '0'); - else - n = n * 10 + (c - '0'); -#else - n = n * 10 + (c - '0'); -#endif - seendigit = 1; - } - if (getnum_error) - return (0); - if (m > 9999) { - ns_info(ns_log_db, - "%s:%d: number after the decimal point exceeds 9999", - src, lineno); - getnum_error = 1; - return (0); - } - if (seendecimal) { - ns_info(ns_log_db, - "%s:%d: decimal serial number interpreted as %d", - src, lineno, n+m); - } - return (n + m); -} - -#ifndef BIND_UPDATE -static -#endif -int -getnonblank(FILE *fp, const char *src) { - int c; - - while ((c = getc(fp)) != EOF) { - if (isspace(c)) { - if (c == '\n') - lineno++; - continue; - } - if (c == ';') { - while ((c = getc(fp)) != EOF && c != '\n') - ; - if (c == '\n') - lineno++; - continue; - } - return (c); - } - ns_info(ns_log_db, "%s:%d: unexpected EOF", src, lineno); - return (EOF); -} - -/* - * Replace all single "$"'s in "name" with "it". - * ${delta} will add delta to "it" before printing. - * ${delta,width} will change print width as well, zero fill is implied - * ${delta,width,radix} will change radix as well, can be d, o, x, X. - * i.e. ${0,2,X} will produce a two digit hex (upper case) with zero fill. - * Append "origin" to name if required and validate result with makename. - * To get a "$" or "{" in the output use \ before it. - * Return 0 on no error or -1 on error. - * Resulting name stored in "buf". - */ - -static int -genname(char *name, int it, const char *origin, char *buf, int size) { - char *bp = buf; - char *eom = buf + size; - char *cp; - char numbuf[32]; - char fmt[32]; - int delta = 0; - int width; - - while (*name) { - if (*name == '$') { - if (*(++name) == '$') { - /* should be deprecated. how? */ - if (bp >= eom) - return (-1); - *bp++ = *name++; - } else { - strcpy(fmt, "%d"); - if (*name == '{') { - switch (sscanf(name, "{%d,%d,%1[doxX]}", &delta, &width, numbuf)) { - case 1: - break; - case 2: - sprintf(fmt, "%%0%dd", width); - break; - case 3: - sprintf(fmt, "%%0%d%c", width, numbuf[0]); - break; - default: - return (-1); - } - while (*name && *name++ != '}') { - continue; - } - } - sprintf(numbuf, fmt, it + delta); - cp = numbuf; - while (*cp) { - if (bp >= eom) - return (-1); - *bp++ = *cp++; - } - } - } else if (*name == '\\') { - if (*(++name) == '\0') { - if (bp >= eom) - return (-1); - *bp++ = '\\'; - } else { - switch (*name) { - case '\\': - case '.': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (bp >= eom) - return (-1); - *bp++ = '\\'; - default: - if (bp >= eom) - return (-1); - *bp++ = *name++; - } - } - } else { - if (bp >= eom) - return (-1); - *bp++ = *name++; - } - } - if (bp >= eom) - return (-1); - *bp = '\0'; - return (origin == NULL ? 0 : makename(buf, origin, size)); -} - - -/* - * Take name and fix it according to following rules: - * "." means root. - * "@" means current origin. - * "name." means no changes. - * "name" means append origin. - */ -int -makename(char *name, const char *origin, int size) { - int n; - u_char domain[MAXCDNAME]; - - switch (ns_name_pton(name, domain, sizeof(domain))) { - case -1: - return (-1); - case 1: /* FULLY QUALIFIED */ - break; - case 0: /* UNQUALIFIED */ - if (strcmp(name, "@") == 0) /* must test raw name */ - domain[0] = 0; - if ((n = dn_skipname(domain, domain+sizeof(domain))) == -1) - return (-1); - /* step back over root, append origin */ - switch (ns_name_pton(origin, domain+n-1, sizeof(domain)-n+1)) { - case -1: - return (-1); - case 0: - case 1: - break; - } - break; - } - if (ns_name_ntop(domain, name, size) == -1) - return (-1); - if (name[0] == '.') /* root */ - name[0] = '\0'; - return (0); -} - -int -makename_ok(char *name, const char *origin, int class, struct zoneinfo *zp, - enum transport transport, enum context context, - const char *owner, const char *filename, int lineno, int size) -{ - int ret = 1; - - if (makename(name, origin, size) == -1) { - ns_info(ns_log_db, "%s:%d: makename failed", - filename, lineno); - return (0); - } - if (!ns_nameok(NULL, name, class, zp, transport, context, owner, - inaddr_any)) { - ns_info(ns_log_db, "%s:%d: database naming error", - filename, lineno); - ret = 0; - } - return (ret); -} - -void -endline(FILE *fp) { - int c; - - while ((c = getc(fp)) != '\0') { - if (c == '\n') { - (void) ungetc(c,fp); - break; - } else if (c == EOF) { - break; - } - } -} - -#define MAXPORT 1024 -#define MAXLEN 24 - -#ifndef BIND_UPDATE -static -#endif -char -getprotocol(FILE *fp, const char *src) { - int k; - char b[MAXLEN]; - - (void) getword(b, sizeof(b), fp, 0); - - k = protocolnumber(b); - if (k == -1) - ns_info(ns_log_db, "%s:%d: unknown protocol: %s.", - src, lineno, b); - return ((char) k); -} - -#ifndef BIND_UPDATE -static -#endif -int -getservices(int offset, char *data, FILE *fp, const char *src) { - int j, ch, k, maxl, bracket; - char bm[MAXPORT/8]; - char b[MAXLEN]; - - for (j = 0; j < MAXPORT/8; j++) - bm[j] = 0; - maxl = 0; - bracket = 0; - while (getword(b, sizeof(b), fp, 0) || bracket) { - if (feof(fp) || ferror(fp)) - break; - if (strlen(b) == 0) - continue; - if (b[0] == '(') { - bracket++; - continue; - } - if (b[0] == ')') { - bracket = 0; - while ((ch = getc(fp)) != EOF && ch != '\n') - (void)NULL; - if (ch == '\n') - lineno++; - break; - } - k = servicenumber(b); - if (k == -1) { - ns_info(ns_log_db, - "%s:%d: Unknown service '%s'", - src, lineno, b); - continue; - } - if ((k < MAXPORT) && (k)) { - bm[k/8] |= (0x80>>(k%8)); - if (k > maxl) - maxl = k; - } else { - ns_info(ns_log_db, - "%s:%d: port no. (%d) too big", - src, lineno, k); - } - } - if (bracket) - ns_info(ns_log_db, "%s:%d: missing close paren", - src, lineno); - maxl = maxl/8+1; - memcpy(data+offset, bm, maxl); - return (maxl+offset); -} - -/* - * Converts a word to a u_int32_t. Error if any non-numeric - * characters in the word, except leading or trailing white space. - */ -static u_int32_t -wordtouint32(buf) - char *buf; -{ - u_long result; - u_int32_t res2; - char *bufend; - - wordtouint32_error = 0; - result = strtoul(buf, &bufend, 0); - if (bufend == buf) - wordtouint32_error = 1; - else - while ('\0' != *bufend) { - if (isspace(*bufend)) - bufend++; - else { - wordtouint32_error = 1; - break; - } - } - /* Check for truncation between u_long and u_int32_t */ - res2 = result; - if (res2 != result) - wordtouint32_error = 1; - return (res2); -} - -static int -getcharstring(char *buf, char *data, int type, - int minfields, int maxfields, - FILE *fp, const char *src) -{ - int nfield = 0, done = 0, n = 0, i; - char *b = buf; - - do { - nfield++; - i = strlen(buf); -#ifdef ALLOW_LONG_TXT_RDATA - b = buf; - if (type == ns_t_txt || type == ns_t_x25) { - while (i > MAXCHARSTRING - && n + MAXCHARSTRING + 1 < MAXDATA) { - data[n] = (char)MAXCHARSTRING; - memmove(data + n + 1, b, MAXCHARSTRING); - n += MAXCHARSTRING + 1; - b += MAXCHARSTRING; - i -= MAXCHARSTRING; - } - } -#endif /* ALLOW_LONG_TXT_RDATA */ - if (i > MAXCHARSTRING) { - ns_info(ns_log_db, - "%s:%d: RDATA field %d too long", - src, lineno -1, nfield); - return (0); - } - if (n + i + 1 > MAXDATA) { - ns_info(ns_log_db, - "%s:%d: total RDATA too long", - src, lineno -1); - return (0); - } - data[n] = i; - memmove(data + n + 1, b, (int)i); - n += i + 1; - done = (maxfields && nfield >= maxfields); - } while (!done && getword(buf, MAXDATA, fp, 0)); - - if (nfield < minfields) { - ns_info(ns_log_db, - "%s:%d: expected %d RDATA fields, only saw %d", - src, lineno -1, minfields, nfield); - return (0); - } - - if (done) - endline(fp); - - return (n); -} - - -/* - * get_nxt_types(): Read the list of types in the NXT record. - * - * Data is the array where the bit flags are stored; it must - * contain at least ns_t_any/NS_NXT_BITS bytes. - * FP is the input FILE *. - * Filename is the sourcefile - * - * The result is how many bytes are significant in the result. - * ogud@tis.com 1995 - */ -static int -get_nxt_types(u_char *data, FILE *fp, const char *filename) { - char b[MAXLABEL]; /* Not quite the right size, but good enough */ - int maxtype=0; - int success; - int type; - int errs = 0; - - memset(data, 0, NS_NXT_MAX/NS_NXT_BITS+1); - - while (getmlword(b, sizeof(b), fp, 0)) { - if (feof(fp) || ferror(fp)) - break; - if (strlen(b) == 0 || b[0] == '\n') - continue; - - /* Parse RR type (A, MX, etc) */ - type = sym_ston(__p_type_syms, (char *)b, &success); - if ((!success) || type == ns_t_any) { - errs++; - ns_info(ns_log_db, - "%s: Line %d: Unknown type: %s in NXT record.", - filename, lineno, b); - continue; - } - NS_NXT_BIT_SET(type, data); - if (type > maxtype) - maxtype = type; - } - if (errs) - return (0); - else - return (maxtype/NS_NXT_BITS+1); -} - -/* sanity checks PRIMARY ONLY */ -static void -fixup_soa(const char *fn, struct zoneinfo *zp) { - /* Sanity: give enough time for the zone to transfer (retry). */ - if (zp->z_expire < (zp->z_refresh + zp->z_retry)) - ns_notice(ns_log_db, - "%s: WARNING SOA expire value is less than SOA refresh+retry (%u < %u+%u)", - fn, zp->z_expire, zp->z_refresh, zp->z_retry); - - /* Sanity. */ - if (zp->z_expire < (zp->z_refresh + 10 * zp->z_retry)) - ns_warning(ns_log_db, -"%s: WARNING SOA expire value is less than refresh + 10 * retry \ -(%u < (%u + 10 * %u))", - fn, zp->z_expire, zp->z_refresh, zp->z_retry); - - /* - * Sanity: most hardware/telco faults are detected and fixed within - * a week, secondaries should continue to operate for this time. - * (minimum of 4 days for long weekends) - */ - if (zp->z_expire < (7 * 24 * 3600)) - ns_warning(ns_log_db, - "%s: WARNING SOA expire value is less than 7 days (%u)", - fn, zp->z_expire); - - /* - * Sanity: maximum down time if we havn't talked for six months - * war must have broken out. - */ - if (zp->z_expire > ( 183 * 24 * 3600)) - ns_warning(ns_log_db, - "%s: WARNING SOA expire value is greater than 6 months (%u)", - fn, zp->z_expire); - - /* Sanity. */ - if (zp->z_refresh < (zp->z_retry * 2)) - ns_warning(ns_log_db, - "%s: WARNING SOA refresh value is less than 2 * retry (%u < %u * 2)", - fn, zp->z_refresh, zp->z_retry); -} - -/* this function reads in the sig record rdata from the input file and - * returns the following codes - * > 0 length of the recrod - * ERR_EOF end of file - * - */ - -static int -parse_sig_rr(char *buf, int buf_len, u_char *data, int data_size, - FILE *fp, struct zoneinfo *zp, char *domain, u_int32_t ttl, - enum context domain_ctx, enum transport transport, char **errmsg) -{ -/* The SIG record looks like this in the db file: - Name Cl SIG RRtype Algid [OTTL] Texp Tsig Kfoot Signer Sig - - where: Name and Cl are as usual - SIG is a keyword - RRtype is a char string - ALGid is 8 bit u_int - Labels is 8 bit u_int - OTTL is 32 bit u_int (optionally present) - Texp is YYYYMMDDHHMMSS - Tsig is YYYYMMDDHHMMSS - Kfoot is 16-bit unsigned decimal integer - Signer is a char string - Sig is 64 to 319 base-64 digits - A missing OTTL is detected by the magnitude of the Texp value - that follows it, which is larger than any u_int. - The Labels field in the binary RR does not appear in the - text RR. - - It's too crazy to run these pages of SIG code at the right - margin. I'm exdenting them for readability. -*/ - u_int32_t sig_type; - int dateerror; - int siglen, success; - u_char *cp; - u_int32_t al, la, n; - u_int32_t signtime, exptime, timetilexp; - u_int32_t origTTL; - enum context context; - time_t now; - char *errtype = "SIG error"; - int i, my_buf_size = MAXDATA, errs = 0; - - - /* The TTL gets checked against the Original TTL, - and bounded by the signature expiration time, which - are both under the signature. We can't let TTL drift - based on the SOA record. If defaulted, fix it now. - (It's not clear to me why USE_MINIMUM isn't eliminated - before putting ALL RR's into the database. -gnu@toad.com) */ - if (ttl == USE_MINIMUM) - ttl = zp->z_minimum; - - i = 0; - data[i] = '\0'; - - getmlword_nesting = 0; /* KLUDGE err recovery */ - - /* RRtype (char *) - * if old style inp will contain the next token - *copy that into buffer, otherwise read from file - */ - if (buf && buf_len == 0) - if (!getmlword((char*)buf, my_buf_size, fp, 0)) - ERRTO("SIG record doesn't specify type"); - sig_type = sym_ston(__p_type_syms, buf, &success); - if (!success || sig_type == ns_t_any) { - /* - * We'll also accept a numeric RR type, - * for signing RR types that this version - * of named doesn't yet understand. - * In the ns_t_any case, we rely on wordtouint32 - * to fail when scanning the string "ANY". - */ - sig_type = wordtouint32 (buf); - if (wordtouint32_error || sig_type > 0xFFFF) - ERRTO("Unknown RR type in SIG record"); - } - cp = &data[i]; - PUTSHORT((u_int16_t)sig_type, cp); - i += 2; - - /* Algorithm id (8-bit decimal) */ - if (!getmlword(buf, my_buf_size, fp, 0)) - ERRTO("Missing algorithm ID"); - al = wordtouint32(buf); - if (0 == al || wordtouint32_error || 255 <= al) - ERRTO("Bad algorithm number"); - data[i] = (u_char) al; - i++; - - /* - * Labels (8-bit decimal) - */ - if (!getmlword(buf, my_buf_size, fp, 0)) - ERRTO("Missing label count"); - la = wordtouint32(buf); - if (wordtouint32_error || 255 <= la || - (0 == la && *domain != '\0')) - ERRTO("Bad label count number"); - data[i] = (u_char) la; - i++; - - /* - * OTTL (optional u_int32_t) and - * Texp (u_int32_t date) - */ - if (!getmlword(buf, my_buf_size, fp, 0)) - ERRTO("OTTL and expiration time missing"); - /* - * See if OTTL is missing and this is a date. - * This relies on good, silent error checking - * in ns_datetosecs. - */ - exptime = ns_datetosecs(buf, &dateerror); - if (!dateerror) { - /* Output TTL as OTTL */ - origTTL = ttl; - cp = &data[i]; - PUTLONG (origTTL, cp); - i += 4; - } else { - /* Parse and output OTTL; scan TEXP */ - origTTL = wordtouint32(buf); - if (0 >= origTTL || wordtouint32_error || - (origTTL > 0x7fffffff)) - ERRTO("Original TTL value bad"); - cp = &data[i]; - PUTLONG(origTTL, cp); - i += 4; - if (!getmlword(buf, my_buf_size, fp, 0)) - ERRTO("Expiration time missing"); - exptime = ns_datetosecs(buf, &dateerror); - } - if (dateerror || exptime > 0x7fffffff || exptime <= 0) - ERRTO("Invalid expiration time"); - cp = &data[i]; - PUTLONG(exptime, cp); - i += 4; - - /* Tsig (u_int32_t) */ - if (!getmlword(buf, my_buf_size, fp, 0)) - ERRTO("Missing signature time"); - signtime = ns_datetosecs(buf, &dateerror); - if (0 == signtime || dateerror) - ERRTO("Invalid signature time"); - cp = &data[i]; - PUTLONG(signtime, cp); - i += 4; - - /* Kfootprint (unsigned_16) */ - if (!getmlword(buf, my_buf_size, fp, 0)) - ERRTO("Missing key footprint"); - n = wordtouint32(buf); - if (wordtouint32_error || n >= 0x0ffff) - ERRTO("Invalid key footprint"); - cp = &data[i]; - PUTSHORT((u_int16_t)n, cp); - i += 2; - - /* Signer's Name */ - if (!getmlword((char*)buf, my_buf_size, fp, 0)) - ERRTO("Missing signer's name"); - cp = &data[i]; - strcpy((char *)cp, buf); - context = domain_ctx; - MAKENAME_OKZP((char *)cp, data_size); - i += strlen((char *)cp) + 1; - - /* - * Signature (base64 of any length) - * We don't care what algorithm it uses or what - * the internal structure of the BASE64 data is. - */ - if (!getallwords(buf, my_buf_size, fp, 0)) { - siglen = 0; - } else { - cp = &data[i]; - siglen = b64_pton(buf, (u_char*)cp, data_size - i); - if (siglen < 0) - ERRTO("Signature block bad"); - } - - /* set total length and we're done! */ - n = i + siglen; - - /* - * Check signature time, expiration, and adjust TTL. Note - * that all time values are in GMT (UTC), *not* local time. - */ - - now = time (0); /* need to find a better place for this XXX ogud */ - /* Don't let bogus name servers increase the signed TTL */ - if (ttl > origTTL) - ERRTO("TTL is greater than signed original TTL"); - - /* Don't let bogus signers "sign" in the future. */ - if (signtime > (u_int32_t)now) - ERRTO("signature time is in the future"); - - /* Ignore received SIG RR's that are already expired. */ - if (exptime <= (u_int32_t)now) - ERRTO("expiration time is in the past"); - - /* Lop off the TTL at the expiration time. */ - timetilexp = exptime - now; - if (timetilexp < ttl) { - ns_debug(ns_log_load, 1, - "shrinking expiring %s SIG TTL from %d to %d", - p_secstodate(exptime), ttl, timetilexp); - ttl = timetilexp; - } - - /* - * Check algorithm-ID and key structure, for - * the algorithm-ID's that we know about. - */ - switch (al) { - case NS_ALG_MD5RSA: - if (siglen == 0) - ERRTO("No key for RSA algorithm"); - if (siglen < 1) - ERRTO("Signature too short"); - if (siglen > (NS_MD5RSA_MAX_BITS + 7) / 8) - ERRTO("Signature too long"); - break; - - case NS_ALG_DH: - if (siglen < 1) - ERRTO("DH Signature too short"); - break; /* need more tests here */ - - case NS_ALG_DSA: - if (siglen < NS_DSA_SIG_SIZE) - ERRTO("DSS Signature too short"); - else if (siglen > NS_DSA_SIG_SIZE) - ERRTO("DSS Signature too long "); - break; /* need more tests here */ - - case NS_ALG_EXPIRE_ONLY: - if (siglen != 0) - ERRTO( - "Signature supplied to expire-only algorithm"); - break; - case NS_ALG_PRIVATE_OID: - if (siglen == 0) - ERRTO("No ObjectID in key"); - break; - default: - ERRTO("UNKOWN SIG algorithm"); - } - - /* Should we complain about algorithm-ID's that we - don't understand? It may help debug some obscure - cases, but in general we should accept any RR whether - we could cryptographically process it or not; it - may be being published for some newer DNS clients - to validate themselves. */ - - endline(fp); /* flush the rest of the line */ - - return (n); - err: - *errmsg = errtype; - return (-1); -} - -static int -parse_nxt_rr(char *buf, int buf_len, u_char *data, int data_size, - FILE *fp, struct zoneinfo *zp, char *domain, enum context context, - enum transport transport, char **errmsg) -{ - - /* The NXT record looks like: - Name Cl NXT nextname RRT1 RRT2 MX A SOA ... - - where: Name and Cl are as usual - NXT is a keyword - nextname is the next valid name in the zone after "Name". - All names between the two are known to be nonexistent. - RRT's... are a series of RR type names, which indicate that - RR's of these types are published for "Name", and - that no RR's of any other types are published for "Name". - - When a NXT record is cryptographically signed, it proves the - nonexistence of an RR (actually a whole set of RR's). - */ - int n, errs = 0, i; - u_char *cp; -/* char *origin = zp->z_origin; - int class = zp->z_class; */ - *errmsg = "NXT name error"; - - (void) strcpy((char *)data, buf); - MAKENAME_OKZP((char *)data, data_size); - n = strlen((char *)data) + 1; - cp = n + data; - i = get_nxt_types(cp, fp, zp->z_source); - if( i > 0) - return (n + i); - *errmsg = "NXT type error"; - err: - return (-1); -} - - -static int -parse_cert_rr(char *buf, int buf_len, u_char *data, int data_size, - FILE *fp, char **errmsg) -{ - /* Cert record looks like: - * Type Key_tag Alg Cert - * Type: certification type number (16) - * Key_tag: tag of corresponding KEY RR (16) - * Alg: algorithm of the KEY RR (8) - * Cert: base64 enocded block - */ - u_char *cp; - u_int32_t cert_type, key_tag, alg; - char *errtype = "CERT parse error"; - int certlen, i, n, success; - - i = 0; - cp = &data[i]; - cert_type = sym_ston(__p_cert_syms, buf, &success); - if (!success) { - cert_type = wordtouint32(buf); - if (wordtouint32_error || cert_type > 0xFFFF) - ERRTO("CERT type out of range"); - } - PUTSHORT((u_int16_t)cert_type, cp); - i += INT16SZ; - - if (!getmlword((char*)buf, buf_len, fp, 0)) - ERRTO("CERT doesn't specify type"); - - key_tag = wordtouint32(buf); - if (wordtouint32_error || key_tag > 0xFFFF) - ERRTO("CERT KEY tag out of range"); - - PUTSHORT((u_int16_t)key_tag, cp); - i += INT16SZ; - - if (!getmlword(buf, buf_len, fp, 0)) - ERRTO("CERT missing algorithm ID"); - - alg = sym_ston(__p_key_syms, buf, &success); - if (!success) { - alg = wordtouint32(buf); - if (wordtouint32_error || alg > 0xFF) - ERRTO("CERT KEY alg out of range"); - } - - data[i++] = (u_char)alg; - - if (!getallwords(buf, buf_len, fp, 0)) { - certlen = 0; - } - else { - cp = &data[i]; - certlen = b64_pton(buf, (u_char*)cp, sizeof(data) - i); - if (certlen < 0) - ERRTO("CERT blob has encoding error"); - } - /* set total length */ - n = i + certlen; - return (n); - err: - *errmsg = errtype; - return (-1); - -} - -static int -parse_key_rr(char *buf, int buf_len, u_char *data, int data_size, - FILE *fp, struct zoneinfo *zp, char *domain, enum context context, - enum transport transport, char **errmsg) -{ - /* The KEY record looks like this in the db file: - * Name Cl KEY Flags Proto Algid PublicKeyData - * where: - * Name,Cl per usual - * KEY RR type - * Flags 4 digit hex value (unsigned_16) - * Proto 8 bit u_int - * Algid 8 bit u_int - * PublicKeyData - * a string of base64 digits, - * skipping any embedded whitespace. - */ - u_int32_t al, pr; - int nk, klen,i, n; - u_int32_t keyflags; - char *errtype = "KEY error"; - u_char *cp, *expstart; - u_int expbytes, modbytes; - - i = n = 0; - data[i] = '\0'; - cp = data; - getmlword_nesting = 0; /* KLUDGE err recov. */ - - /*>>> Flags (unsigned_16) */ - keyflags = wordtouint32(buf); - if (wordtouint32_error || 0xFFFF < keyflags) - ERRTO("KEY flags error"); - if (keyflags & NS_KEY_RESERVED_BITMASK) - ERRTO("KEY Reserved Flag Bit"); - PUTSHORT(keyflags, cp); - - /*>>> Protocol (8-bit decimal) */ - if (!getmlword((char*)buf, buf_len, fp, 0)) - ERRTO("KEY Protocol Field"); - pr = wordtouint32(buf); - if (wordtouint32_error || 255 < pr) - ERRTO("KEY Protocol Field"); - *cp++ = (u_char) pr; - - /*>>> Algorithm id (8-bit decimal) */ - if (!getmlword((char*)buf, buf_len, fp, 0)) - ERRTO("KEY Algorithm ID"); - al = wordtouint32(buf); - if (wordtouint32_error || 0 == al || 255 == al || 255 < al) - ERRTO("KEY Algorithm ID"); - *cp++ = (u_char) al; - - /*>>> Extended KEY flag field in bytes 5 and 6 */ - if (NS_KEY_EXTENDED_FLAGS & keyflags) { - u_int32_t keyflags2; - - if (!getmlword((char*)buf, buf_len, fp, 0)) - ERRTO("KEY Flags Field"); - keyflags2 = wordtouint32(buf); - if (wordtouint32_error || 0xFFFF < keyflags2) - ERRTO("Extended key flags error"); - if (keyflags2 & NS_KEY_RESERVED_BITMASK2) - ERRTO("KEY Reserved Flag2 Bit"); - PUTSHORT(keyflags2, cp); - } - - /*>>> Public Key data is in BASE64. - * We don't care what algorithm it uses or what - * the internal structure of the BASE64 data is. - */ - if (!getallwords(buf, MAXDATA, fp, 0)) - klen = 0; - else { - /* Convert from BASE64 to binary. */ - klen = b64_pton(buf, (u_char*)cp, - data_size - (cp - data)); - if (klen < 0) - ERRTO("KEY Public Key"); - } - - /* set total length */ - n = klen + (cp - data); - - /* - * Now check for valid key flags & algs & etc, from the RFC. - */ - - if (NS_KEY_TYPE_NO_KEY == (keyflags & NS_KEY_TYPEMASK)) - nk = 1; /* No-key */ - else - nk = 0; /* have a key */ - - if ((keyflags & (NS_KEY_NAME_TYPE | NS_KEY_TYPEMASK)) == - (NS_KEY_NAME_ZONE | NS_KEY_TYPE_CONF_ONLY)) - /* Zone key must have Auth bit set. */ - ERRTO("KEY Zone Key Auth. bit"); - - if (al == 0 && nk == 0) - ERRTO("KEY Algorithm"); - if (al != 0 && pr == 0) - ERRTO("KEY Protocols"); - - if (nk == 1 && klen != 0) - ERRTO("KEY No-Key Flags Set"); - - if (nk == 0 && klen == 0) - ERRTO("KEY Type Spec'd"); - - /* - * Check algorithm-ID and key structure, for the algorithm-ID's - * that we know about. - */ - switch (al) { - case NS_ALG_MD5RSA: - if (klen == 0) - break; - expstart = cp; - expbytes = *expstart++; - if (expbytes == 0) - GETSHORT(expbytes, expstart); - - if (expbytes < 1) - ERRTO("Exponent too short"); - if (expbytes > (NS_MD5RSA_MAX_BITS + 7) / 8) - ERRTO("Exponent too long"); - if (*expstart == 0) - ERRTO("Exponent w/ 0"); - - modbytes = klen - (expbytes + (expstart - cp)); - if (modbytes < (NS_MD5RSA_MIN_BITS + 7) / 8) - ERRTO("Modulus too short"); - if (modbytes > (NS_MD5RSA_MAX_BITS + 7) / 8) - ERRTO("Modulus too long"); - if (*(expstart+expbytes) == 0) - ERRTO("Modulus starts w/ 0"); - break; - - case NS_ALG_DH: { - u_char *dh_cp; - u_int16_t dh_len, plen, glen, ulen; - - dh_cp = (u_char *)cp; - GETSHORT(plen, dh_cp); - if(plen < 16) - ERRTO("DH short plen"); - dh_len = 2 + plen; - if(dh_len > klen) - ERRTO("DH plen > klen"); - - GETSHORT(glen, dh_cp); - if(glen <= 0 || glen > plen) - ERRTO("DH glen bad"); - dh_len = 2 + glen; - if(dh_len > klen) - ERRTO("DH glen > klen"); - - GETSHORT(ulen, dh_cp); - if(ulen <= 0 || ulen > plen) - ERRTO("DH ulen bad"); - dh_len = 2 + ulen; - if(dh_len > klen) - ERRTO("DH ulen > klen"); - else if (dh_len < klen) - ERRTO("DH *len < klen"); - break; - } - - case NS_ALG_DSA: { - u_int8_t t; - - if ( klen == 0) - break; - t = *cp; - if (t > 8) - ERRTO("DSA T value"); - if (klen != (1 + 20 + 3 *(64+8*t))) - ERRTO("DSA length"); - break; - } - - case NS_ALG_PRIVATE_OID: - if (klen == 0) - ERRTO("No ObjectID in key"); - break; - default: - ERRTO("Unknown Key algorithm"); - } - - endline(fp); /* flush the rest of the line */ - return (n); - err: - *errmsg = errtype; - return (-1); -} /*T_KEY*/ - -/* - * function to invoke DNSSEC specific parsing routines. - * this is simpler than copying these complicated blocks into the - * multiple souce files that read files (ixfr, nsupdate etc..). - * this code should be in a library rather than in this file but - * what the heck for now (ogud@tislabs.com) - */ -int -parse_sec_rdata(char *buf, int buf_len, int buf_full, u_char *data, - int data_size, FILE *fp, struct zoneinfo *zp, - char *domain, u_int32_t ttl, int type, enum context context, - enum transport transport, char **errmsg) -{ - int ret = -1; - - getmlword_nesting = 0; /* KLUDGE err recov. */ - if (!buf_full && buf && buf_len != 0) /* check if any data in buf */ - if (!getmlword(buf, buf_len, fp, 1)) { - *errmsg = "unexpected end of input"; - goto err; - } - - switch (type) { - case ns_t_sig: - ret = parse_sig_rr(buf, buf_len, data, data_size, fp, zp, - domain, ttl, context, transport, errmsg); - break; - case ns_t_key: - ret = parse_key_rr(buf, buf_len, data, data_size, fp, zp, - domain, context, transport, errmsg); - break; - case ns_t_nxt: - ret = parse_nxt_rr(buf, buf_len, data, data_size, fp, zp, - domain, context, transport, errmsg); - break; - case ns_t_cert: - ret = parse_cert_rr(buf, buf_len, data, data_size, fp, errmsg); - break; - default: - ret = -1; - *errmsg = "parse_sec_rdata():Unsupported SEC type type"; - goto err; - } - return (ret); - err: - endline(fp); - return (ret); -} - diff --git a/contrib/bind/bin/named/db_lookup.c b/contrib/bind/bin/named/db_lookup.c deleted file mode 100644 index 00b3d8db4eab0..0000000000000 --- a/contrib/bind/bin/named/db_lookup.c +++ /dev/null @@ -1,341 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)db_lookup.c 4.18 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: db_lookup.c,v 8.26 2000/04/21 06:54:03 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Table lookup routines. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> - -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include "port_after.h" - -#include "named.h" - -/* - * Lookup 'name' and return a pointer to the namebuf; - * NULL otherwise. If 'insert', insert name into tables. - * Wildcard lookups are handled. - */ -struct namebuf * -nlookup(const char *name, struct hashbuf **htpp, - const char **fname, int insert) -{ - struct namebuf *np; - const char *cp; - int c; - u_int hval; - struct hashbuf *htp; - struct namebuf *parent = NULL; - int escaped = 0; - - htp = *htpp; - hval = 0; - *fname = "???"; - for (cp = name; (c = *cp++) != 0; (void)NULL) { - if (!escaped && (c == '.')) { - parent = np = nlookup(cp, htpp, fname, insert); - if (np == NULL) - return (NULL); - if (*fname != cp) - return (np); - if ((htp = np->n_hash) == NULL) { - if (!insert) { - if (ns_wildcard(NAME(*np))) - *fname = name; - return (np); - } - htp = savehash((struct hashbuf *)NULL); - np->n_hash = htp; - } - *htpp = htp; - break; - } - - HASHIMILATE(hval, c); - if (escaped) - escaped = 0; - else if (c == '\\') - escaped = 1; - } - cp--; - /* - * Lookup this label in current hash table. - */ - for (np = htp->h_tab[hval % htp->h_size]; - np != NULL; - np = np->n_next) { - if (np->n_hashval == hval && - ((size_t)NAMELEN(*np) == (size_t)(cp - name)) && - (strncasecmp(name, NAME(*np), cp - name) == 0)) { - *fname = name; - return (np); - } - } - if (!insert) { - /* - * Look for wildcard in this hash table. - * Don't use a cached "*" name as a wildcard, - * only authoritative. - */ - hval = ('*' & HASHMASK) % htp->h_size; - for (np = htp->h_tab[hval]; np != NULL; np = np->n_next) { - if (ns_wildcard(NAME(*np)) && - np->n_data && np->n_data->d_zone != 0) { - *fname = name; - return (np); - } - } - return (parent); - } - np = savename(name, cp - name); - np->n_parent = parent; - np->n_hashval = hval; - hval %= htp->h_size; - np->n_next = htp->h_tab[hval]; - htp->h_tab[hval] = np; - /* Increase hash table size. */ - if (++htp->h_cnt > (htp->h_size * AVGCH_NLOOKUP)) { - *htpp = savehash(htp); - if (parent == NULL) { - if (htp == hashtab) { - hashtab = *htpp; - } else { - fcachetab = *htpp; - } - } - else - parent->n_hash = *htpp; - htp = *htpp; - } - *fname = name; - return (np); -} - -/* struct namebuf * - * np_parent(struct namebuf *np) - * Find the "parent" namebuf of np. - * This is tricky since the parent of "com" is "" and both are stored - * in the same hashbuf. - * See also: - * the AXFR wart description in ns_axfr.c - */ -struct namebuf * -np_parent(struct namebuf *np) { - struct hashbuf *htp; - struct namebuf *np2; - - if (np->n_parent != NULL || NAME(*np)[0] == '\0') - return (np->n_parent); - - /* Try to figure out if np is pointing into the cache or hints. */ - /* Try the cache first. */ - htp = hashtab; - try_again: - /* Search the hash chain that np should be part of. */ - for (np2 = htp->h_tab[np->n_hashval % htp->h_size]; - np2 != NULL; - np2 = np2->n_next) - { - if (np == np2) { /* found it! */ - /* "" hashes into the first bucket */ - for (np = htp->h_tab[0]; np != NULL; np = np->n_next) { - if (NAME(*np)[0] == '\0') - /* found the root namebuf */ - return (np); - } - /* there are no RR's with a owner name of "." yet */ - return (NULL); - } - } - /* Try the hints. */ - if (htp == hashtab) { - htp = fcachetab; - goto try_again; - } - ns_debug(ns_log_db, 1, "np_parent(0x%lx) couldn't find namebuf", - (u_long)np); - return (NULL); /* XXX shouldn't happen */ -} - -/* int - * match(dp, class, type) - * Does data record `dp' match the class and type? - * return value: - * boolean - */ -int -match(struct databuf *dp, int class, int type) { - if (dp->d_class != class && class != C_ANY) - return (0); - if (dp->d_type != type && dp->d_type != T_SIG && type != T_ANY) - return (0); - if (type != T_SIG && dp->d_type == T_SIG && SIG_COVERS(dp) != type) - return (0); - return (1); -} - -/* static int - * nxtlower(name, dp) - * Is the NXT/SIG NXT record 'lower'? - * return value: - * boolean - */ -static int -nxtlower(const char *name, struct databuf *dp) { - /* An NXT is a lower NXT iff the SOA bit is set in the bitmap */ - if (dp->d_type == T_NXT) { - u_char *nxtbitmap = dp->d_data + strlen((char *)dp->d_data) + 1; - return (NS_NXT_BIT_ISSET(T_SOA, nxtbitmap) ? 1 : 0); - } - /* If it's not an NXT, it's a SIG NXT. An NXT record must be signed - * by the zone, so the signer name must be the same as the owner. - */ - return (ns_samename(name, (char *)dp->d_data + SIG_HDR_SIZE) != 1 ? 0 : 1); -} - -/* int - * nxtmatch(name, dp1, dp2) - * Do NXT/SIG NXT records `dp1' and `dp2' belong to the same NXT set? - * return value: - * boolean - */ -int -nxtmatch(const char *name, struct databuf *dp1, struct databuf *dp2) { - int dp1_lower, dp2_lower; - int type1, type2; - - if (dp1->d_type == ns_t_sig) - type1 = SIG_COVERS(dp1); - else - type1 = dp1->d_type; - if (dp2->d_type == ns_t_sig) - type2 = SIG_COVERS(dp2); - else - type2 = dp2->d_type; - - if (type1 != ns_t_nxt || type2 != ns_t_nxt) - return (0); - dp1_lower = nxtlower(name, dp1); - dp2_lower = nxtlower(name, dp2); - return (dp1_lower == dp2_lower); -} - -/* int - * rrmatch(name, dp1, dp2) - * Do data records `dp1' and `dp2' match in class and type? - * If both are NXTs, do they belong in the same NXT set? - * If both are SIGs, do the covered types match? - * If both are SIG NXTs, do the covered NXTs belong in the same set? - * Why is DNSSEC so confusing? - * return value: - * boolean - */ -int -rrmatch(const char *name, struct databuf *dp1, struct databuf *dp2) { - if (dp1->d_class != dp2->d_class && - dp1->d_class != C_ANY && dp2->d_class != C_ANY) - return(0); - if (dp1->d_type != dp2->d_type && - dp1->d_type != T_ANY && dp2->d_type != T_ANY) - return(0); - if (dp1->d_type == T_NXT) - return(nxtmatch(name, dp1, dp2)); - if (dp1->d_type != T_SIG) - return(1); - if (SIG_COVERS(dp1) == SIG_COVERS(dp2)) { - if (SIG_COVERS(dp1) == ns_t_nxt) - return(nxtmatch(name, dp1, dp2)); - else - return(1); - } - return(0); -} diff --git a/contrib/bind/bin/named/db_save.c b/contrib/bind/bin/named/db_save.c deleted file mode 100644 index 1fe0e73ff82f1..0000000000000 --- a/contrib/bind/bin/named/db_save.c +++ /dev/null @@ -1,211 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)db_save.c 4.16 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: db_save.c,v 8.27 2000/04/21 06:54:03 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Buffer allocation and deallocation routines. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" - -/* - * Allocate a name buffer & save name. - */ -struct namebuf * -savename(const char *name, int len) { - struct namebuf *np; - - /* - * Note that MAXLABEL * 4 < 256, so a single length byte is enough. - * Also, we use MAXLABEL * 4 because each label character can - * expand into up to four characters when rendered in canonical - * form. - */ - INSIST(len >= 0 && len <= (MAXLABEL * 4)); - np = (struct namebuf *) memget(NAMESIZE(len)); - if (np == NULL) - panic("savename: memget", NULL); - memset(np, 0, NAMESIZE(len)); - NAMELEN(*np) = (unsigned)len; - memcpy(NAME(*np), name, len); - NAME(*np)[len] = '\0'; - return (np); -} - -/* - * Allocate a data buffer & save data. - */ -struct databuf * -savedata(class, type, ttl, data, size) - int class, type; - u_int32_t ttl; - u_char *data; - int size; -{ - struct databuf *dp; - int bytes = DATASIZE(size); - - dp = (struct databuf *)memget(bytes); - if (dp == NULL) - panic("savedata: memget", NULL); - if (class > CLASS_MAX) - panic("savedata: bad class", NULL); - memset(dp, 0, bytes); - dp->d_next = NULL; - dp->d_type = type; - dp->d_class = class; - dp->d_ttl = ttl; - dp->d_size = size; - dp->d_mark = 0; - dp->d_flags = 0; - dp->d_cred = 0; - dp->d_clev = 0; - dp->d_secure = DB_S_INSECURE; - dp->d_rcode = NOERROR; - dp->d_ns = NULL; - dp->d_nstime = 0; - memcpy(dp->d_data, data, dp->d_size); - return (dp); -} - -/* - * Allocate a data buffer & save data. - */ -struct hashbuf * -savehash(oldhtp) - struct hashbuf *oldhtp; -{ - struct hashbuf *htp; - struct namebuf *np, *nnp, **hp; - int n, newsize; - - if (oldhtp == NULL) - newsize = hashsizes[0]; - else { - for (n = 0; (newsize = hashsizes[n++]) != 0; (void)NULL) - if (oldhtp->h_size == newsize) { - newsize = hashsizes[n]; - break; - } - if (newsize == 0) - newsize = oldhtp->h_size * 2 + 1; - } - ns_debug(ns_log_db, 4, "savehash GROWING to %d", newsize); - htp = (struct hashbuf *) memget(HASHSIZE(newsize)); - if (htp == NULL) - ns_panic(ns_log_db, 0, "savehash: %s", strerror(errno)); - htp->h_size = newsize; - memset(htp->h_tab, 0, newsize * sizeof(struct namebuf *)); - if (oldhtp == NULL) { - htp->h_cnt = 0; - return (htp); - } - ns_debug(ns_log_db, 4, "savehash(%#lx) cnt=%d, sz=%d, newsz=%d", - (u_long)oldhtp, oldhtp->h_cnt, oldhtp->h_size, newsize); - htp->h_cnt = oldhtp->h_cnt; - for (n = 0; n < oldhtp->h_size; n++) { - for (np = oldhtp->h_tab[n]; np != NULL; np = nnp) { - nnp = np->n_next; - hp = &htp->h_tab[np->n_hashval % htp->h_size]; - np->n_next = *hp; - *hp = np; - } - } - oldhtp->h_cnt = 0; /* Keep rm_hash() happy. */ - rm_hash(oldhtp); - return (htp); -} diff --git a/contrib/bind/bin/named/db_sec.c b/contrib/bind/bin/named/db_sec.c deleted file mode 100644 index 2ed4a4cc840a1..0000000000000 --- a/contrib/bind/bin/named/db_sec.c +++ /dev/null @@ -1,1097 +0,0 @@ - -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: db_sec.c,v 8.31 2000/04/21 06:54:04 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <ctype.h> -#include <resolv.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> -#include <isc/tree.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" - -struct zpubkey { - struct dst_key *zpk_key; /* Should be DST_KEY */ - char *zpk_name; - struct zpubkey *zpk_next; -}; - -typedef struct zpubkey *zpubkey_list; - -static int nxt_match_rrset(struct databuf *dp, struct db_rrset *rrset); - -/* - * A converted databuf is a stripped down databuf after converting the - * data to wire format. - */ -struct converted_databuf { - struct converted_databuf *cd_next; - u_char *cd_data; - int cd_size, cd_alloc; -}; - -/* All of the trusted keys and zone keys */ -static tree *trusted_keys = NULL; - -static int -compare_pubkey (struct zpubkey *zpk1, struct zpubkey *zpk2) { - char ta[NS_MAXDNAME], tb[NS_MAXDNAME]; - - if (ns_makecanon(zpk1->zpk_name, ta, sizeof ta) < 0 || - ns_makecanon(zpk2->zpk_name, tb, sizeof tb) < 0) - return (-1); - return (strcasecmp(ta, tb)); -} - -static struct zpubkey * -tree_srch_pubkey (const char *name) { - struct zpubkey tkey, *key; - - tkey.zpk_name = (char *) name; - if (trusted_keys == NULL) { - tree_init(&trusted_keys); - return (NULL); - } - key = (struct zpubkey *)tree_srch(&trusted_keys, compare_pubkey, - &tkey); - return (key); -} - -static DST_KEY * -find_public_key (const char *name, u_int16_t key_id) { - struct namebuf *knp; - struct hashbuf *htp; - struct databuf *dp; - const char *fname; - DST_KEY *key; - - ns_debug(ns_log_default, 5, "find_public_key(%s, %d)", name, key_id); - - htp = hashtab; - knp = nlookup (name, &htp, &fname, 0); - if (fname != name) - /* The name doesn't exist, so there's no key */ - return (NULL); - - for (dp = knp->n_data; dp != NULL; dp = dp->d_next) { - if (dp->d_type != ns_t_key || dp->d_secure < DB_S_SECURE) - continue; - key = dst_dnskey_to_key(name, dp->d_data, dp->d_size); - /* XXX what about multiple keys with same footprint? */ - if (key) { - if (key->dk_id == ntohs(key_id)) - return (key); - else - dst_free_key(key); - } - } - return (NULL); -} - - -static DST_KEY * -find_trusted_key (const char *name, u_int16_t key_id) { - struct zpubkey *zpk; - zpubkey_list keylist = tree_srch_pubkey (name); - - ns_debug(ns_log_default, 5, "find_trusted_key(%s, %d)", name, key_id); - - for (zpk = keylist; zpk; zpk = zpk->zpk_next) - if (zpk->zpk_key->dk_id == ntohs(key_id)) - return (zpk->zpk_key); - - return (NULL); -} - -int -add_trusted_key (const char *name, const int flags, const int proto, - const int alg, const char *str) -{ - zpubkey_list keylist; - struct zpubkey *zpk; - u_char buf[1024]; - int n; - - keylist = tree_srch_pubkey (name); - - zpk = (struct zpubkey *) memget (sizeof (struct zpubkey)); - if (zpk == NULL) - ns_panic(ns_log_default, 1, - "add_trusted_key: memget failed(%s)", name); - n = b64_pton(str, buf, sizeof(buf)); - if (n < 0) - goto failure; - zpk->zpk_key = dst_buffer_to_key(name, alg, flags, proto, buf, n); - if (zpk->zpk_key == NULL) { - ns_warning(ns_log_default, - "add_trusted_key: dst_buffer_to_key(%s) failed", - name); - goto failure; - } - zpk->zpk_name = zpk->zpk_key->dk_key_name; - zpk->zpk_next = NULL; - - if (keylist == NULL) { - if (tree_add (&trusted_keys, compare_pubkey, zpk, NULL) == NULL) - goto failure; - } - else { - struct zpubkey *tkey = keylist; - while (tkey->zpk_next) - tkey = tkey->zpk_next; - tkey->zpk_next = zpk; - } - - return (1); - failure: - memput(zpk, sizeof (struct zpubkey)); - return (0); -} - -/* Can the signer sign records for this name? This is a heuristic. */ -static int -can_sign(const char *name, const char *signer) { - return (ns_samedomain(name, signer) && - dn_count_labels(name) - dn_count_labels(signer) <= 2); -} - -static int -rrset_set_security(struct db_rrset *rrset, int slev) { - struct dnode *dnp; - - for (dnp = rrset->rr_list; dnp != NULL; dnp = dnp->dn_next) - dnp->dp->d_secure = slev; - for (dnp = rrset->rr_sigs; dnp != NULL; dnp = dnp->dn_next) - dnp->dp->d_secure = slev; - return (slev); -} - -static int -convert_databuf(struct databuf *dp, struct converted_databuf *cdp) { - u_char *bp = cdp->cd_data; - u_char *cp = dp->d_data; - u_char *eob = cdp->cd_data + cdp->cd_alloc; - int len; - u_char buf[MAXDNAME]; - - switch (dp->d_type) { - case ns_t_soa: - case ns_t_minfo: - case ns_t_rp: - if (eob - bp < strlen((char *)cp) + 1) - return (-1); - if (ns_name_pton((char *)cp, buf, sizeof buf) < 0) - return (-1); - len = ns_name_ntol(buf, bp, eob - bp); - if (len < 0) - return (-1); - bp += len; - cp += strlen((char *)cp) + 1; - - if (eob - bp < strlen((char *)cp) + 1) - return (-1); - if (ns_name_pton((char *)cp, buf, sizeof buf) < 0) - return (-1); - len = ns_name_ntol(buf, bp, eob - bp); - if (len < 0) - return (-1); - bp += len; - cp += strlen((char *)cp) + 1; - - if (dp->d_type == ns_t_soa) { - if (eob - bp < 5 * INT32SZ) - return (-1); - memcpy(bp, cp, 5 * INT32SZ); - bp += (5 * INT32SZ); - cp += (5 * INT32SZ); - } - - break; - - case ns_t_ns: - case ns_t_cname: - case ns_t_mb: - case ns_t_mg: - case ns_t_mr: - case ns_t_ptr: - case ns_t_nxt: - if (eob - bp < strlen((char *)cp) + 1) - return (-1); - if (ns_name_pton((char *)cp, buf, sizeof buf) < 0) - return (-1); - len = ns_name_ntol(buf, bp, eob - bp); - if (len < 0) - return (-1); - bp += len; - cp += (len = strlen((char *)cp) + 1); - - if (dp->d_type == ns_t_nxt) { - if (eob - bp < dp->d_size - len) - return (-1); - memcpy(bp, cp, dp->d_size - len); - bp += (dp->d_size - len); - cp += (dp->d_size - len); - } - break; - - case ns_t_srv: - if (eob - bp < 2 * INT16SZ) - return (-1); - memcpy(bp, cp, 2 * INT16SZ); - bp += (2 * INT16SZ); - cp += (2 * INT16SZ); - /* no break */ - case ns_t_rt: - case ns_t_mx: - case ns_t_afsdb: - case ns_t_px: - if (eob - bp < INT16SZ) - return (-1); - memcpy (bp, cp, INT16SZ); - bp += INT16SZ; - cp += INT16SZ; - - if (eob - bp < strlen((char *)cp) + 1) - return (-1); - if (ns_name_pton((char *)cp, buf, sizeof buf) < 0) - return (-1); - len = ns_name_ntol(buf, bp, eob - bp); - if (len < 0) - return (-1); - bp += len; - cp += strlen((char *)cp) + 1; - - if (dp->d_type == ns_t_px) { - if (eob - bp < strlen((char *)cp) + 1) - return (-1); - if (ns_name_pton((char *)cp, buf, sizeof buf) < 0) - return (-1); - len = ns_name_ntol(buf, bp, eob - bp); - if (len < 0) - return (-1); - bp += len; - cp += strlen((char *)cp) + 1; - } - break; - - default: - if (eob - bp < dp->d_size) - return (-1); - memcpy(bp, cp, dp->d_size); - bp += dp->d_size; - } - cdp->cd_size = bp - cdp->cd_data; - return (cdp->cd_size); -} - -static int -digest_rr(char *envelope, int elen, struct converted_databuf *cdp, - char *buffer, int blen) -{ - char *bp = buffer, *eob = buffer + blen; - - if (eob - bp < elen) - return (-1); - memcpy (bp, envelope, elen); - bp += elen; - - if (eob - bp < INT16SZ) - return (-1); - PUTSHORT(cdp->cd_size, bp); - - if (eob - bp < cdp->cd_size) - return (-1); - memcpy (bp, cdp->cd_data, cdp->cd_size); - bp += cdp->cd_size; - - return (bp - buffer); -} - -/* Sorts the converted databuf in the list */ -static void -insert_converted_databuf(struct converted_databuf *cdp, - struct converted_databuf **clist) -{ - struct converted_databuf *tcdp, *next; - int t; - -#define compare_cdatabuf(c1, c2, t) \ - (t = memcmp(c1->cd_data, c2->cd_data, MIN(c1->cd_size, c2->cd_size)), \ - t == 0 ? c1->cd_size - c2->cd_size : t) - - if (*clist == NULL) { - *clist = cdp; - return; - } - - tcdp = *clist; - if (compare_cdatabuf(cdp, tcdp, t) < 0) { - cdp->cd_next = tcdp; - *clist = cdp; - return; - } - - next = tcdp->cd_next; - while (next) { - if (compare_cdatabuf(cdp, next, t) < 0) { - cdp->cd_next = next; - tcdp->cd_next = cdp; - return; - } - tcdp = next; - next = next->cd_next; - } - tcdp->cd_next = cdp; -#undef compare_cdatabuf -} - -static void -free_clist(struct converted_databuf *clist) { - struct converted_databuf *cdp; - - while (clist != NULL) { - cdp = clist; - clist = clist->cd_next; - memput(cdp->cd_data, cdp->cd_alloc); - memput(cdp, sizeof(struct converted_databuf)); - } -} - -/* Removes all empty nodes from an rrset's SIG list. */ -static void -rrset_trim_sigs(struct db_rrset *rrset) { - struct dnode *dnp, *odnp, *ndnp; - - odnp = NULL; - dnp = rrset->rr_sigs; - while (dnp != NULL) { - if (dnp->dp != NULL) { - odnp = dnp; - dnp = dnp->dn_next; - } - else { - if (odnp != NULL) - odnp->dn_next = dnp->dn_next; - else - rrset->rr_sigs = dnp->dn_next; - ndnp = dnp->dn_next; - memput(dnp, sizeof(struct dnode)); - dnp = ndnp; - } - } -} - -int -verify_set(struct db_rrset *rrset) { - DST_KEY *key = NULL; - struct sig_record *sigdata; - struct dnode *sigdn; - struct databuf *sigdp; - time_t now; - char *signer; - u_char name_n[MAXDNAME]; - u_char *sig, *eom; - int trustedkey = 0, siglen, labels, len = 0, ret; - u_char *buffer = NULL, *bp; - u_char envelope[MAXDNAME+32], *ep; - struct dnode *dnp; - int bufsize = 2048; /* Large enough for MAXDNAME + SIG_HDR_SIZE */ - struct converted_databuf *clist = NULL, *cdp; - int dnssec_failed = 0, dnssec_succeeded = 0; - int return_value; - int i; - - if (rrset == NULL || rrset->rr_name == NULL) { - ns_warning (ns_log_default, "verify_set: missing rrset/name"); - return (rrset_set_security(rrset, DB_S_FAILED)); - } - - if (rrset->rr_sigs == NULL) - return (rrset_set_security(rrset, DB_S_INSECURE)); - - ns_debug(ns_log_default, 5, "verify_set(%s, %s, %s)", rrset->rr_name, - p_type(rrset->rr_type), p_class(rrset->rr_class)); - - now = time(NULL); - - for (sigdn = rrset->rr_sigs; sigdn != NULL; sigdn = sigdn->dn_next) { - u_int32_t namefield; - struct sig_record sigrec; - - sigdp = sigdn->dp; - - eom = sigdp->d_data + sigdp->d_size; - if (sigdp->d_size < SIG_HDR_SIZE) { - return_value = DB_S_FAILED; - goto end; - } - memcpy(&sigrec, sigdp->d_data, SIG_HDR_SIZE); - sigdata = &sigrec; - signer = (char *)sigdp->d_data + SIG_HDR_SIZE; - sig = (u_char *)signer + strlen(signer) + 1; - siglen = eom - sig; - - /* - * Don't verify a set if the SIG inception time is in - * the future. This should be fixed before 2038 (BEW) - */ - if (ntohl(sigdata->sig_time_n) > now) - continue; - - /* An expired set is dropped, but the data is not. */ - if (ntohl(sigdata->sig_exp_n) < now) { - db_freedata(sigdp); - sigdn->dp = NULL; - continue; - } - - /* Cleanup from the last iteration if we continue'd */ - if (trustedkey == 0 && key != NULL) - dst_free_key(key); - - key = find_trusted_key(signer, sigdata->sig_keyid_n); - - if (key == NULL) { - trustedkey = 0; - key = find_public_key(signer, sigdata->sig_keyid_n); - } - else - trustedkey = 1; - - /* if we don't have the key, either - * - the data should be considered insecure - * - the sig is not a dnssec signature - */ - if (key == NULL) - continue; - - /* Can a key with this name sign the data? */ - if (!can_sign(rrset->rr_name, signer)) - continue; - - /* Check the protocol and flags of the key */ - if (key->dk_proto != NS_KEY_PROT_DNSSEC && - key->dk_proto != NS_KEY_PROT_ANY) - continue; - if (key->dk_flags & NS_KEY_NO_AUTH) - continue; - namefield = key->dk_flags & NS_KEY_NAME_TYPE; - if (namefield == NS_KEY_NAME_USER || - namefield == NS_KEY_NAME_RESERVED) - continue; - if (namefield == NS_KEY_NAME_ENTITY && - (key->dk_flags & NS_KEY_SIGNATORYMASK == 0)) - continue; - - /* - * If we're still here, we have a non-null key that's either - * a zone key or an entity key with signing authority. - */ - - if (buffer == NULL) { - bp = buffer = memget(bufsize); - if (bp == NULL) { - return_value = DB_S_FAILED; - goto end; - } - } - else - bp = buffer; - - - /* Digest the fixed portion of the SIG record */ - memcpy(bp, (char *) sigdata, SIG_HDR_SIZE); - bp += SIG_HDR_SIZE; - - /* Digest the signer's name, canonicalized */ - if (ns_name_pton(signer, name_n, sizeof name_n) < 0) { - return_value = DB_S_FAILED; - goto end; - } - i = ns_name_ntol(name_n, (u_char *)bp, bufsize - SIG_HDR_SIZE); - if (i < 0) { - return_value = DB_S_FAILED; - goto end; - } - bp += i; - - /* create the dns record envelope: - * <name><type><class><Original TTL> - */ - if (ns_name_pton(rrset->rr_name, name_n, sizeof name_n) < 0 || - ns_name_ntol(name_n, (u_char *)envelope, sizeof envelope) < 0) { - return_value = DB_S_FAILED; - goto end; - } - - labels = dn_count_labels(rrset->rr_name); - if (labels > sigdata->sig_labels_n) { - ep = envelope; - for (i=0; i < (labels - 1 - sigdata->sig_labels_n); i++) - ep += (*ep+1); - i = dn_skipname(ep, envelope + sizeof envelope); - if (i < 0) { - return_value = DB_S_FAILED; - goto end; - } - envelope[0] = '\001'; - envelope[1] = '*'; - memmove(envelope + 2, ep, i); - } - i = dn_skipname(envelope, envelope + sizeof envelope); - if (i < 0) { - return_value = DB_S_FAILED; - goto end; - } - ep = envelope + i; - PUTSHORT (rrset->rr_type, ep); - PUTSHORT (rrset->rr_class, ep); - if (envelope + sizeof(envelope) - ep < INT32SZ) { - return_value = DB_S_FAILED; - goto end; - } - memcpy (ep, &sigdata->sig_ottl_n, INT32SZ); - ep += INT32SZ; - - if (clist == NULL) { - for (dnp = rrset->rr_list; - dnp != NULL; - dnp = dnp->dn_next) - { - struct databuf *dp = dnp->dp; - - cdp = memget(sizeof(struct converted_databuf)); - if (cdp == NULL) { - return_value = DB_S_FAILED; - goto end; - } - memset(cdp, 0, sizeof(*cdp)); - /* Should be large enough... */ - cdp->cd_alloc = dp->d_size + 8; - cdp->cd_data = memget(cdp->cd_alloc); - if (cdp->cd_data == NULL) { - memput(cdp, sizeof(*cdp)); - return_value = DB_S_FAILED; - goto end; - } - while (convert_databuf(dp, cdp) < 0) { - memput(cdp->cd_data, cdp->cd_alloc); - cdp->cd_alloc *= 2; - cdp->cd_data = memget(cdp->cd_alloc); - if (cdp->cd_data == NULL) { - memput(cdp, sizeof(*cdp)); - return_value = DB_S_FAILED; - goto end; - } - } - insert_converted_databuf(cdp, &clist); - } - } - - for (cdp = clist; cdp != NULL; cdp = cdp->cd_next) { - len = digest_rr((char *)envelope, ep-envelope, cdp, - (char *)bp, bufsize - (bp - buffer)); - while (len < 0) { - u_char *newbuf; - - /* Double the buffer size */ - newbuf = memget(bufsize*2); - if (newbuf == NULL) { - return_value = DB_S_FAILED; - goto end; - } - memcpy(newbuf, buffer, bp - buffer); - bp = (bp - buffer) + newbuf; - memput(buffer, bufsize); - buffer = newbuf; - bufsize *= 2; - - len = digest_rr((char *)envelope, ep-envelope, - cdp, (char *)bp, - bufsize - (bp - buffer)); - } - bp += len; - } - - if (len < 0) { - return_value = DB_S_FAILED; - goto end; - } - - ret = dst_verify_data(SIG_MODE_ALL, key, NULL, buffer, - bp - buffer, sig, siglen); - - if (ret < 0) { - dnssec_failed++; - db_freedata(sigdp); - sigdn->dp = NULL; - } - else - dnssec_succeeded++; - } - -end: - if (dnssec_failed > 0) - rrset_trim_sigs(rrset); - if (trustedkey == 0 && key != NULL) - dst_free_key(key); - - if (dnssec_failed > 0 && dnssec_succeeded == 0) { - ns_warning (ns_log_default, - "verify_set(%s, %s, %s) failed", - rrset->rr_name, p_type(rrset->rr_type), - p_class(rrset->rr_class)); - return_value = DB_S_FAILED; - } - else if (dnssec_succeeded > 0) - return_value = DB_S_SECURE; - else - return_value = DB_S_INSECURE; - free_clist(clist); - if (buffer != NULL) - memput(buffer, bufsize); - return (rrset_set_security(rrset, return_value)); -} - -static void -rrset_free_partial(struct db_rrset *rrset, int free_data, struct dnode *start) { - struct dnode *dnp; - int found_start = 0; - - ns_debug(ns_log_default, 5, "rrset_free(%s)", rrset->rr_name); - - if (start == NULL) - found_start = 1; - - while (rrset->rr_list) { - dnp = rrset->rr_list; - if (dnp == start) - found_start = 1; - rrset->rr_list = rrset->rr_list->dn_next; - if (dnp->dp != NULL && free_data == 1 && found_start == 1) - db_freedata(dnp->dp); - memput(dnp, sizeof(struct dnode)); - } - while (rrset->rr_sigs) { - dnp = rrset->rr_sigs; - if (dnp == start) - found_start = 1; - rrset->rr_sigs = rrset->rr_sigs->dn_next; - if (dnp->dp != NULL && free_data == 1 && found_start == 1) - db_freedata(dnp->dp); - memput(dnp, sizeof(struct dnode)); - } -} - -static void -rrset_free(struct db_rrset *rrset, int free_data) { - rrset_free_partial(rrset, free_data, NULL); -} - -/* - * This is called when we have an rrset with SIGs and no other data. - * Returns 1 if we either found the necessary data or if the SIG can be added - * with no other data. 0 indicates that the SIG cannot be added. - */ -static int -attach_data(struct db_rrset *rrset) { - int type, class; - struct databuf *dp, *newdp, *sigdp; - struct dnode *dnp; - struct namebuf *np; - struct hashbuf *htp; - char *signer; - const char *fname; - char *name = rrset->rr_name; - - sigdp = rrset->rr_sigs->dp; - - type = SIG_COVERS(sigdp); - class = sigdp->d_class; - signer = (char *)(sigdp + SIG_HDR_SIZE); - - /* First, see if the signer can sign data for the name. If not, - * it's not a DNSSEC signature, so we can insert it with no - * corresponding data. - */ - if (!can_sign(name, signer)) - return (1); - - htp = hashtab; - np = nlookup (name, &htp, &fname, 0); - if (fname != name) - return (0); - - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (dp->d_type == type && dp->d_class == class) { - newdp = savedata(class, type, dp->d_ttl, dp->d_data, - dp->d_size); - dnp = (struct dnode *) memget (sizeof (struct dnode)); - if (dnp == NULL) - ns_panic(ns_log_default, 1, - "attach_data: memget failed"); - dnp->dp = newdp; - dnp->dn_next = rrset->rr_list; - rrset->rr_list = dnp; - } - } - if (rrset->rr_list != NULL) - return (1); - else - return (0); -} - -static int -rrset_db_update(struct db_rrset *rrset, int flags, struct hashbuf **htpp, - struct sockaddr_in from, int *rrcount) -{ - struct dnode *dnp; - struct databuf *dp; - int ret; - - /* If we have any unattached SIG records that are DNSSEC signatures, - * don't cache them unless we already have the corresponding data. - * If we do cache unattached SIGs, we run into problems later if we - * have a SIG X and get a query for type X. - */ - if (rrset->rr_list == NULL) { - if (attach_data(rrset) == 0) { - rrset_free(rrset, 1); - return (OK); - } - - if (rrset->rr_list != NULL && - verify_set(rrset) == DB_S_FAILED) - { - rrset_free(rrset, 1); - return (OK); - } - } - - for (dnp = rrset->rr_list; dnp != NULL; dnp = dnp->dn_next) { - dp = dnp->dp; - ret = db_update(rrset->rr_name, dp, dp, NULL, - flags, (*htpp), from); - if (ret != OK) { - /* XXX Probably should do rollback. */ - db_err(ret, rrset->rr_name, dp->d_type, - dnp->file, dnp->line); - if (ret != DATAEXISTS) { - rrset_free_partial(rrset, 1, dnp); - return (ret); - } - db_freedata(dp); - } - if (rrcount != NULL) - (*rrcount)++; - dnp->dp = NULL; - } - for (dnp = rrset->rr_sigs; dnp != NULL; dnp = dnp->dn_next) { - dp = dnp->dp; - if (dp == NULL) /* verifyset() can remove sigs */ - continue; - ret = db_update(rrset->rr_name, dp, dp, NULL, - flags, (*htpp), from); - if (ret != OK) { - /* XXX Probably should do rollback. */ - db_err(ret, rrset->rr_name, dp->d_type, - dnp->file, dnp->line); - if (ret != DATAEXISTS) { - rrset_free_partial(rrset, 1, dnp); - return (ret); - } - db_freedata(dp); - } - if (rrcount != NULL) - (*rrcount)++; - dnp->dp = NULL; - } - rrset_free(rrset, 0); - return (OK); -} - -static int -rr_in_set(struct databuf *rr, struct dnode *set) { - struct dnode *dnp; - - if (set == NULL) - return (0); - - for(dnp = set; dnp != NULL; dnp = dnp->dn_next) { - if (dnp->dp->d_size == rr->d_size && - memcmp(dnp->dp->d_data, rr->d_data, dnp->dp->d_size) == 0) - return (1); - } - return (0); -} - -static int -add_to_rrset_list(struct db_rrset **rrsets, char *name, struct databuf *dp, - int line, const char *file) -{ - struct db_rrset *rrset = *rrsets; - struct dnode *dnp; - - while (rrset != NULL) { - if (rrset->rr_type != ns_t_nxt || dp->d_type != ns_t_nxt) { - if (dp->d_type == ns_t_sig) { - if (SIG_COVERS(dp) == rrset->rr_type) - break; - } else { - if (dp->d_type == rrset->rr_type) - break; - } - } - else if (nxt_match_rrset(dp, rrset)) - break; - rrset = rrset->rr_next; - } - - if (rrset != NULL) { - if ((dp->d_type == ns_t_sig && rr_in_set(dp, rrset->rr_sigs)) || - (dp->d_type != ns_t_sig && rr_in_set(dp, rrset->rr_list))) - { - db_freedata(dp); - return (DATAEXISTS); - } - } else { - rrset = (struct db_rrset *) memget(sizeof(struct db_rrset)); - if (rrset == NULL) - ns_panic(ns_log_default, 1, - "add_to_rrset_list: memget failed(%s)", name); - memset(rrset, 0, sizeof(struct db_rrset)); - rrset->rr_name = savestr(name, 1); - rrset->rr_class = dp->d_class; - if (dp->d_type == ns_t_sig) - rrset->rr_type = SIG_COVERS(dp); - else - rrset->rr_type = dp->d_type; - rrset->rr_next = *rrsets; - *rrsets = rrset; - } - - dnp = (struct dnode *) memget(sizeof(struct dnode)); - if (dnp == NULL) - ns_panic(ns_log_default, 1, - "add_to_rrset_list: memget failed(%s)", name); - memset(dnp, 0, sizeof(struct dnode)); - dnp->dp = dp; - if (dp->d_type == ns_t_sig) { - if (rrset->rr_sigs != NULL) { - struct dnode *fdnp; - - /* Preserve the order of the RRs */ - /* Add this one to the end of the list */ - for (fdnp = rrset->rr_sigs; - fdnp->dn_next != NULL; - fdnp = fdnp->dn_next) - /* NULL */ ; - fdnp->dn_next = dnp; - } else - rrset->rr_sigs = dnp; - } else { - if (rrset->rr_list != NULL) { - struct dnode *fdnp; - - /* Preserve the order of the RRs */ - /* Add this one to the end of the list */ - for (fdnp = rrset->rr_list; - fdnp->dn_next != NULL; - fdnp = fdnp->dn_next) - /* NULL */ ; - fdnp->dn_next = dnp; - } else - rrset->rr_list = dnp; - } - dnp->file = (char *) file; - dnp->line = line; - return (0); -} - -static int -update_rrset_list(struct db_rrset **rrsets, int flags, struct hashbuf **htpp, - struct sockaddr_in from, int *rrcount) -{ - struct db_rrset *rrset = *rrsets, *next = NULL, *last = NULL; - int result = 0, tresult, cnameandother = 0; - - while (rrset != NULL) { - if (rrset->rr_type == ns_t_key) - break; - last = rrset; - rrset = rrset->rr_next; - } - - if (rrset != NULL && last != NULL) { - last->rr_next = rrset->rr_next; - rrset->rr_next = *rrsets; - *rrsets = rrset; - } - - rrset = *rrsets; - - while (rrset != NULL) { - if (verify_set(rrset) > DB_S_FAILED) { - ns_debug(ns_log_default, 10, - "update_rrset_list(%s, %s): set verified", - rrset->rr_name, p_type(rrset->rr_type)); - tresult = rrset_db_update(rrset, flags, htpp, - from, rrcount); - if (tresult == CNAMEANDOTHER) - cnameandother++; - if (tresult != OK) - result = tresult; - } - else { - rrset_free(rrset, 1); - result = DNSSECFAIL; - } - freestr(rrset->rr_name); - next = rrset->rr_next; - memput(rrset, sizeof(struct db_rrset)); - rrset = next; - } - *rrsets = NULL; - if (cnameandother != 0) - return (CNAMEANDOTHER); - return (result); -} - -int -db_set_update(char *name, struct databuf *dp, void **state, - int flags, struct hashbuf **htpp, struct sockaddr_in from, - int *rrcount, int line, const char *file) -{ - struct db_rrset **rrsets; - struct db_rrset *rrset; - int result = 0; - - ns_debug(ns_log_default, 5, "db_set_update(%s)", - (name == NULL) ? "<NULL>" : (*name == 0) ? "." : name); - - if (state == NULL) - ns_panic(ns_log_default, 1, - "Called db_set_update with state == NULL"); - - rrsets = (struct db_rrset **) state; - - if (*rrsets != NULL) { - rrset = *rrsets; - if (rrset->rr_name != NULL && dp != NULL && - name != NULL && ns_samename(name, rrset->rr_name) == 1 && - dp->d_class == rrset->rr_class) - return (add_to_rrset_list(rrsets, name, dp, - line, file)); - } - - if (*rrsets != NULL) - result = update_rrset_list(rrsets, flags, htpp, from, rrcount); - - if (dp != NULL) { - ns_debug(ns_log_default, 10, - "db_set_update(%s), creating new list", name); - - (void) add_to_rrset_list(rrsets, name, dp, line, file); - } - return (result); -} - -static int -nxt_match_rrset(struct databuf *dp, struct db_rrset *rrset) { - if (rrset->rr_list != NULL) - return (nxtmatch(rrset->rr_name, dp, rrset->rr_list->dp)); - else - return (nxtmatch(rrset->rr_name, dp, rrset->rr_sigs->dp)); -} diff --git a/contrib/bind/bin/named/db_tsig.c b/contrib/bind/bin/named/db_tsig.c deleted file mode 100644 index e8e81f970352c..0000000000000 --- a/contrib/bind/bin/named/db_tsig.c +++ /dev/null @@ -1,158 +0,0 @@ - -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: db_tsig.c,v 8.6 2000/04/21 06:54:04 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <ctype.h> -#include <resolv.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> -#include <isc/tree.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" - -typedef struct { - DST_KEY *key; - void *ctx; -} tsig_axfr_state; - -#define TSIG_ALG_MD5 "HMAC-MD5.SIG-ALG.REG.INT" -#define TSIG_ALG_MD5_SHORT "hmac-md5" - -char * -tsig_alg_name(int value) { - if (value == KEY_HMAC_MD5) - return(TSIG_ALG_MD5); - else - return(NULL); -} - -int -tsig_alg_value(char *name) { - if (ns_samename(name, TSIG_ALG_MD5) == 1 || - strcasecmp(name, TSIG_ALG_MD5_SHORT) == 0) - return (KEY_HMAC_MD5); - else - return (-1); -} - -DST_KEY * -tsig_key_from_addr(struct in_addr addr) { - server_info si = si = find_server(addr); - if (si == NULL || si->key_list == NULL || si->key_list->first == NULL) - return(NULL); - return(si->key_list->first->key); -} - -struct tsig_record * -new_tsig(DST_KEY *key, u_char *sig, int siglen) { - struct tsig_record *tsig; - - if (siglen > TSIG_SIG_SIZE) - return(NULL); - tsig = memget(sizeof(struct tsig_record)); - if (tsig == NULL) - return(NULL); - tsig->key = key; - tsig->siglen = siglen; - memcpy(tsig->sig, sig, siglen); - return(tsig); -} - -void -free_tsig(struct tsig_record *tsig) { - if (tsig == NULL) - return; - memput(tsig, sizeof(struct tsig_record)); -} diff --git a/contrib/bind/bin/named/db_update.c b/contrib/bind/bin/named/db_update.c deleted file mode 100644 index 3bd9838b222f3..0000000000000 --- a/contrib/bind/bin/named/db_update.c +++ /dev/null @@ -1,989 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)db_update.c 4.28 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: db_update.c,v 8.42 2000/04/21 06:54:04 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <resolv.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include "port_after.h" - -#include "named.h" - -/* int - * isRefByNS(name, htp) - * recurse through all of `htp' looking for NS RR's that refer to `name'. - * returns: - * nonzero if at least one such NS RR exists - * cautions: - * this is very expensive; probably you only want to use on fcachetab. - */ -static int -isRefByNS(const char *name, struct hashbuf *htp) { - struct namebuf *np; - struct databuf *dp; - - for (np = htp->h_tab[0]; np != NULL; np = np->n_next) { - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if ((dp->d_class == C_ANY || - dp->d_class == C_IN || - dp->d_class == C_HS) && - dp->d_type == T_NS && - !dp->d_rcode && - ns_samename(name, (char *)dp->d_data) == 1) { - return (1); - } - } - if (np->n_hash && isRefByNS(name, np->n_hash)) - return (1); - } - return (0); -} - - -/* int - * findMyZone(struct namebuf *np, int class) - * surf the zone cuts and find this zone the hard way - * return value: - * zone number or DB_Z_CACHE if it's outside a zone - * interesting cases: - * DEC.COM SOA (primary) - * CRL.DEC.COM NS (in primary) - * if you start at CRL.. here, you find the DEC.COM zone - * if you start at NS.CRL.. here, you're in the cache - * DEC.COM SOA (primary) - * CRL.DEC.COM NS (in primary) - * CRL.DEC.COM SOA (secondary) - * CRL.DEC.COM NS (in secondary) - * if you start at CRL.. here, you find the CRL.DEC.COM zone - * if you start at NS.CRL.. here, you're in the CRL.. zone - */ -int -findMyZone(struct namebuf *np, int class) { - for ((void)NULL; np; np = np_parent(np)) { - struct databuf *dp; - - /* if we encounter an SOA, we're in its zone (which can be - * the cache or an authoritative zone, depending). - */ - for (dp = np->n_data; dp; dp = dp->d_next) - if (match(dp, class, T_SOA) && dp->d_type == T_SOA) - return (dp->d_zone); - - /* if we find an NS at some node without having seen an SOA - * (above), then we're out in the cache somewhere. - */ - for (dp = np->n_data; dp; dp = dp->d_next) - if (match(dp, class, T_NS) && dp->d_type == T_NS) - return (DB_Z_CACHE); - } - - /* The cache has not yet been primed. */ - return (DB_Z_CACHE); -} - -/* int - * db_update(name, odp, newdp, savedpp, flags, htp, from) - * update data base node at `name'. `flags' controls the action. - * side effects: - * inverse query tables modified, if we're using them. - * return value: - * OK - success - * NONAME - name doesn't exist - * AUTH - you can't do that - * DATAEXISTS - there's something there and DB_NODATA was specified - * NODATA - there's no data, and (DB_DELETE or DB_MEXIST) was spec'd - * - * Policy: How to add data if one more RR is -ve data - * - * NEND NOERROR_NODATA - * NXD NXDOMAIN - * - * match - * old - * Data NEND NXD - * Data Merge Data Data - * new NEND NEND NEND NEND - * NXD NXD NXD NXD - * - * no match - * old - * Data NEND NXD - * Data Merge Merge Data - * new NEND Merge Merge NEND - * NXD NXD NXD NXD - * - */ -/* XXX: this code calls nlookup, which can create namebuf's. if this code - * has to exit with a fatal error, it should scan from the new np upward - * and for each node which has no children and no data it should remove - * the namebuf. design notes: (1) there's no harm in doing this even if - * success occurred; (2) stopping on the first nonremovable np is optimal; - * the code for removal should be taken out of clean_cache() and made - * general enough for this use, and for clean_cache()'s continued use. - * vix, 21jul94 - */ -int -db_update(const char *name, - struct databuf *odp, struct databuf *newdp, - struct databuf **savedpp, - int flags, struct hashbuf *htp, struct sockaddr_in from) -{ - struct databuf *dp, *pdp; - struct namebuf *np; - int zn, isHintNS; - int check_ttl = 0; - int deleted_something = 0; - const char *fname; -#ifdef BIND_UPDATE - int found_other_ns = 0; - struct databuf *tmpdp; -#endif - - ns_debug(ns_log_db, 3, "db_update(%s, %#x, %#x, %#x, 0%o, %#x)%s", - name, odp, newdp, savedpp, flags, htp, - (odp && (odp->d_flags&DB_F_HINT)) ? " hint" : ""); - np = nlookup(name, &htp, &fname, newdp != NULL); - if (np == NULL || fname != name) - return (NONAME); - - if (newdp && zones[newdp->d_zone].z_type == Z_PRIMARY) - check_ttl = 1; - - /* don't let nonauthoritative updates write in authority zones */ - if (newdp && ((zn = findMyZone(np, newdp->d_class)) != DB_Z_CACHE) && -#ifdef STUBS - (zones[zn].z_type != Z_STUB) && -#endif - (flags & DB_NOTAUTH)) { - int foundRR = 0; - - /* - * Don't generate the warning if the update - * would have been harmless (identical data). - */ - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!db_cmp(dp, newdp)) { - foundRR++; - break; - } - } - if (!foundRR) - ns_debug(ns_log_db, 5, - "[%s].%d update? to auth zone \"%s\" (%s)", - inet_ntoa(from.sin_addr), - ntohs(from.sin_port), - zones[zn].z_origin, - name); - return (AUTH); - } - - if (newdp && zn && !(flags & DB_NOTAUTH)) { - if (nlabels(zones[zn].z_origin) > newdp->d_clev) { - ns_debug(ns_log_db, 5, - "attempted update child zone %s, %s", - zones[zn].z_origin, name); - return (AUTH); - } - } - - /* some special checks for root NS' A RR's */ - isHintNS = isRefByNS(name, fcachetab); -#ifdef DEPRECATED - if (newdp && isHintNS && newdp->d_type == T_A) { - /* upgrade credibility of additional data for rootsrv addrs */ - if (newdp->d_cred == DB_C_ADDITIONAL) { - ns_debug(ns_log_db, 3, - "upgrading credibility for A RR (%s)", - name); - /* XXX: should copy NS RR's, but we really just want - * to prevent deprecation later so this will do. - */ - newdp->d_cred = DB_C_ANSWER; - newdp->d_clev = 0; - } - } -#endif - - /* Reflect certain updates in hint cache also... */ - /* Don't stick data we are authoritative for in hints. */ - if (!(flags & DB_NOHINTS) && - (flags & DB_PRIMING) && - (odp != NULL) && - (htp != fcachetab) && - (DB_Z_SPECIAL(odp->d_zone)) && - !(odp->d_flags & DB_F_HINT) && - (!newdp || !newdp->d_rcode) && - ((name[0] == '\0' && odp->d_type == T_NS) || - (odp->d_type == T_A && isHintNS) - ) - ) - { - ns_debug(ns_log_db, 3, "db_update: hint '%s' %u", - name, odp->d_ttl); - dp = savedata(odp->d_class, odp->d_type, odp->d_ttl, - odp->d_data, odp->d_size); - dp->d_zone = DB_Z_CACHE; - dp->d_flags = DB_F_HINT; - dp->d_cred = DB_C_CACHE; - dp->d_secure = odp->d_secure; /* BEW - this should be ok */ - dp->d_clev = 0; - if (db_update(name, - dp, dp, NULL, - (flags|DB_NOHINTS), - fcachetab, from) - != OK) { - ns_debug(ns_log_db, 3, - "db_update: hint %#x freed", dp); - db_freedata(dp); - } - } - - if (odp != NULL) { - int foundRR = 0; - - pdp = NULL; - for (dp = np->n_data; dp != NULL; ) { - if (!rrmatch(name, dp, odp)) { - /* {class,type} doesn't match. these are - * the aggregation cases. - */ - /* Check that CNAMEs are only accompanied by - * Secure DNS RR's (KEY, SIG, and NXT). - */ - if (((dp->d_type == T_CNAME && - odp->d_type != T_KEY && - odp->d_type != T_SIG && - odp->d_type != T_NXT) || - (odp->d_type == T_CNAME && - dp->d_type != T_KEY && - dp->d_type != T_SIG && - dp->d_type != T_NXT)) && - odp->d_class == dp->d_class && - /* XXXRTH d_mark removed in 4.9.5, - but still here for dynamic - update */ - odp->d_mark == dp->d_mark && - !dp->d_rcode && - !odp->d_rcode && -#ifdef BIND_UPDATE - /* updating a CNAME with another CNAME is permitted */ - (dp->d_type != T_CNAME || - odp->d_type != T_CNAME) && -#endif - zones[odp->d_zone].z_type != Z_CACHE) { - ns_info(ns_log_db, - "%s has CNAME and other data (invalid)", - name); - if (zones[odp->d_zone].z_type == - Z_PRIMARY) - return (CNAMEANDOTHER); - goto skip; - } - if (!newdp || newdp->d_class != dp->d_class) - goto skip; - - /* if the new data is authorative - * remove any data for this domain with - * the same class that isn't as credable - */ - if (newdp->d_cred == DB_C_ZONE && - newdp->d_cred > dp->d_cred) - /* better credibility and the old datum - * was not from a zone file. remove - * the old datum. - */ - goto delete; - -#if 0 /* caught by findMyZone() now. */ - /* if we have authoritative data for a - * node, don't add in other data. - */ - if (dp->d_cred == DB_C_ZONE && - newdp->d_cred < dp->d_cred) - return (AUTH); -#endif - - /* if the new data is authoritative - * but isn't as credible, reject it. - */ - if (newdp->d_cred == DB_C_ZONE && - dp->d_cred == DB_C_ZONE) { - /* Both records are from a zone file. - * If their credibility levels differ, - * we're dealing with a zone cut. The - * record with lower clev is from the - * upper zone's file and is therefore - * glue. - */ - - /* BEW/OG: we see no reason to override - * these rules with new security based - * rules. - */ - if (newdp->d_clev < dp->d_clev) { - if (!ISVALIDGLUE(newdp)) { - ns_info(ns_log_db, - "domain %s %s record in zone %s should be in zone %s, ignored", - name, p_type(newdp->d_type), - zones[newdp->d_zone].z_origin, - zones[dp->d_zone].z_origin); - } - return (AUTH); - } - if (newdp->d_clev > dp->d_clev) { - if (!ISVALIDGLUE(dp)) { - ns_info(ns_log_db, - "domain %s %s record in zone %s should be in zone %s, deleted", - name, p_type(dp->d_type), - zones[dp->d_zone].z_origin, - zones[newdp->d_zone].z_origin); - } - goto delete; - } - } - - /* process NXDOMAIN */ - /* policy */ - if (newdp->d_rcode == NXDOMAIN) { - if (dp->d_cred < DB_C_AUTH && - newdp->d_secure >= dp->d_secure) - goto delete; - else - return (DATAEXISTS); - } - - if (dp->d_rcode == NXDOMAIN) - goto delete; - - /* process NOERROR_NODATA */ - /* NO PROCESSING REQUIRED */ - - goto skip; - } /*if {class,type} did not match*/ - - /* - * {type,class} did match. This is the replace case. - */ - ns_debug(ns_log_db, 5, - "db_update: flags = %#x, sizes = %d, %d (cmp %d)", - flags, odp->d_size, dp->d_size, - db_cmp(dp, odp)); - if (newdp) { - ns_debug(ns_log_db, 4, -"credibility for %s is %d(%d)(sec %d) from [%s].%d, is %d(%d)(sec %d) in cache", - *name ? name : ".", - newdp->d_cred, - newdp->d_clev, - newdp->d_secure, - inet_ntoa(from.sin_addr), - ntohs(from.sin_port), - dp->d_cred, - dp->d_secure, - dp->d_clev); - if ((newdp->d_secure > dp->d_secure) || - (newdp->d_secure == dp->d_secure && - (newdp->d_cred > dp->d_cred))) - { - /* better credibility / security. - * remove the old datum. - */ - goto delete; - } - if ((newdp->d_secure < dp->d_secure) || - (newdp->d_secure == dp->d_secure && - (newdp->d_cred < dp->d_cred))) - { - /* credibility / security is worse. - * ignore it. - */ - return (AUTH); - } - /* BEW/OG: from above, we know the security - * levels are the same. - */ - if (newdp->d_cred == DB_C_ZONE && - dp->d_cred == DB_C_ZONE ) { - /* Both records are from a zone file. - * If their credibility levels differ, - * we're dealing with a zone cut. The - * record with lower clev is from the - * upper zone's file and is therefore - * glue. - */ - - /* XXX - Tricky situation here is you - * have 2 zones a.b.c and sub.a.b.c - * being served by the same server. - * named will send NS records for - * sub.a.b.c during zone transfer of - * a.b.c zone. If we're secondary for - * both zones, and we reload zone - * a.b.c, we'll get the NS records - * (and possibly A records to go with - * them?) for sub.a.b.c as part of the - * a.b.c zone transfer. But we've - * already got a more credible record - * from the sub.a.b.c zone. So we want - * to ignore the new record, but we - * shouldn't syslog because there's - * nothing the user can do to prevent - * the situation. Perhaps we should - * only complain when we are primary? - */ - - if (newdp->d_clev < dp->d_clev) { - if (!ISVALIDGLUE(newdp)) { - ns_info(ns_log_db, - "domain %s %s record in zone %s should be in zone %s, ignored", - name, p_type(newdp->d_type), - zones[newdp->d_zone].z_origin, - zones[dp->d_zone].z_origin); - } - return (AUTH); - } - if (newdp->d_clev > dp->d_clev) { - if (!ISVALIDGLUE(dp)) { - ns_info(ns_log_db, - "domain %s %s record in zone %s should be in zone %s, deleted", - name, p_type(dp->d_type), - zones[dp->d_zone].z_origin, - zones[newdp->d_zone].z_origin); - } - goto delete; - } - } - - /* credibility is the same. - * let it aggregate in the normal way. - */ - - /* - * if the new or old RR is -ve, delete old. - */ - if (dp->d_rcode || newdp->d_rcode) { - /* XXX: how can a zone rr be neg? */ - if (dp->d_cred != DB_C_ZONE) - goto delete; - else - return (DATAEXISTS); - } - - /* - * Some RR types should not be aggregated. - */ - if (dp->d_type == T_SOA) { -#ifdef BIND_UPDATE - u_int32_t dp_ser, ndp_ser; - u_char *dp_cp, *ndp_cp; - - dp_cp = findsoaserial(dp->d_data); - ndp_cp = findsoaserial(newdp->d_data); - GETLONG(dp_ser, dp_cp); - GETLONG(ndp_ser, ndp_cp); - - if (SEQ_GT(ndp_ser, dp_ser)) - goto delete; - else - return (SERIAL); -#else - goto delete; -#endif /*BIND_UPDATE*/ - } - if (dp->d_type == T_WKS && - !memcmp(dp->d_data, newdp->d_data, - INT32SZ + sizeof(u_char))) - goto delete; - if (dp->d_type == T_CNAME && - !NS_OPTION_P(OPTION_MULTIPLE_CNAMES) && - db_cmp(dp, odp) != 0) - if ((flags & DB_REPLACE) == 0 && - zones[dp->d_zone].z_type == - Z_PRIMARY) { - ns_warning(ns_log_db, - "%s has multiple CNAMES", - name); - return (CNAMEANDOTHER); - } else - goto delete; -#if 0 -/* BEW - this _seriously_ breaks DNSSEC. Is it necessary for dynamic update? */ -#ifdef BIND_UPDATE - if (dp->d_type == T_SIG) - /* - * Type covered has already been - * checked. - */ - goto delete; -#endif -#endif - if (dp->d_type == T_NXT) { - goto delete; - } - if (dp->d_type == T_SIG && - SIG_COVERS(dp) == T_NXT) { - struct sig_record *sr1, *sr2; - - sr1 = (struct sig_record *) dp->d_data; - sr2 = (struct sig_record *) - newdp->d_data; - if (sr1->sig_alg_n == sr2->sig_alg_n) - goto delete; - } - if (check_ttl) { - if (newdp->d_ttl != dp->d_ttl) - ns_warning(ns_log_db, - "%s %s %s differing ttls: corrected", - name[0]?name:".", - p_class(dp->d_class), - p_type(dp->d_type)); - if (newdp->d_ttl > dp->d_ttl) { - newdp->d_ttl = dp->d_ttl; - } else { - dp->d_ttl = newdp->d_ttl; - } - } - } - if ((flags & DB_NODATA) && !db_cmp(dp, odp)) { - /* Refresh ttl if cache entry. */ - if (dp->d_zone == DB_Z_CACHE) { - if (odp->d_zone != DB_Z_CACHE) { - /* Changing cache->auth. */ - dp->d_zone = odp->d_zone; - dp->d_ttl = odp->d_ttl; - ns_debug(ns_log_db, 4, - "db_update: cache entry now in auth zone"); - return (DATAEXISTS); - } - fixttl(odp); - if (odp->d_ttl > dp->d_ttl) - dp->d_ttl = odp->d_ttl; - ns_debug(ns_log_db, 3, - "db_update: new ttl %u +%lu", - dp->d_ttl, - (u_long)(dp->d_ttl - tt.tv_sec) - ); - } - return (DATAEXISTS); - } - /* - * If the old databuf has some data, check that the - * data matches that in the new databuf. - */ - if (odp->d_size > 0) - if (db_cmp(dp, odp)) - goto skip; - if (odp->d_clev < dp->d_clev) - goto skip; - if ((odp->d_secure < dp->d_secure) || - ((odp->d_secure == dp->d_secure) && - (odp->d_cred < dp->d_cred))) - goto skip; -#ifdef BIND_UPDATE - if (ns_samename(name, zones[dp->d_zone].z_origin) == 1 - && newdp == NULL) { - /* do not delete SOA or NS records as a set */ - /* XXXRTH isn't testing d_size unnecessary? */ - if ((odp->d_size == 0) && - (odp->d_class == C_ANY) && - (odp->d_type == T_ANY || - odp->d_type == T_SOA || - odp->d_type == T_NS) && - (dp->d_type == T_SOA || - dp->d_type == T_NS)) - goto skip; - /* XXXRTH I added this to prevent SOA deletion - I'm using the same style of comparison as - the other code in this section. Do we - really need to look at dp->d_type here? - We're in the "match" section... */ - if ((odp->d_type == T_SOA) && - (dp->d_type == T_SOA)) - goto skip; - /* do not delete the last NS record - for the zone */ - if ((odp->d_type == T_NS) && - (dp->d_type == T_NS)) { - found_other_ns = 0; - for (tmpdp = np->n_data; - tmpdp && !found_other_ns; - tmpdp = tmpdp->d_next) - if ((tmpdp->d_type == T_NS) && - (tmpdp != dp)) - found_other_ns = 1; - if (!found_other_ns) { - ns_debug(ns_log_db, 3, - "cannot delete last remaining NS record for zone %s", - name); - goto skip; - } - } - } -#endif - - foundRR = 1; - if (flags & DB_DELETE) { - delete: -#ifdef BIND_UPDATE - /* - * XXX assume here that savedpp!=NULL iff. db_update - * has been called by the dyanmic update code. - * Maybe a new flag is more appropriate? - */ - if (savedpp != NULL) - foundRR = 1; -#endif - deleted_something = 1; - dp = rm_datum(dp, np, pdp, savedpp); - } else { - skip: pdp = dp; - dp = dp->d_next; - } - } - if (!foundRR) { - if (flags & DB_DELETE) - return (NODATA); - if (flags & DB_MEXIST) - return (NODATA); - } - } - if (newdp == NULL) { - if (deleted_something) { - while (np->n_data == NULL && np->n_hash == NULL) { - np = purge_node(htp, np); - if (np == NULL) - break; - } - } - return (OK); - } - /* XXX: empty nodes bypass credibility checks above; should check - * response source address here if flags&NOTAUTH. - */ - fixttl(newdp); - ns_debug(ns_log_db, 3, "db_update: adding%s %#x", - (newdp->d_flags&DB_F_HINT) ? " hint":"", newdp); - - if (NS_OPTION_P(OPTION_HOSTSTATS) && - newdp->d_zone == DB_Z_CACHE && - (newdp->d_flags & DB_F_HINT) == 0) - newdp->d_ns = nameserFind(from.sin_addr, NS_F_INSERT); - - /* Add to end of list, generally preserving order */ - newdp->d_next = NULL; - if ((dp = np->n_data) == NULL) { - DRCNTINC(newdp); - if (newdp->d_flags & DB_F_ACTIVE) - panic("db_update: DB_F_ACTIVE set", NULL); - newdp->d_flags |= DB_F_ACTIVE; - np->n_data = newdp; - return (OK); - } - while (dp->d_next != NULL) { - if ((flags & DB_NODATA) && !db_cmp(dp, newdp)) - return (DATAEXISTS); - dp = dp->d_next; - } - if ((flags & DB_NODATA) && !db_cmp(dp, newdp)) - return (DATAEXISTS); - DRCNTINC(newdp); - if (newdp->d_flags & DB_F_ACTIVE) - panic("db_update: DB_F_ACTIVE set", NULL); - newdp->d_flags |= DB_F_ACTIVE; - dp->d_next = newdp; - return (OK); -} - -void -fixttl(struct databuf *dp) { - if (dp->d_zone == DB_Z_CACHE && (dp->d_flags & DB_F_HINT) == 0) { - if (dp->d_ttl <= (u_int32_t)tt.tv_sec) - return; - else if (dp->d_ttl < (u_int32_t)tt.tv_sec+min_cache_ttl) - dp->d_ttl = (u_int32_t)tt.tv_sec+min_cache_ttl; - else if (dp->d_ttl > (u_int32_t)tt.tv_sec+max_cache_ttl) - dp->d_ttl = (u_int32_t)tt.tv_sec+max_cache_ttl; - } -} - -/* - * Compare type, class and data from databufs for equivalence. - * All domain names in RR's must be compared case-insensitively. - * Return 0 if equivalent, nonzero otherwise. - */ -int -db_cmp(const struct databuf *dp1, const struct databuf *dp2) { - const u_char *cp1, *cp2; - int len, len2; - - /* XXXDYNUP- should be changed to - if (!match(dp1, dp2->d_type, dp2->d_class) */ - if (dp1->d_type != dp2->d_type || dp1->d_class != dp2->d_class) - return (1); - /* XXXDYNUP - should be changed to (dp1->d_size != dp2->d_size && - dp1->d_size != 0 && dp2->d_size != 0) */ - if (dp1->d_size != dp2->d_size) - return (1); - /* d_mark is only used for dynamic updates currently */ -#ifndef BIND_UPDATE - if (dp1->d_mark != dp2->d_mark) - return (1); /* old and new RR's are distinct */ -#endif - if (dp1->d_rcode && dp2->d_rcode) - return ((dp1->d_rcode == dp1->d_rcode)?0:1); - if (dp1->d_rcode || dp2->d_rcode) - return (1); - - switch (dp1->d_type) { - - case T_A: - case T_WKS: - case T_NULL: - case T_NSAP: - case T_AAAA: - case T_LOC: - case T_KEY: - /* Only binary data */ - return (memcmp(dp1->d_data, dp2->d_data, dp1->d_size)); - - case T_NS: - case T_CNAME: - case T_PTR: - case T_MB: - case T_MG: - case T_MR: - /* Only a domain name */ - if (ns_samename((char *)dp1->d_data, (char *)dp2->d_data) == 1) - return (0); - else - return (1); - - case T_SIG: - /* Binary data, a domain name, more binary data */ - if (dp1->d_size < NS_SIG_SIGNER) - return (1); - if (memcmp(dp1->d_data, dp2->d_data, NS_SIG_SIGNER)) - return (1); - len = NS_SIG_SIGNER + - strlen((char *)dp1->d_data + NS_SIG_SIGNER); - if (ns_samename((char *)dp1->d_data + NS_SIG_SIGNER, - (char *)dp2->d_data + NS_SIG_SIGNER) != 1) - return (1); - return (memcmp(dp1->d_data + len, - dp2->d_data + len, - dp1->d_size - len)); - - case T_NXT: - /* First a domain name, then binary data */ - if (ns_samename((char *)dp1->d_data, (char *)dp2->d_data) != 1) - return (1); - len = strlen((char *)dp1->d_data)+1; - return (memcmp(dp1->d_data + len, - dp2->d_data + len, - dp1->d_size - len)); - - case T_HINFO: - case T_ISDN: - cp1 = dp1->d_data; - cp2 = dp2->d_data; - len = *cp1; - len2 = *cp2; - if (len != len2) - return (1); - if (strncasecmp((char *)++cp1, (char *)++cp2, len)) - return (1); - cp1 += len; - cp2 += len; - len = *cp1; - len2 = *cp2; - if (len != len2) - return (1); - return (strncasecmp((char *)++cp1, (char *)++cp2, len)); - - case T_SOA: - case T_MINFO: - case T_RP: - if (ns_samename((char *)dp1->d_data, (char *)dp2->d_data) != 1) - return (1); - cp1 = dp1->d_data + strlen((char *)dp1->d_data) + 1; - cp2 = dp2->d_data + strlen((char *)dp2->d_data) + 1; - if (ns_samename((char *)cp1, (char *)cp2) != 1) - return (1); - if (dp1->d_type != T_SOA) - return (0); - cp1 += strlen((char *)cp1) + 1; - cp2 += strlen((char *)cp2) + 1; - return (memcmp(cp1, cp2, INT32SZ * 5)); - - case T_NAPTR: { - int t1,t2; - - if (dp1->d_size != dp2->d_size) - return (1); - cp1 = dp1->d_data; - cp2 = dp2->d_data; - - /* Order */ - if (*cp1++ != *cp2++ || *cp1++ != *cp2++) - return (1); - - /* Preference */ - if (*cp1++ != *cp2++ || *cp1++ != *cp2++) - return (1); - - /* Flags */ - t1 = *cp1++; t2 = *cp2++; - if (t1 != t2 || memcmp(cp1, cp2, t1)) - return (1); - cp1 += t1; cp2 += t2; - - /* Services */ - t1 = *cp1++; t2 = *cp2++; - if (t1 != t2 || memcmp(cp1, cp2, t1)) - return (1); - cp1 += t1; cp2 += t2; - - /* Regexp */ - t1 = *cp1++; t2 = *cp2++; - if (t1 != t2 || memcmp(cp1, cp2, t1)) - return (1); - cp1 += t1; cp2 += t2; - - /* Replacement */ - t1 = strlen((char *)cp1); t2 = strlen((char *)cp2); - if (t1 != t2 || memcmp(cp1, cp2, t1)) - return (1); - cp1 += t1 + 1; cp2 += t2 + 1; - - /* they all checked out! */ - return (0); - } - - case T_MX: - case T_AFSDB: - case T_RT: - case T_SRV: - cp1 = dp1->d_data; - cp2 = dp2->d_data; - if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* cmp prio */ - return (1); - if (dp1->d_type == T_SRV) { - if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* weight */ - return (1); - if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* port */ - return (1); - } - if (ns_samename((char *)cp1, (char *)cp2) != 1) - return (1); - return (0); - - case T_PX: - cp1 = dp1->d_data; - cp2 = dp2->d_data; - if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* cmp prio */ - return (1); - if (ns_samename((char *)cp1, (char *)cp2) != 1) - return (1); - cp1 += strlen((char *)cp1) + 1; - cp2 += strlen((char *)cp2) + 1; - if (ns_samename((char *)cp1, (char *)cp2) != 1) - return (1); - return (0); - - case T_TXT: - case T_X25: - if (dp1->d_size != dp2->d_size) - return (1); - return (memcmp(dp1->d_data, dp2->d_data, dp1->d_size)); - - default: - return (1); - } -} diff --git a/contrib/bind/bin/named/named-bootconf.pl b/contrib/bind/bin/named/named-bootconf.pl deleted file mode 100755 index ce474c4f47a4e..0000000000000 --- a/contrib/bind/bin/named/named-bootconf.pl +++ /dev/null @@ -1,324 +0,0 @@ -#!/usr/bin/perl - -## Copyright (c) 1996, 1997 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -## $Id: named-bootconf.pl,v 8.16 1998/02/13 19:48:25 halley Exp $ - -# This is a filter. Input is a named.boot. Output is a named.conf. - -$new_config = ""; - -$have_options = 0; -%options = (); -%options_comments = (); -@topology = (); -@topology_comments = (); -@bogus = (); -@bogus_comments = (); -@transfer_acl = (); -@transfer_comments = (); -$logging = ""; - -while(<>) { - next if /^$/; - - # skip comment-only lines - if (/^\s*;+\s*(.*)$/) { - $new_config .= "// $1\n"; - next; - } - - # handle continued lines - while (/\\$/) { - s/\\$/ /; - $_ .= <>; - } - - chop; - - # deal with lines ending in a coment - if (s/\s*;+\s*(.*)$//) { - $comment = "// $1"; - } else { - $comment = ""; - } - - ($directive, @rest) = split; - - $class = ""; - if ($directive =~ /^(.*)\/(.*)$/) { - $directive = $1; - $class = $2; - } - - if ($directive eq "primary") { - $zname = shift(@rest); - &maybe_print_comment("","\n"); - $new_config .= "zone \"$zname\" "; - if ($class ne "") { - $new_config .= "$class "; - } - $new_config .= "{\n"; - $new_config .= "\ttype master;\n"; - $filename = shift(@rest); - $new_config .= "\tfile \"$filename\";\n"; - $new_config .= "};\n\n"; - } elsif ($directive eq "secondary" || $directive eq "stub") { - if ($directive eq "secondary") { - $type = "slave"; - } else { - $type = "stub"; - } - $zname = shift(@rest); - &maybe_print_comment("","\n"); - $new_config .= "zone \"$zname\" "; - if ($class ne "") { - $new_config .= "$class "; - } - $new_config .= "{\n"; - $new_config .= "\ttype $type;\n"; - $filename = pop(@rest); - if ($filename =~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) { - push(@rest, $filename); - $filename = ""; - } else { - $new_config .= "\tfile \"$filename\";\n"; - } - $new_config .= "\tmasters {\n"; - foreach $master (@rest) { - $new_config .= "\t\t$master;\n"; - } - $new_config .= "\t};\n"; - $new_config .= "};\n\n"; - } elsif ($directive eq "cache") { - $zname = shift(@rest); - &maybe_print_comment("","\n"); - $new_config .= "zone \"$zname\" {\n"; - $new_config .= "\ttype hint;\n"; - $filename = shift(@rest); - $new_config .= "\tfile \"$filename\";\n"; - $new_config .= "};\n\n"; - } elsif ($directive eq "directory") { - $options{"directory"} = "\"$rest[0]\""; - $options_comments{"directory"} = $comment; - $have_options = 1; - } elsif ($directive eq "check-names") { - $type = shift(@rest); - if ($type eq "primary") { - $type = "master"; - } elsif ($type eq "secondary") { - $type = "slave"; - } - $action = shift(@rest); - $options{"check-names $type"} = $action; - $options_comments{"check-names $type"} = $comment; - $have_options = 1; - } elsif ($directive eq "forwarders") { - $options{"forwarders"}="{\n"; - foreach $forwarder (@rest) { - $options{"forwarders"} .= "\t\t$forwarder;\n"; - } - $options{"forwarders"} .= "\t}"; - $options_comments{"forwarders"} = $comment; - $have_options = 1; - } elsif ($directive eq "slave") { - &handle_options("forward-only"); - } elsif ($directive eq "options") { - &handle_options(@rest); - } elsif ($directive eq "limit") { - &handle_limit(@rest); - } elsif ($directive eq "include") { - $new_config .= - "// make sure your include is still in the right place\n"; - $comment = "\t" . $comment; - $new_config .= "include \"$rest[0]\";$comment\n\n"; - } elsif ($directive eq "xfrnets" || $directive eq "tcplist") { - if ($comment ne "") { - $comment = "\t$comment"; - } - foreach $elt (@rest) { - push(@transfer_acl, $elt); - push(@transfer_comments, $comment); - } - $have_options = 1; - } elsif ($directive eq "sortlist") { - if ($comment ne "") { - $comment = "\t$comment"; - } - foreach $elt (@rest) { - push(@topology, $elt); - push(@topology_comments, $comment); - } - } elsif ($directive eq "bogusns") { - if ($comment ne "") { - $comment = "\t$comment"; - } - foreach $elt (@rest) { - push(@bogus, $elt); - push(@bogus_comments, $comment); - } - } elsif ($directive eq "max-fetch") { - $options{"transfers-in"}=$rest[0]; - $options_comments{"transfers-in"}=$comment; - $have_options = 1; - } else { - $new_config .= "// NOTE: unconverted directive '$directive @rest'\n\n"; - } -} - -print "// generated by named-bootconf.pl\n\n"; -if ($have_options) { - print "options {\n"; - foreach $option (sort(keys(%options))) { - print "\t$option $options{$option};"; - if ($options_comments{$option} ne "") { - print "\t$options_comments{$option}"; - } - print "\n"; - } - if (@transfer_acl > 0) { - print "\tallow-transfer {\n"; - for ($i = 0; $i <= $#transfer_acl; $i++) { - &print_maybe_masked("\t\t", $transfer_acl[$i], - $transfer_comments[$i]); - } - print "\t};\n"; - } - print "\t/* -\t * If there is a firewall between you and nameservers you want -\t * to talk to, you might need to uncomment the query-source -\t * directive below. Previous versions of BIND always asked -\t * questions using port 53, but BIND 8.1 uses an unprivileged -\t * port by default. -\t */ -\t// query-source address * port 53; -"; - - print "};\n\n"; -} -if ($logging ne "") { - print "logging {\n$logging};\n\n"; -} -if (@topology > 0) { - print "// Note: the following will be supported in a future release.\n"; - print "/*\n"; - print "host { any; } {\n\ttopology {\n"; - for ($i = 0; $i <= $#topology; $i++) { - &print_maybe_masked("\t\t", $topology[$i], - $topology_comments[$i]); - } - print "\t};\n};\n"; - print "*/\n"; - print "\n"; -} -if (@bogus > 0) { - for ($i = 0; $i <= $#bogus; $i++) { - print "server $bogus[$i] { bogus yes; };$bogus_comments[$i]\n"; - } - print "\n"; -} -print $new_config; - -exit 0; - -sub maybe_print_comment { - $prefix = shift; - $suffix = shift; - if ($comment ne "") { - $new_config .= sprintf("%s%s%s", $prefix, $comment, $suffix); - } -} - -sub handle_options { - foreach $option (@_) { - if ($option eq "forward-only") { - $options{"forward"}="only"; - $options_comments{"forward"}=$comment; - $have_options = 1; - } elsif ($option eq "no-recursion") { - $options{"recursion"}="no"; - $options_comments{"recursion"}=$comment; - $have_options = 1; - } elsif ($option eq "no-fetch-glue") { - $options{"fetch-glue"}="no"; - $options_comments{"fetch-glue"}=$comment; - $have_options = 1; - } elsif ($option eq "fake-iquery") { - $options{"fake-iquery"}="yes"; - $options_comments{"fake-iquery"}=$comment; - $have_options = 1; - } elsif ($option eq "query-log") { - if ($comment ne "") { - $logging .= "\t$comment\n"; - } - $logging .= "\tcategory queries { default_syslog; };\n"; - } else { - $options{"// NOTE: unconverted option '$option'"}=""; - $options_comments{"// NOTE: unconverted option '$option'"}= - $comment; - $have_options = 1; - } - } -} - -sub handle_limit { - $limit = shift; - if ($limit eq "datasize" || $limit eq "transfers-in" - || $limit eq "transfers-per-ns" || $limit eq "files") { - $options{$limit}=$_[0]; - $options_comments{$limit}=$comment; - $have_options = 1; - } else { - $options{"// NOTE: unconverted limit '$limit @_'"}=""; - $options_comments{"// NOTE: unconverted limit '$limit @_'"}=$comment; - $have_options = 1; - } -} - -sub print_maybe_masked { - # this assumes a contiguous netmask starting at the MSB - $prefix = shift; - $elt = shift; - $elt_comment = shift; - if ($elt =~ /^(.*)&(.*)$/) { - $address = $1; - $mask = $2; - ($m1,$m2,$m3,$m4) = split(/\./, $mask); - $mask_val = ($m1 << 24) + ($m2 << 16) +($m3 << 8) + $m4; - $zero_bits = 0; - while (($mask_val % 2) == 0) { - $mask_val /= 2; - $zero_bits++; - } - $mask_bits = 32 - $zero_bits; - } else { - $address = $elt; - ($a1,$a2,$a3,$a4) = split(/\./, $address); - if ($a1 < 128) { - $mask_bits = 8; - } elsif ($a1 < 192) { - $mask_bits = 16; - } else { - $mask_bits = 24; - } - } - - print "$prefix$address"; - if ($mask_bits != 32) { - print "/$mask_bits"; - } - print ";$elt_comment\n"; -} diff --git a/contrib/bind/bin/named/named.conf b/contrib/bind/bin/named/named.conf deleted file mode 100644 index d423b343df2c2..0000000000000 --- a/contrib/bind/bin/named/named.conf +++ /dev/null @@ -1,456 +0,0 @@ -/* - * This is a worthless, nonrunnable example of a named.conf file that has - * every conceivable syntax element in use. We use it to test the parser. - * It could also be used as a conceptual template for users of new features. - */ - -/* - * C-style comments are OK - */ - -// So are C++-style comments - -# So are shell-style comments - -// watch out for ";" -- it's important! - -options { - directory "."; // use current directory - named-xfer "/usr/libexec/named-xfer"; // _PATH_XFER - dump-file "named_dump.db"; // _PATH_DUMPFILE - pid-file "/var/run/named.pid"; // _PATH_PIDFILE - statistics-file "named.stats"; // _PATH_STATS - memstatistics-file "named.memstats"; // _PATH_MEMSTATS - check-names master fail; - check-names slave warn; - check-names response ignore; - host-statistics no; - deallocate-on-exit no; // Painstakingly deallocate all - // objects when exiting instead of - // letting the OS clean up for us. - // Useful a memory leak is suspected. - // Final statistics are written to the - // memstatistics-file. - datasize default; - stacksize default; - coresize default; - files unlimited; - recursion yes; - fetch-glue yes; - fake-iquery no; - notify yes; // send NOTIFY messages. You can set - // notify on a zone-by-zone - // basis in the "zone" statement - // see (below) - max-serial-queries 4; // number of parallel SOA queries - // we can have outstanding for master - // zone change testing purposes - auth-nxdomain yes; // always set AA on NXDOMAIN. - // don't set this to 'no' unless - // you know what you're doing -- older - // servers won't like it. - multiple-cnames no; // if yes, then a name my have more - // than one CNAME RR. This use - // is non-standard and is not - // recommended, but it is available - // because previous releases supported - // it and it was used by large sites - // for load balancing. - allow-query { any; }; - allow-transfer { any; }; - transfers-in 10; // DEFAULT_XFERS_RUNNING, cannot be - // set > than MAX_XFERS_RUNNING (20) - transfers-per-ns 2; // DEFAULT_XFERS_PER_NS - transfers-out 0; // not implemented - max-transfer-time-in 120; // MAX_XFER_TIME; the default number - // of minutes an inbound zone transfer - // may run. May be set on a per-zone - // basis. - /* - * The "transfer-format" option specifies the way outbound zone - * transfers (i.e. from us to them) are formatted. Two values are - * allowed: - * - * one-answer Each RR gets its own DNS message. - * This format is not very efficient, - * but is widely understood. All - * versions of BIND prior to 8.1 generate - * this format for outbound zone - * and require it on inbound transfers. - * - * many-answers As many RRs as will fit are put into - * each DNS message. This format is - * the most efficient, but is only known - * to work with BIND 8. Patches to - * BIND 4.9.5 named-xfer that enable it - * to understand 'many-answers' will be - * available. - * - * If you are going to be doing zone transfers to older servers, you - * shouldn't use 'many-answers'. 'transfer-format' may also be set - * on a host-by-host basis using the 'server' statement (see below). - */ - transfer-format one-answer; - query-source address * port *; - /* - * The "forward" option is only meaningful if you've defined - * forwarders. "first" gives the normal BIND - * forwarding behavior, i.e. ask the forwarders first, and if that - * doesn't work then do the full lookup. You can also say - * "forward only;" which is what used to be specified with - * "slave" or "options forward-only". "only" will never attempt - * a full lookup; only the forwarders will be used. - */ - forward first; - forwarders { }; // default is no forwarders - /* - * Here's a forwarders example that isn't trivial - */ - /* - forwarders { - 1.2.3.4; - 5.6.7.8; - }; - */ - topology { localhost; localnets; }; // prefer local nameservers - /* - * Here's a more complicated topology example; it's commented out - * because only one topology block is allowed. - * - topology { - 10/8; // prefer network 10.0.0.0 - // netmask 255.0.0.0 most - !1.2.3/24; // don't like 1.2.3.0 netmask - // 255.255.255.0 at all - { 1.2/16; 3/8; }; // like 1.2.0.0 netmask 255.255.0.0 - // and 3.0.0.0 netmask 255.0.0.0 - // equally well, but less than 10/8 - }; - */ - - listen-on port 53 { any; }; // listen for queries on port 53 on - // any interface on the system - // (i.e. all interfaces). The - // "port 53" is optional; if you - // don't specify a port, port 53 - // is assumed. - /* - * Multiple listen-on statements are allowed. Here's a more - * complicated example: - */ - /* - listen-on { 5.6.7.8; }; // listen on port 53 on interface - // 5.6.7.8 - listen-on port 1234 { // listen on port 1234 on any - !1.2.3.4; // interface on network 1.2.3 - 1.2.3/24; // netmask 255.255.255.0, except for - }; // interface 1.2.3.4. - */ - - /* - * Interval Timers - */ - cleaning-interval 60; // clean the cache of expired RRs - // every 'cleaning-interval' minutes - interface-interval 60; // scan for new or deleted interfaces - // every 'interface-interval' minutes - statistics-interval 60; // log statistics every - // 'statistics-interval' minutes - /* - * IXFR options - */ - maintain-ixfr-base no; // If yes, keep transaction log file for IXFR - max-ixfr-log-size 20; // Not implemented, maximum size the - // IXFR transaction log file to grow -}; - -/* - * Control listeners, for "ndc". Every nameserver needs at least one. - */ -controls { - inet * port 52 allow { any; }; // a bad idea - unix "/var/run/ndc" perm 0600 owner 0 group 0; // the default -}; - -zone "master.demo.zone" { - type master; // what used to be called "primary" - file "master.demo.zone"; - check-names fail; - allow-update { none; }; - allow-transfer { any; }; - allow-query { any; }; - // notify yes; // send NOTIFY messages for this - // zone? The global option is used - // if "notify" is not specified - // here. - also-notify { }; // don't notify any nameservers other - // than those on the NS list for this - // zone -}; - -zone "slave.demo.zone" { - type slave; // what used to be called "secondary" - file "slave.demo.zone"; - ixfr-base "slave.demo.zone.ixfr"; // File name for IXFR transaction log file - masters { - 1.2.3.4; // where to zone transfer from - 5.6.7.8; - }; - transfer-source 10.0.0.53; // fixes multihoming problems - check-names warn; - allow-update { none; }; - allow-transfer { any; }; - allow-query { any; }; - max-transfer-time-in 120; // if not set, global option is used. - also-notify { }; // don't notify any nameservers other - // than those on the NS list for this - // zone -}; - -zone "stub.demo.zone" { - type stub; // stub zones are like slave zones, - // except that only the NS records - // are transferred. - file "stub.demo.zone"; - masters { - 1.2.3.4; // where to zone transfer from - 5.6.7.8; - }; - check-names warn; - allow-update { none; }; - allow-transfer { any; }; - allow-query { any; }; - max-transfer-time-in 120; // if not set, global option is used. -}; - -zone "." { - type hint; // used to be specified w/ "cache" - file "cache.db"; - pubkey 257 255 1 "AQP2fHpZ4VMpKo/jc9Fod821uyfY5p8j5h/Am0V/KpBTMZjdXmp9QJe6yFRoIIzkaNCgTIftASdpXGgCwFB2j2KXP/rick6gvEer5VcDEkLR5Q=="; -}; - -trusted-keys { - . 257 255 1 "AQP2fHpZ4VMpKo/jc9Fod821uyfY5p8j5h/Am0V/KpBTMZjdXmp9QJe6yFRoIIzkaNCgTIftASdpXGgCwFB2j2KXP/rick6gvEer5VcDEkLR5Q=="; -}; - - -acl can_query { !1.2.3/24; any; }; // network 1.2.3.0 mask 255.255.255.0 - // is disallowed; rest are OK -acl can_axfr { 1.2.3.4; can_query; }; // host 1.2.3.4 and any host allowed - // by can_query are OK - -zone "non-default-acl.demo.zone" { - type master; - file "foo"; - allow-query { can_query; }; - allow-transfer { can_axfr; }; - allow-update { - 1.2.3.4; - 5.6.7.8; - }; -}; - -key sample_key { // for TSIG - algorithm hmac-md5; // hmac-md5 is the supported algorithm - secret "abcdefgh"; // base 64 encoded secret -}; - -key key2 { - algorithm hmac-md5; - secret "87654321"; -}; - -acl key_acl { key sample_key; }; // a request signed with sample_key - -server 1.2.3.4 { - bogus no; // if yes, we won't query or listen - // to this server - transfer-format one-answer; // set transfer format for this - // server (see the description of - // 'transfer-format' above) - // if not specified, the global option - // will be used - transfers 0; // not implemented - keys { sample_key; key2; }; // for TSIG; sign requests to this - // server with this key - support-ixfr yes; // for IXFR supported by server - // if yes, the listed server talks IXFR -}; - -logging { - /* - * All log output goes to one or more "channels"; you can make as - * many of them as you want. - */ - - channel syslog_errors { // this channel will send errors or - syslog user; // or worse to syslog (user facility) - severity error; - }; - - /* - * Channels have a severity level. Messages at severity levels - * greater than or equal to the channel's level will be logged on - * the channel. In order of decreasing severity, the levels are: - * - * critical a fatal error - * error - * warning - * notice a normal, but significant event - * info an informational message - * debug 1 the least detailed debugging info - * ... - * debug 99 the most detailed debugging info - */ - - /* - * Here are the built-in channels: - * - * channel default_syslog { - * syslog daemon; - * severity info; - * }; - * - * channel default_debug { - * file "named.run"; // note: stderr is used instead - * // of "named.run" if the server - * // is started with the "-f" - * // option. - * severity dynamic; // this means log debugging - * // at whatever debugging level - * // the server is at, and don't - * // log anything if not - * // debugging. - * }; - * - * channel null { // this is the bit bucket; - * file "/dev/null"; // any logging to this channel - * // is discarded. - * }; - * - * channel default_stderr { // writes to stderr - * file "<stderr>"; // this is illustrative only; - * // there's currently no way - * // of saying "stderr" in the - * // configuration language. - * // i.e. don't try this at home. - * severity info; - * }; - * - * default_stderr only works before the server daemonizes (i.e. - * during initial startup) or when it is running in foreground - * mode (-f command line option). - */ - - /* - * There are many categories, so you can send the logs - * you want to see wherever you want, without seeing logs you - * don't want. Right now the categories are - * - * default the catch-all. many things still - * aren't classified into categories, and - * they all end up here. also, if you - * don't specify any channels for a - * category, the default category is used - * instead. - * config high-level configuration file - * processing - * parser low-level configuration file processing - * queries what used to be called "query logging" - * lame-servers messages like "Lame server on ..." - * statistics - * panic if the server has to shut itself - * down due to an internal problem, it - * logs the problem here (as well as - * in the problem's native category) - * update dynamic update - * ncache negative caching - * xfer-in zone transfers we're receiving - * xfer-out zone transfers we're sending - * db all database operations - * eventlib debugging info from the event system - * (see below) - * packet dumps of packets received and sent - * (see below) - * notify the NOTIFY protocol - * cname messages like "XX points to a CNAME" - * security approved/unapproved requests - * os operating system problems - * insist consistency check failures - * maintenance periodic maintenance - * load zone loading - * response-checks messages like - * "Malformed response ..." - * "wrong ans. name ..." - * "unrelated additional info ..." - * "invalid RR type ..." - * "bad referral ..." - */ - - category parser { - syslog_errors; // you can log to as many channels - default_syslog; // as you want - }; - - category lame-servers { null; }; // don't log these at all - - channel moderate_debug { - severity debug 3; // level 3 debugging to file - file "foo"; // foo - print-time yes; // timestamp log entries - print-category yes; // print category name - print-severity yes; // print severity level - /* - * Note that debugging must have been turned on either - * on the command line or with a signal to get debugging - * output (non-debugging output will still be written to - * this channel). - */ - }; - - /* - * If you don't want to see "zone XXXX loaded" messages but do - * want to see any problems, you could do the following. - */ - channel no_info_messages { - syslog; - severity notice; - }; - - category load { no_info_messages; }; - - /* - * You can also define category "default"; it gets used when no - * "category" statement has been given for a category. - */ - category default { - default_syslog; - moderate_debug; - }; - - /* - * If you don't define category default yourself, the default - * default category will be used. It is - * - * category default { default_syslog; default_debug; }; - */ - - /* - * If you don't define category panic yourself, the default - * panic category will be used. It is - * - * category panic { default_syslog; default_stderr; }; - */ - - /* - * Two categories, 'packet' and 'eventlib', are special. Only one - * channel may be assigned to each of them, and it must be a - * file channel. If you don't define them yourself, they default to - * - * category eventlib { default_debug; }; - * - * category packet { default_debug; }; - */ -}; - -include "filename"; // can't do within a statement diff --git a/contrib/bind/bin/named/named.h b/contrib/bind/bin/named/named.h deleted file mode 100644 index e9e95fa5f1652..0000000000000 --- a/contrib/bind/bin/named/named.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * $Id: named.h,v 8.27 2000/04/21 06:54:04 vixie Exp $ - */ - -/* Options. Change them at your peril. */ -#define DEBUG -#define ADDAUTH -#define STUBS -#define RETURNSOA -#define BOGUSNS -#define TRACEROOT -#define XFRNETS -#define QRYLOG -#define YPKLUDGE -#define RENICE -#define BIND_IXFR -#define BIND_NOTIFY -#define BIND_UPDATE -#define WANT_PIDFILE -#define FWD_LOOP -#define DOTTED_SERIAL -#define SENSIBLE_DOTS -#define ROUND_ROBIN -#define DNS_SECURITY -#undef RSAREF -#undef BSAFE -#define ALLOW_LONG_TXT_RDATA -#define STRICT_RFC2308 -#undef BIND_ZXFR - -#include <isc/assertions.h> -#include <isc/list.h> -#include <isc/ctl.h> - -#include <res_update.h> - -#include "pathnames.h" - -#include "ns_defs.h" -#include "db_defs.h" - -#include "ns_glob.h" -#include "db_glob.h" - -#include "ns_func.h" -#include "db_func.h" diff --git a/contrib/bind/bin/named/ns_config.c b/contrib/bind/bin/named/ns_config.c deleted file mode 100644 index 670e288eeae93..0000000000000 --- a/contrib/bind/bin/named/ns_config.c +++ /dev/null @@ -1,3126 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_config.c,v 8.114 2000/04/23 02:18:58 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Check Point Software Technologies Incorporated not be used - * in advertising or publicity pertaining to distribution of the document - * or software without specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND CHECK POINT SOFTWARE TECHNOLOGIES - * INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL CHECK POINT SOFTWARE TECHNOLOGIES INCORPRATED - * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> -#include <unistd.h> -#include <fcntl.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#ifdef HAVE_GETRUSAGE /* XXX */ -#include <sys/resource.h> -#endif - -#include "named.h" -#include "ns_parseutil.h" - -/* Private. */ - -static int tmpnum = 0; -static int config_initialized = 0; - -static int need_logging_free = 0; -static int default_logging_installed; - -static int options_installed = 0; -static int logging_installed = 0; -static int default_options_installed; -static int initial_configuration = 1; - -static char **logging_categories; -static char *current_pid_filename = NULL; - -#define ZONE_SYM_TABLE_SIZE 4973 -static symbol_table zone_symbol_table; - -/* Zones */ - -void -free_zone_timerinfo(struct zoneinfo *zp) { - if (zp->z_timerinfo != NULL) { - freestr(zp->z_timerinfo->name); - memput(zp->z_timerinfo, sizeof *zp->z_timerinfo); - zp->z_timerinfo = NULL; - } else - ns_error(ns_log_config, "timer for zone '%s' had no timerinfo", - zp->z_origin); -} - -void -free_zone_contents(struct zoneinfo *zp, int undefine_sym) { - INSIST(zp != NULL); - - if (undefine_sym) - undefine_symbol(zone_symbol_table, zp->z_origin, zp->z_class); - if (zp->z_flags & Z_TIMER_SET) { - free_zone_timerinfo(zp); - if (evClearTimer(ev, zp->z_timer) < 0) - ns_error(ns_log_config, - "evClearTimer for zone '%s' failed in ns_init: %s", - zp->z_origin, - strerror(errno)); - } - if (zp->z_origin != NULL) - freestr(zp->z_origin); - zp->z_origin = NULL; - if (zp->z_source != NULL) - freestr(zp->z_source); - zp->z_source = NULL; - if (zp->z_ixfr_base != NULL) - freestr(zp->z_ixfr_base); - zp->z_ixfr_base = NULL; - if (zp->z_ixfr_tmp != NULL) - freestr(zp->z_ixfr_tmp); - zp->z_ixfr_tmp = NULL; - if (zp->z_update_acl != NULL) - free_ip_match_list(zp->z_update_acl); - zp->z_update_acl = NULL; - if (zp->z_query_acl != NULL) - free_ip_match_list(zp->z_query_acl); - zp->z_query_acl = NULL; - if (zp->z_transfer_acl != NULL) - free_ip_match_list(zp->z_transfer_acl); - zp->z_transfer_acl = NULL; -#ifdef BIND_UPDATE - if (zp->z_updatelog != NULL) - freestr(zp->z_updatelog); - zp->z_updatelog = NULL; -#endif /* BIND_UPDATE */ -#ifdef BIND_NOTIFY - if (zp->z_also_notify != NULL) - memput(zp->z_also_notify, - zp->z_notify_count * sizeof *zp->z_also_notify); - zp->z_also_notify = NULL; -#endif - block_signals(); - if (LINKED(zp, z_reloadlink)) - UNLINK(reloadingzones, zp, z_reloadlink); - unblock_signals(); -} - -static void -release_zone(struct zoneinfo *zp) { - INSIST(zp != NULL); - - free_zone_contents(zp, 0); - memput(zp, sizeof *zp); -} - -struct zoneinfo * -find_zone(const char *name, int class) { - struct zoneinfo *zp; - symbol_value value; - - ns_debug(ns_log_config, 3, "find_zone(%s, %d)", - *name ? name : ".", class); - if (lookup_symbol(zone_symbol_table, name, class, &value)) { - INSIST(value.integer >= 0 && value.integer < nzones); - ns_debug(ns_log_config, 3, "find_zone: existing zone %d", - value.integer); - zp = &zones[value.integer]; - return (zp); - } - ns_debug(ns_log_config, 3, "find_zone: unknown zone"); - return (NULL); -} - -static struct zoneinfo * -new_zone(int class, int type) { - struct zoneinfo *zp; - - if (EMPTY(freezones)) - make_new_zones(); - - zp = HEAD(freezones); - UNLINK(freezones, zp, z_freelink); - return (zp); -} - -/* - * Check out a zoneinfo structure and return non-zero if it's OK. - */ -static int -validate_zone(struct zoneinfo *zp) { - char filename[MAXPATHLEN+1]; - - /* Check name */ - if (!res_dnok(zp->z_origin)) { - ns_error(ns_log_config, "invalid zone name '%s'", - zp->z_origin); - return (0); - } - - /* Check class */ - if (zp->z_class == C_ANY || zp->z_class == C_NONE) { - ns_error(ns_log_config, "invalid class %d for zone '%s'", - zp->z_class, zp->z_origin); - return (0); - } - - /* Check type. */ - if (zp->z_type == 0) { - ns_error(ns_log_config, "no type specified for zone '%s'", - zp->z_origin); - return (0); - } - if (zp->z_type == z_cache && ns_samename(zp->z_origin, "") != 1) { - ns_error(ns_log_config, - "only the root zone may be a cache zone (zone '%s')", - zp->z_origin); - return (0); - } - if (zp->z_type == z_hint && ns_samename(zp->z_origin, "") != 1) { - ns_error(ns_log_config, - "only the root zone may be a hint zone (zone '%s')", - zp->z_origin); - return (0); - } - - /* Check filename. */ - if (zp->z_type == z_master && zp->z_source == NULL) { - ns_error(ns_log_config, - "'file' statement missing for master zone %s", - zp->z_origin); - return (0); - } - /* - * XXX We should run filename through an OS-specific - * validator here. - */ - if (zp->z_source != NULL && - strlen(zp->z_source) > MAXPATHLEN) { - ns_error(ns_log_config, "filename too long for zone '%s'", - zp->z_origin); - return (0); - } - - if (zp->z_ixfr_base != NULL && strlen(zp->z_ixfr_base) > MAXPATHLEN) { - ns_error(ns_log_config, "ixfr filename too long for zone '%s'", - zp->z_origin); - return (0); - } - if (zp->z_ixfr_tmp != NULL && strlen(zp->z_ixfr_tmp) > MAXPATHLEN) { - ns_error(ns_log_config, "tmp ixfr filename too long for zone '%s'", - zp->z_origin); - return (0); - } - - /* Check masters */ - if (zp->z_addrcnt != 0) { - if (zp->z_type == z_master || zp->z_type == z_hint || - zp->z_type == z_cache) { - ns_error(ns_log_config, - "'masters' statement present for %s zone '%s'", - (zp->z_type == z_master) ? "master" : - (zp->z_type == z_hint) ? "hint" : "cache", - zp->z_origin); - return (0); - } - } else { - if (zp->z_type == z_slave || zp->z_type == z_stub) { - ns_error(ns_log_config, - "no 'masters' statement for non-master zone '%s'", - zp->z_origin); - return (0); - } - } - - /* Check allow-update and allow-transfer. */ - if (zp->z_update_acl || zp->z_transfer_acl) { - if (zp->z_type != z_master && zp->z_type != z_slave) { - ns_error(ns_log_config, - "'allow-{update,transfer}' option for non-{master,slave} zone '%s'", - zp->z_origin); - return (0); - } - } - - /* Check allow-query. */ - if (zp->z_query_acl) { - if (zp->z_type != z_master && - zp->z_type != z_slave && - zp->z_type != z_stub) { - ns_error(ns_log_config, - "'allow-query' option for non-{master,slave,stub} zone '%s'", - zp->z_origin); - return (0); - } - } - -#ifdef BIND_NOTIFY - /* Check notify */ - if (zp->z_notify != znotify_use_default) { - if (zp->z_type != z_master && zp->z_type != z_slave) { - ns_error(ns_log_config, - "'notify' given for non-master, non-slave zone '%s'", - zp->z_origin); - return (0); - } - } - - /* Check also-notify */ - if (zp->z_notify_count != 0) { - if (zp->z_type != z_master && zp->z_type != z_slave) { - ns_error(ns_log_config, - "'also-notify' given for non-master, non-slave zone '%s'", - zp->z_origin); - return (0); - } - } -#endif - -#ifdef BIND_UPDATE - /* XXX need more checking here */ - if (!zp->z_updatelog && zp->z_source) { - /* XXX OS-specific filename validation here */ - if ((strlen(zp->z_source) + (sizeof ".log" - 1)) > - MAXPATHLEN) { - ns_error(ns_log_config, - "filename too long for dynamic zone '%s'", - zp->z_origin); - return (0); - } - /* this sprintf() is now safe */ - sprintf(filename, "%s.log", zp->z_source); - zp->z_updatelog = savestr(filename, 1); - } - - /* Check forward */ - if (zp->z_optset & OPTION_FORWARD_ONLY) { - if (zp->z_type == z_hint) { - ns_error(ns_log_config, - "'forward' given for hint zone '%s'", - zp->z_origin); - return (0); - } - } - /* Check forwarders */ - if (zp->z_fwdtab) { - if (zp->z_type == z_hint) { - ns_error(ns_log_config, - "'forwarders' given for hint zone '%s'", - zp->z_origin); - return (0); - } - } - - if (zp->z_type == z_master) { - if (!zp->z_soaincrintvl) - zp->z_soaincrintvl = SOAINCRINTVL; - if (!zp->z_dumpintvl) - zp->z_dumpintvl = DUMPINTVL; - if (!zp->z_deferupdcnt) - zp->z_deferupdcnt = DEFERUPDCNT; - } -#endif /* BIND_UPDATE */ - - if (!zp->z_ixfr_base && zp->z_source) { - /* XXX OS-specific filename validation here */ - if ((strlen(zp->z_source) + (sizeof ".ixfr" - 1)) > - MAXPATHLEN) { - ns_error(ns_log_config, - "filename too long for dynamic zone '%s'", - zp->z_origin); - return (0); - } - /* this sprintf() is now safe */ - sprintf(filename, "%s.ixfr", zp->z_source); - zp->z_ixfr_base = savestr(filename, 1); - } - if (!zp->z_ixfr_tmp && zp->z_source) { - /* XXX OS-specific filename validation here */ - if ((strlen(zp->z_source) + (sizeof ".ixfr.tmp" - 1)) > - MAXPATHLEN) { - ns_error(ns_log_config, - "filename too long for dynamic zone '%s'", - zp->z_origin); - return (0); - } - /* this sprintf() is now safe */ - sprintf(filename, "%s.ixfr.tmp", zp->z_source); - zp->z_ixfr_tmp = savestr(filename, 1); - } - - return (1); -} - -/* - * Start building a new zoneinfo structure. Returns an opaque - * zone_config suitable for use by the parser. - */ -zone_config -begin_zone(char *name, int class) { - zone_config zh; - struct zoneinfo *zp; - - /* - * require: name is canonical, class is a valid class - */ - - ns_debug(ns_log_config, 3, "begin_zone('%s', %d)", - (*name == '\0') ? "." : name, class); - - zp = (struct zoneinfo *)memget(sizeof (struct zoneinfo)); - if (zp == NULL) - panic("memget failed in begin_zone", NULL); - memset(zp, 0, sizeof (struct zoneinfo)); - zp->z_origin = name; - zp->z_class = class; - zp->z_checknames = not_set; - if (server_options->flags & OPTION_MAINTAIN_IXFR_BASE) - zp->z_maintain_ixfr_base = 1; - else - zp->z_maintain_ixfr_base = 0; - zp->z_max_log_size_ixfr = server_options->max_log_size_ixfr; - zh.opaque = zp; - return (zh); -} - -/* - * Merge new configuration information into an existing zone. The - * new zoneinfo must be valid. - */ -static void -update_zone_info(struct zoneinfo *zp, struct zoneinfo *new_zp) { - char buf[MAXPATHLEN+1]; - int i; - - INSIST(zp != NULL); - INSIST(new_zp != NULL); - - ns_debug(ns_log_config, 1, "update_zone_info('%s', %d)", - (*new_zp->z_origin == '\0') ? "." : new_zp->z_origin, - new_zp->z_type); - -#ifdef BIND_UPDATE - /* - * A dynamic master zone that's becoming non-dynamic may need to be - * dumped before we start the update. - */ - if ((zp->z_flags & Z_DYNAMIC) && !(new_zp->z_flags & Z_DYNAMIC) && - ((zp->z_flags & Z_NEED_SOAUPDATE) || - (zp->z_flags & Z_NEED_DUMP))) - (void) zonedump(zp, ISNOTIXFR); -#endif - - /* - * First do the simple stuff, making sure to free - * any data that was dynamically allocated. - */ - if (zp->z_origin != NULL) - freestr(zp->z_origin); - zp->z_origin = new_zp->z_origin; - new_zp->z_origin = NULL; - zp->z_maintain_ixfr_base = new_zp->z_maintain_ixfr_base; - zp->z_max_log_size_ixfr = new_zp->z_max_log_size_ixfr; - zp->z_class = new_zp->z_class; - zp->z_type = new_zp->z_type; - zp->z_checknames = new_zp->z_checknames; - for (i = 0; i < new_zp->z_addrcnt; i++) - zp->z_addr[i] = new_zp->z_addr[i]; - zp->z_addrcnt = new_zp->z_addrcnt; - if (zp->z_update_acl) - free_ip_match_list(zp->z_update_acl); - zp->z_update_acl = new_zp->z_update_acl; - new_zp->z_update_acl = NULL; - if (zp->z_query_acl) - free_ip_match_list(zp->z_query_acl); - zp->z_query_acl = new_zp->z_query_acl; - new_zp->z_query_acl = NULL; - zp->z_axfr_src = new_zp->z_axfr_src; - if (zp->z_transfer_acl) - free_ip_match_list(zp->z_transfer_acl); - zp->z_transfer_acl = new_zp->z_transfer_acl; - new_zp->z_transfer_acl = NULL; - zp->z_max_transfer_time_in = new_zp->z_max_transfer_time_in; -#ifdef BIND_NOTIFY - zp->z_notify = new_zp->z_notify; - if (zp->z_also_notify) - memput(zp->z_also_notify, - zp->z_notify_count * sizeof *zp->z_also_notify); - zp->z_also_notify = new_zp->z_also_notify; - zp->z_notify_count = new_zp->z_notify_count; - new_zp->z_also_notify = NULL; - new_zp->z_notify_count = 0; -#endif - if ((new_zp->z_flags & Z_FORWARD_SET) != 0) - zp->z_flags |= Z_FORWARD_SET; - else - zp->z_flags &= ~Z_FORWARD_SET; - if (zp->z_fwdtab != NULL) - free_forwarders(zp->z_fwdtab); - zp->z_fwdtab = new_zp->z_fwdtab; - new_zp->z_fwdtab = NULL; - - zp->z_dialup = new_zp->z_dialup; - zp->z_options = new_zp->z_options; - zp->z_optset = new_zp->z_optset; - -#ifdef BIND_UPDATE - if (new_zp->z_flags & Z_DYNAMIC) - zp->z_flags |= Z_DYNAMIC; - else - zp->z_flags &= ~Z_DYNAMIC; - zp->z_soaincrintvl = new_zp->z_soaincrintvl; - zp->z_dumpintvl = new_zp->z_dumpintvl; - zp->z_deferupdcnt = new_zp->z_deferupdcnt; - if (zp->z_updatelog) - freestr(zp->z_updatelog); - zp->z_updatelog = new_zp->z_updatelog; - new_zp->z_updatelog = NULL; -#endif /* BIND_UPDATE */ - zp->z_port = new_zp->z_port; - - /* - * Now deal with files. - */ - switch (zp->z_type) { - case z_cache: - ns_panic(ns_log_config, 1, "impossible condition"); - break; - case z_hint: - ns_debug(ns_log_config, 1, "source = %s", new_zp->z_source); - zp->z_refresh = 0; /* No dumping. */ - if (zp->z_source != NULL && - strcmp(new_zp->z_source, zp->z_source) == 0 && - (reconfiging || !zonefile_changed_p(zp))) { - ns_debug(ns_log_config, 1, "cache is up to date"); - break; - } - - /* File has changed, or hasn't been loaded yet. */ - if (zp->z_source) { - freestr(zp->z_source); - ns_stopxfrs(zp); - purge_zone(zp->z_origin, fcachetab, zp->z_class); - } - zp->z_source = new_zp->z_source; - new_zp->z_source = NULL; - - if (zp->z_ixfr_base) - freestr(zp->z_ixfr_base); - zp->z_ixfr_base = new_zp->z_ixfr_base; - new_zp->z_ixfr_base = NULL; - - if (zp->z_ixfr_tmp) - freestr(zp->z_ixfr_tmp); - zp->z_ixfr_tmp = new_zp->z_ixfr_tmp; - new_zp->z_ixfr_tmp = NULL; - - ns_debug(ns_log_config, 1, "reloading hint zone"); - (void) db_load(zp->z_source, zp->z_origin, zp, NULL, - ISNOTIXFR); - break; - - case z_master: - ns_debug(ns_log_config, 1, "source = %s", new_zp->z_source); - /* - * If we've loaded this file, and the file hasn't changed - * then there's no need to reload. - */ - if (zp->z_source != NULL && - strcmp(new_zp->z_source, zp->z_source) == 0 && - (reconfiging || !zonefile_changed_p(zp))) { - ns_debug(ns_log_config, 1, "zone is up to date"); - break; - } -#ifdef BIND_UPDATE - if (zp->z_source && (zp->z_flags & Z_DYNAMIC)) - ns_warning(ns_log_config, - "source file of dynamic zone '%s' has changed", - zp->z_origin); - - primary_reload: -#endif /* BIND_UPDATE */ - if (zp->z_source != NULL) - freestr(zp->z_source); - zp->z_source = new_zp->z_source; - new_zp->z_source = NULL; - - if (zp->z_ixfr_base != NULL) - freestr(zp->z_ixfr_base); - zp->z_ixfr_base = new_zp->z_ixfr_base; - new_zp->z_ixfr_base = NULL; - - if (zp->z_ixfr_tmp != NULL) - freestr(zp->z_ixfr_tmp); - zp->z_ixfr_tmp = new_zp->z_ixfr_tmp; - new_zp->z_ixfr_tmp = NULL; - - if (reload_master(zp) == 1) { - /* - * Note that going to primary_reload - * unconditionally reloads the zone. - */ - new_zp->z_source = savestr(zp->z_source, 1); - new_zp->z_ixfr_base = savestr(zp->z_ixfr_base, 1); - new_zp->z_ixfr_tmp = savestr(zp->z_ixfr_tmp, 1); - goto primary_reload; - } - break; - - case z_slave: -#ifdef STUBS - case z_stub: -#endif - ns_debug(ns_log_config, 1, "addrcnt = %d", zp->z_addrcnt); - if (!new_zp->z_source) { - /* - * We will always transfer this zone again - * after a reload. - */ - sprintf(buf, "NsTmp%ld.%d", (long)getpid(), tmpnum++); - new_zp->z_source = savestr(buf, 1); - zp->z_flags |= Z_TMP_FILE; - } else - zp->z_flags &= ~Z_TMP_FILE; - /* - * If we had a backup file name, and it was changed, - * free old zone and start over. If we don't have - * current zone contents, try again now in case - * we have a new server on the list. - */ - if (zp->z_source != NULL && - (strcmp(new_zp->z_source, zp->z_source) != 0 || - ((!reconfiging) && zonefile_changed_p(zp)))) { - ns_debug(ns_log_config, 1, - "backup file changed or missing"); - freestr(zp->z_source); - zp->z_source = NULL; - zp->z_serial = 0; /* force xfer */ - ns_stopxfrs(zp); - /* - * We only need to reload if we have ever - * successfully transferred the zone. - */ - if ((zp->z_flags & Z_AUTH) != 0) { - zp->z_flags &= ~Z_AUTH; - /* - * Purge old data and mark the parent for - * reloading so that NS records are present - * during the zone transfer. - */ - do_reload(zp->z_origin, zp->z_type, - zp->z_class, 1); - } - } - if (zp->z_source == NULL) { - zp->z_source = new_zp->z_source; - new_zp->z_source = NULL; - } - - if (zp->z_ixfr_base != NULL) - freestr(zp->z_ixfr_base); - zp->z_ixfr_base = new_zp->z_ixfr_base; - new_zp->z_ixfr_base = NULL; - - if (zp->z_ixfr_tmp != NULL) - freestr(zp->z_ixfr_tmp); - zp->z_ixfr_tmp = new_zp->z_ixfr_tmp; - new_zp->z_ixfr_tmp = NULL; - - if ((!noexpired || ((zp->z_flags & Z_EXPIRED) == 0)) && - ((zp->z_flags & Z_AUTH) == 0)) - zoneinit(zp); - else { - /* - ** Force secondary to try transfer soon - ** after SIGHUP. - */ - if ((zp->z_flags & (Z_QSERIAL|Z_XFER_RUNNING)) == 0 && - reloading && !reconfiging) { - qserial_retrytime(zp, tt.tv_sec); - sched_zone_maint(zp); - } - } - break; - case z_forward: - /* - * We don't know if the forwarder's list has changed - * so just purge the cache. In the future we may want - * see if the forwarders list has changed and only - * do this then. - */ - clean_cache_from(zp->z_origin, hashtab); - break; - } - if ((zp->z_flags & Z_FOUND) != 0 && /* already found? */ - (zp - zones) != DB_Z_CACHE) /* cache never sets Z_FOUND */ - ns_error(ns_log_config, "Zone \"%s\" declared more than once", - zp->z_origin); - zp->z_flags |= Z_FOUND; - ns_debug(ns_log_config, 1, - "zone[%d] type %d: '%s' z_time %lu, z_refresh %u", - zp-zones, zp->z_type, - *(zp->z_origin) == '\0' ? "." : zp->z_origin, - (u_long)zp->z_time, zp->z_refresh); -} - -/* - * Finish constructing a new zone. If valid, the constructed zone is - * merged into the zone database. The zone_config used is invalid after - * end_zone() completes. - */ -void -end_zone(zone_config zh, int should_install) { - struct zoneinfo *zp, *new_zp; - char *zname; - symbol_value value; - - new_zp = zh.opaque; - INSIST(new_zp != NULL); - - zname = (new_zp->z_origin[0] == '\0') ? "." : new_zp->z_origin; - ns_debug(ns_log_config, 3, "end_zone('%s', %d)", zname, - should_install); - - if (!should_install) { - release_zone(new_zp); - return; - } - if (!validate_zone(new_zp)) { - ns_error(ns_log_config, - "zone '%s' did not validate, skipping", zname); - release_zone(new_zp); - return; - } - zp = find_zone(new_zp->z_origin, new_zp->z_class); - if (zp != NULL && zp->z_type != new_zp->z_type) { - remove_zone(zp, "redefined"); - zp = NULL; - } - if (zp == NULL) { - zp = new_zone(new_zp->z_class, new_zp->z_type); - INSIST(zp != NULL); - value.integer = (zp - zones); - define_symbol(zone_symbol_table, savestr(new_zp->z_origin, 1), - new_zp->z_class, value, SYMBOL_FREE_KEY); - } - ns_debug(ns_log_config, 5, "zone '%s', type = %d, class = %d", zname, - new_zp->z_type, new_zp->z_class); - if (new_zp->z_source != NULL) - ns_debug(ns_log_config, 5, " file = %s", new_zp->z_source); - ns_debug(ns_log_config, 5, " checknames = %d", new_zp->z_checknames); - if (new_zp->z_addrcnt != 0) { - int i; - - ns_debug(ns_log_config, 5, " masters:"); - for (i = 0; i < new_zp->z_addrcnt; i++) - ns_debug(ns_log_config, 5, " %s", - inet_ntoa(new_zp->z_addr[i])); - } - - update_zone_info(zp, new_zp); - release_zone(new_zp); - zh.opaque = NULL; -} - -int -set_zone_type(zone_config zh, int type) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Fail if type already set for this zone */ - if (zp->z_type != 0) - return (0); - zp->z_type = type; - return (1); -} - -int -set_zone_filename(zone_config zh, char *filename) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Fail if filename already set for this zone */ - if (zp->z_source != NULL) - return (0); - zp->z_source = filename; - return (1); -} - -int -set_zone_checknames(zone_config zh, enum severity s) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Fail if checknames already set for this zone */ - if (zp->z_checknames != not_set) - return (0); - zp->z_checknames = s; - return (1); -} - -int -set_zone_ixfr_file(zone_config zh, char *filename) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Fail if filename already set for this zone */ - if (zp->z_ixfr_base != NULL) - return (0); - zp->z_ixfr_base = filename; - if (zp->z_ixfr_tmp == NULL) { - int len = strlen(zp->z_ixfr_base) + (sizeof ".tmp"); - char *str = (char *) memget(len); - - sprintf(str, "%s.tmp", zp->z_ixfr_base); - zp->z_ixfr_tmp = savestr(str, 1); - memput(str, len); - } - - return (1); -} - -int -set_zone_ixfr_tmp(zone_config zh, char *filename) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Fail if filename already set for this zone */ - if (zp->z_ixfr_tmp != NULL) - return (0); - zp->z_ixfr_tmp = filename; - return (1); -} - -int -set_zone_dialup(zone_config zh, int value) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - if (value) { - zp->z_dialup = zdialup_yes; -#ifdef BIND_NOTIFY - zp->z_notify = znotify_yes; -#endif - } else - zp->z_dialup = zdialup_no; - - return (1); -} - -int -set_zone_notify(zone_config zh, int value) { -#ifdef BIND_NOTIFY - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - if (value) - zp->z_notify = znotify_yes; - else - zp->z_notify = znotify_no; -#endif - return (1); -} - -int -set_zone_maintain_ixfr_base(zone_config zh, int value) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - zp->z_maintain_ixfr_base = value; - - return (1); -} - -int -set_zone_update_acl(zone_config zh, ip_match_list iml) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Fail if update_acl already set for this zone */ - if (zp->z_update_acl != NULL) - return (0); - zp->z_update_acl = iml; -#ifdef BIND_UPDATE - if (!ip_match_is_none(iml)) - zp->z_flags |= Z_DYNAMIC; - else - ns_debug(ns_log_config, 3, "update acl is none for '%s'", - zp->z_origin); -#endif - return (1); -} - -int -set_zone_query_acl(zone_config zh, ip_match_list iml) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Fail if checknames already set for this zone */ - if (zp->z_query_acl != NULL) - return (0); - zp->z_query_acl = iml; - return (1); -} - -int -set_zone_master_port(zone_config zh, u_short port) { - struct zoneinfo *zp = zh.opaque; - - zp->z_port = port; - return (1); -} - -int -set_zone_transfer_source(zone_config zh, struct in_addr ina) { - struct zoneinfo *zp = zh.opaque; - - zp->z_axfr_src = ina; - return (1); -} - -int -set_zone_transfer_acl(zone_config zh, ip_match_list iml) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Fail if checknames already set for this zone */ - if (zp->z_transfer_acl != NULL) - return (0); - zp->z_transfer_acl = iml; - return (1); -} - -int -set_zone_transfer_time_in(zone_config zh, long max_time) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Fail if checknames already set for this zone */ - if (zp->z_max_transfer_time_in) - return (0); - zp->z_max_transfer_time_in = max_time; - return (1); -} - -int -set_zone_max_log_size_ixfr(zone_config zh, int size) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - zp->z_max_log_size_ixfr = size; - return (0); -} - -int -set_zone_pubkey(zone_config zh, const int flags, const int proto, - const int alg, const char *str) -{ - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - INSIST(zp != NULL && zp->z_origin != NULL); - return (add_trusted_key(zp->z_origin, flags, proto, alg, str)); -} - -int -set_trusted_key(const char *name, const int flags, const int proto, - const int alg, const char *str) { - INSIST(name != NULL); - return (add_trusted_key(name, flags, proto, alg, str)); -} - -int -add_zone_master(zone_config zh, struct in_addr address) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - zp->z_addr[zp->z_addrcnt] = address; - zp->z_addrcnt++; - if (zp->z_addrcnt >= NSMAX) { - ns_warning(ns_log_config, "NSMAX reached for zone '%s'", - zp->z_origin); - zp->z_addrcnt = NSMAX - 1; - } - return (1); -} - -int -add_zone_notify(zone_config zh, struct in_addr address) { -#ifdef BIND_NOTIFY - struct zoneinfo *zp; - int i; - - zp = zh.opaque; - INSIST(zp != NULL); - - /* Check for duplicates. */ - - for (i = 0; i < zp->z_notify_count; i++) { - if (memcmp(zp->z_also_notify + i, - &address, sizeof address) == 0) { - ns_warning(ns_log_config, - "duplicate also-notify address ignored [%s] for zone '%s'", - inet_ntoa(address), zp->z_origin); - return (1); - } - } - i = 0; - - if (zp->z_also_notify == NULL) { - zp->z_also_notify = memget(sizeof *zp->z_also_notify); - if (zp->z_also_notify == NULL) - i = 1; - } else { - register size_t size; - register struct in_addr *an_tmp; - size = zp->z_notify_count * sizeof *zp->z_also_notify; - an_tmp = memget(size + sizeof *zp->z_also_notify); - if (an_tmp == NULL) { - i = 1; - } else { - memcpy(an_tmp, zp->z_also_notify, size); - memput(zp->z_also_notify, size); - zp->z_also_notify = an_tmp; - } - } - if (i == 0) { - zp->z_also_notify[zp->z_notify_count] = address; - zp->z_notify_count++; - } else { - ns_warning(ns_log_config, "also-notify add failed (memget) [%s] for zone '%s'", - inet_ntoa(address), zp->z_origin); - } -#endif - return (1); -} - -/* Options */ - -options -new_options() { - options op; - - op = (options)memget(sizeof (struct options)); - if (op == NULL) - panic("memget failed in new_options()", NULL); - - op->version = savestr(ShortVersion, 1); - op->directory = savestr(".", 1); - op->pid_filename = savestr(_PATH_PIDFILE, 1); - op->named_xfer = savestr(_PATH_XFER, 1); - op->dump_filename = savestr(_PATH_DUMPFILE, 1); - op->stats_filename = savestr(_PATH_STATS, 1); - op->memstats_filename = savestr(_PATH_MEMSTATS, 1); - op->flags = DEFAULT_OPTION_FLAGS; - op->transfers_in = DEFAULT_XFERS_RUNNING; - op->transfers_per_ns = DEFAULT_XFERS_PER_NS; - op->transfers_out = 0; - op->serial_queries = MAXQSERIAL; - op->transfer_format = axfr_one_answer; - op->max_transfer_time_in = MAX_XFER_TIME; - memset(&op->query_source, 0, sizeof op->query_source); - op->query_source.sin_family = AF_INET; - op->query_source.sin_addr.s_addr = htonl(INADDR_ANY); - op->query_source.sin_port = htons(0); /* INPORT_ANY */ - op->axfr_src.s_addr = 0; -#ifdef BIND_NOTIFY - op->notify_count = 0; - op->also_notify = NULL; -#endif - op->blackhole_acl = NULL; - op->query_acl = NULL; - op->transfer_acl = NULL; - op->recursion_acl = NULL; - op->sortlist = NULL; - op->topology = NULL; - op->data_size = 0UL; /* use system default */ - op->stack_size = 0UL; /* use system default */ - op->core_size = 0UL; /* use system default */ - op->files = ULONG_MAX; /* unlimited */ - op->check_names[primary_trans] = fail; - op->check_names[secondary_trans] = warn; - op->check_names[response_trans] = ignore; - op->listen_list = NULL; - op->fwdtab = NULL; - /* XXX init forwarding */ - op->clean_interval = 3600; - op->interface_interval = 3600; - op->stats_interval = 3600; - op->ordering = NULL; - op->max_ncache_ttl = DEFAULT_MAX_NCACHE_TTL; - op->lame_ttl = NTTL; - op->heartbeat_interval = 3600; - op->max_log_size_ixfr = 20; - op->minroots = MINROOTS; - return (op); -} - -void -free_options(options op) { - INSIST(op != NULL); - - if (op->version) - freestr(op->version); - if (op->directory) - freestr(op->directory); - if (op->pid_filename) - freestr(op->pid_filename); - if (op->named_xfer) - freestr(op->named_xfer); - if (op->dump_filename) - freestr(op->dump_filename); - if (op->stats_filename) - freestr(op->stats_filename); - if (op->memstats_filename) - freestr(op->memstats_filename); -#ifdef BIND_NOTIFY - if (op->also_notify) - free_also_notify(op); -#endif - if (op->blackhole_acl) - free_ip_match_list(op->blackhole_acl); - if (op->query_acl) - free_ip_match_list(op->query_acl); - if (op->recursion_acl) - free_ip_match_list(op->recursion_acl); - if (op->transfer_acl) - free_ip_match_list(op->transfer_acl); - if (op->sortlist) - free_ip_match_list(op->sortlist); - if (op->ordering) - free_rrset_order_list(op->ordering); - if (op->topology) - free_ip_match_list(op->topology); - if (op->listen_list) - free_listen_info_list(op->listen_list); - if (op->fwdtab) - free_forwarders(op->fwdtab); - memput(op, sizeof *op); -} - -static void -set_boolean_option(u_int *op_flags, int bool_opt, int value) { - INSIST(op_flags != NULL); - - switch (bool_opt) { - case OPTION_NORECURSE: - case OPTION_NOFETCHGLUE: - case OPTION_FORWARD_ONLY: - case OPTION_FAKE_IQUERY: - case OPTION_NONOTIFY: - case OPTION_NONAUTH_NXDOMAIN: - case OPTION_MULTIPLE_CNAMES: - case OPTION_USE_IXFR: - case OPTION_MAINTAIN_IXFR_BASE: - case OPTION_HOSTSTATS: - case OPTION_DEALLOC_ON_EXIT: - case OPTION_USE_ID_POOL: - case OPTION_NORFC2308_TYPE1: - case OPTION_NODIALUP: - case OPTION_TREAT_CR_AS_SPACE: - if (value) - *op_flags |= bool_opt; - else - *op_flags &= ~bool_opt; - break; - default: - panic("unexpected option in set_boolean_option", NULL); - } -} - -void -set_global_boolean_option(options op, int bool_opt, int value) { - - INSIST(op != NULL); - - set_boolean_option(&op->flags, bool_opt, value); -} - -void -set_zone_boolean_option(zone_config zh, int bool_opt, int value) { - struct zoneinfo *zp; - - zp = zh.opaque; - INSIST(zp != NULL); - - set_boolean_option(&zp->z_options, bool_opt, value); - - /* Flag that zone option overrides corresponding global option */ - zp->z_optset |= bool_opt; -} - -#ifdef HAVE_GETRUSAGE -enum limit { Datasize, Stacksize, Coresize, Files }; - -static struct rlimit initial_data_size; -static struct rlimit initial_stack_size; -static struct rlimit initial_core_size; -static struct rlimit initial_num_files; - -static void -get_initial_limits() { - int fdlimit = evHighestFD(ev) + 1; - -# ifdef RLIMIT_DATA - if (getrlimit(RLIMIT_DATA, &initial_data_size) < 0) - ns_warning(ns_log_config, "getrlimit(DATA): %s", - strerror(errno)); -# endif -# ifdef RLIMIT_STACK - if (getrlimit(RLIMIT_STACK, &initial_stack_size) < 0) - ns_warning(ns_log_config, "getrlimit(STACK): %s", - strerror(errno)); -# endif -# ifdef RLIMIT_CORE - if (getrlimit(RLIMIT_CORE, &initial_core_size) < 0) - ns_warning(ns_log_config, "getrlimit(CORE): %s", - strerror(errno)); -# endif -# ifdef RLIMIT_NOFILE - if (getrlimit(RLIMIT_NOFILE, &initial_num_files) < 0) - ns_warning(ns_log_config, "getrlimit(NOFILE): %s", - strerror(errno)); - else if (initial_num_files.rlim_cur > fdlimit) { - initial_num_files.rlim_cur = fdlimit; - if (initial_num_files.rlim_cur > initial_num_files.rlim_max) - initial_num_files.rlim_max = fdlimit; - if (setrlimit(RLIMIT_NOFILE, &initial_num_files) < 0) { - ns_warning(ns_log_config, "setrlimit(files): %s", - strerror(errno)); - } else { - ns_warning(ns_log_config, - "limit files set to fdlimit (%d)", - fdlimit); - } - } -# endif -} - -static void -ns_rlimit(enum limit limit, u_long limit_value) { - struct rlimit limits, old_limits; - int rlimit = -1; - int fdlimit = evHighestFD(ev) + 1; - char *name; - rlimit_type value; - - if (limit_value == ULONG_MAX) { -#ifndef RLIMIT_FILE_INFINITY - if (limit == Files) - value = MIN((rlimit_type)evHighestFD(ev) + 1, - initial_num_files.rlim_max); - else -#endif - value = (rlimit_type)RLIM_INFINITY; - } else - value = (rlimit_type)limit_value; - - limits.rlim_cur = limits.rlim_max = value; - switch (limit) { - case Datasize: -#ifdef RLIMIT_DATA - rlimit = RLIMIT_DATA; -#endif - name = "max data size"; - if (value == 0) - limits = initial_data_size; - break; - case Stacksize: -#ifdef RLIMIT_STACK - rlimit = RLIMIT_STACK; -#endif - name = "max stack size"; - if (value == 0) - limits = initial_stack_size; - break; - case Coresize: -#ifdef RLIMIT_CORE - rlimit = RLIMIT_CORE; -#endif - name = "max core size"; - if (value == 0) - limits = initial_core_size; - break; - case Files: -#ifdef RLIMIT_NOFILE - rlimit = RLIMIT_NOFILE; -#endif - name = "max number of open files"; - if (value == 0) - limits = initial_num_files; - if (value > fdlimit) - limits.rlim_cur = limits.rlim_max = value = fdlimit; - break; - default: - name = NULL; /* Make gcc happy. */ - panic("impossible condition in ns_rlimit()", NULL); - } - if (rlimit == -1) { - ns_warning(ns_log_config, - "limit \"%s\" not supported on this system - ignored", - name); - return; - } - if (getrlimit(rlimit, &old_limits) < 0) { - ns_warning(ns_log_config, "getrlimit(%s): %s", name, - strerror(errno)); - } - if (user_id != 0 && limits.rlim_max == RLIM_INFINITY) - limits.rlim_cur = limits.rlim_max = old_limits.rlim_max; - if (setrlimit(rlimit, &limits) < 0) { - ns_warning(ns_log_config, "setrlimit(%s): %s", name, - strerror(errno)); - return; - } else { - if (value == 0) - ns_debug(ns_log_config, 3, "%s is default", name); - else if (value == RLIM_INFINITY) - ns_debug(ns_log_config, 3, "%s is unlimited", name); - else -#ifdef RLIMIT_LONGLONG - ns_debug(ns_log_config, 3, "%s is %llu", name, - (unsigned long long)value); -#else - ns_debug(ns_log_config, 3, "%s is %lu", name, value); -#endif - } -} -#endif /* HAVE_GETRUSAGE */ - -listen_info_list -new_listen_info_list() { - listen_info_list ll; - - ll = (listen_info_list)memget(sizeof (struct listen_info_list)); - if (ll == NULL) - panic("memget failed in new_listen_info_list()", NULL); - ll->first = NULL; - ll->last = NULL; - return (ll); -} - -void -free_listen_info_list(listen_info_list ll) { - listen_info li, next_li; - - INSIST(ll != NULL); - for (li = ll->first; li != NULL; li = next_li) { - next_li = li->next; - free_ip_match_list(li->list); - memput(li, sizeof *li); - } - memput(ll, sizeof *ll); -} - -void -add_listen_on(options op, u_short port, ip_match_list iml) { - listen_info_list ll; - listen_info ni; - - INSIST(op != NULL); - - if (op->listen_list == NULL) - op->listen_list = new_listen_info_list(); - ll = op->listen_list; - ni = (listen_info)memget(sizeof (struct listen_info)); - if (ni == NULL) - panic("memget failed in add_listen_on", NULL); - ni->port = port; - ni->list = iml; - ni->next = NULL; - if (ll->last != NULL) - ll->last->next = ni; - ll->last = ni; - if (ll->first == NULL) - ll->first = ni; -} - -FILE * -write_open(char *filename) { - FILE *stream; - int fd; - struct stat sb; - int regular; - - if (stat(filename, &sb) < 0) { - if (errno != ENOENT) { - ns_error(ns_log_os, - "write_open: stat of %s failed: %s", - filename, strerror(errno)); - return (NULL); - } - regular = 1; - } else - regular = (sb.st_mode & S_IFREG); - - if (!regular) { - ns_error(ns_log_os, "write_open: %s isn't a regular file", - filename); - return (NULL); - } - - (void)unlink(filename); - fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, - S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); - if (fd < 0) - return (NULL); - (void) fchown(fd, user_id, group_id); - stream = fdopen(fd, "w"); - if (stream == NULL) - (void)close(fd); - return (stream); -} - -void -update_pid_file() { - FILE *fp; - - REQUIRE(server_options != NULL); - REQUIRE(server_options->pid_filename != NULL); - - /* XXX */ ns_debug(ns_log_default, 1, "update_pid_file()"); - if (current_pid_filename != NULL) { - (void)unlink(current_pid_filename); - freestr(current_pid_filename); - current_pid_filename = NULL; - } - current_pid_filename = savestr(server_options->pid_filename, 0); - if (current_pid_filename == NULL) { - ns_error(ns_log_config, - "savestr() failed in update_pid_file()"); - return; - } - fp = write_open(current_pid_filename); - if (fp != NULL) { - (void) fprintf(fp, "%ld\n", (long)getpid()); - (void) fclose(fp); - } else - ns_error(ns_log_config, "couldn't create pid file '%s'", - server_options->pid_filename); -} - -/* - * XXX This function will eventually be public and will be relocated to - * the UNIX OS support library. - */ - -static int -os_change_directory(const char *name) { - struct stat sb; - - if (name == NULL || - *name == '\0') { - errno = EINVAL; - return (0); - } - - if (chdir(name) < 0) - return (0); - - if (stat(name, &sb) < 0) { - ns_error(ns_log_os, "stat(%s) failed: %s", name, - strerror(errno)); - return (1); - } - if (sb.st_mode & S_IWOTH) - ns_warning(ns_log_os, "directory %s is world-writable", name); - - return (1); -} - -static void -periodic_getnetconf(evContext ctx, void *uap, struct timespec due, - struct timespec inter) -{ - getnetconf(1); -} - -static void -set_interval_timer(int which_timer, int interval) { - evTimerID *tid = NULL; - evTimerFunc func = NULL; - - switch (which_timer) { - case CLEAN_TIMER: - tid = &clean_timer; - func = ns_cleancache; - break; - case INTERFACE_TIMER: - tid = &interface_timer; - func = periodic_getnetconf; - break; - case STATS_TIMER: - tid = &stats_timer; - func = ns_logstats; - break; - case HEARTBEAT_TIMER: - tid = &heartbeat_timer; - func = ns_heartbeat; - break; - default: - ns_panic(ns_log_config, 1, - "set_interval_timer: unknown timer %d", which_timer); - } - if ((active_timers & which_timer) != 0) { - if (interval > 0) { - if (evResetTimer(ev, *tid, func, NULL, - evAddTime(evNowTime(), - evConsTime(interval, 0)), - evConsTime(interval, 0)) < 0) - ns_error(ns_log_config, - "evResetTimer %d interval %d failed: %s", - which_timer, interval, - strerror(errno)); - } else { - if (evClearTimer(ev, *tid) < 0) - ns_error(ns_log_config, - "evClearTimer %d failed: %s", - which_timer, strerror(errno)); - else - active_timers &= ~which_timer; - } - } else if (interval > 0) { - if (evSetTimer(ev, func, NULL, - evAddTime(evNowTime(), - evConsTime(interval, 0)), - evConsTime(interval, 0), tid) < 0) - ns_error(ns_log_config, - "evSetTimer %d interval %d failed: %s", - which_timer, interval, strerror(errno)); - else - active_timers |= which_timer; - } -} - -/* - * Set all named global options based on the global options structure - * generated by the parser. - */ -void -set_options(options op, int is_default) { - INSIST(op != NULL); - - if (op->listen_list == NULL) { - ip_match_list iml; - ip_match_element ime; - struct in_addr address; - - op->listen_list = new_listen_info_list(); - - address.s_addr = htonl(INADDR_ANY); - iml = new_ip_match_list(); - ime = new_ip_match_pattern(address, 0); - add_to_ip_match_list(iml, ime); - add_listen_on(op, htons(NS_DEFAULTPORT), iml); - } - if (op->topology == NULL) { - ip_match_list iml; - ip_match_element ime; - - /* default topology is { localhost; localnets; } */ - iml = new_ip_match_list(); - ime = new_ip_match_localhost(); - add_to_ip_match_list(iml, ime); - ime = new_ip_match_localnets(); - add_to_ip_match_list(iml, ime); - op->topology = iml; - } - if (server_options != NULL) - free_options(server_options); - server_options = op; - - /* XXX should validate pid filename */ - INSIST(op->pid_filename != NULL); - - if (op->directory && !os_change_directory(op->directory)) - ns_panic(ns_log_config, 0, "can't change directory to %s: %s", - op->directory, strerror(errno)); - - /* XXX currently a value of 0 means "use default"; it would be - better if the options block had a "attributes updated" vector - (like the way X deals with GC updates) */ - - if (!op->transfers_in) - op->transfers_in = DEFAULT_XFERS_RUNNING; - else if (op->transfers_in > MAX_XFERS_RUNNING) { - ns_warning(ns_log_config, - "the maximum number of concurrent inbound transfers is %d", - MAX_XFERS_RUNNING); - op->transfers_in = MAX_XFERS_RUNNING; - } - - if (!op->transfers_per_ns) - op->transfers_per_ns = DEFAULT_XFERS_PER_NS; - - if (!op->max_transfer_time_in) - op->max_transfer_time_in = MAX_XFER_TIME; - - /* XXX currently transfers_out is not used */ - - if (!op->max_ncache_ttl) - op->max_ncache_ttl = DEFAULT_MAX_NCACHE_TTL; - else if (op->max_ncache_ttl > max_cache_ttl) - op->max_ncache_ttl = max_cache_ttl; - - if (op->lame_ttl > (3 * NTTL)) - op->lame_ttl = 3 * NTTL; - - /* - * Limits - */ - -#ifdef HAVE_GETRUSAGE - ns_rlimit(Datasize, op->data_size); - ns_rlimit(Stacksize, op->stack_size); - ns_rlimit(Coresize, op->core_size); - ns_rlimit(Files, op->files); -#else - ns_info(ns_log_config, "cannot set resource limits on this system"); -#endif - - /* - * Timers - */ - set_interval_timer(CLEAN_TIMER, server_options->clean_interval); - set_interval_timer(INTERFACE_TIMER, - server_options->interface_interval); - set_interval_timer(STATS_TIMER, server_options->stats_interval); - set_interval_timer(HEARTBEAT_TIMER, - server_options->heartbeat_interval); - - options_installed = 1; - default_options_installed = is_default; -} - -void -use_default_options() { - set_options(new_options(), 1); -} - -/* - * rrset order types - */ -static struct res_sym order_table [] = { - { unknown_order, " unknown " }, /* can't match */ - { fixed_order, "fixed" }, - { cyclic_order, "cyclic" }, - { random_order, "random" }, - { unknown_order, NULL } -}; - -/* - * Return the print name of the ordering value. - */ -const char * -p_order(int order) { - return (__sym_ntos(order_table, order, (int *)0)); -} - -/* - * Lookup the ordering by name and return the matching enum value. - */ -enum ordering -lookup_ordering(const char *name) { - int i; - - for (i = 0; order_table[i].name != NULL; i++) - if (strcasecmp(name,order_table[i].name) == 0) - return ((enum ordering)order_table[i].number); - return (unknown_order); -} - -/* - * rrset-order Lists - */ -rrset_order_list -new_rrset_order_list() { - rrset_order_list rol ; - - rol = (rrset_order_list)memget(sizeof (struct rrset_order_list)); - if (rol == NULL) - panic("memget failed in new_rrset_order_list", NULL); - rol->first = NULL; - rol->last = NULL; - - return (rol); -} - -void -free_rrset_order_list(rrset_order_list rol) { - rrset_order_element roe, next_element; - - for (roe = rol->first; roe != NULL; roe = next_element) { - next_element = roe->next; - freestr(roe->name); - memput(roe, sizeof (*roe)); - } - memput(rol, sizeof (*rol)); -} - - -void -add_to_rrset_order_list(rrset_order_list rol, rrset_order_element roe) { - INSIST(rol != NULL); - INSIST(roe != NULL); - - if (rol->last != NULL) - rol->last->next = roe; - roe->next = NULL; - rol->last = roe; - if (rol->first == NULL) - rol->first = roe; -} - -/* XXX this isn't being used yet, but it probably should be. Where? */ -void -dprint_rrset_order_list(int category, rrset_order_list rol, int indent, - char *allow, char *deny) { - rrset_order_element roe ; - char spaces[40+1]; - - INSIST(rol != NULL); - - if (indent > 40) - indent = 40; - if (indent) - memset(spaces, ' ', indent); - spaces[indent] = '\0'; - - for (roe = rol->first; roe != NULL; roe = roe->next) { - ns_debug(category, 7, "%sclass %s type %s name %s order %s", - spaces, p_class(roe->class), p_type(roe->type), - roe->name, p_order(roe->order)); - } -} - - -rrset_order_element -new_rrset_order_element(int class, int type, char *name, enum ordering order) -{ - rrset_order_element roe; - int i ; - - roe = (rrset_order_element)memget(sizeof (struct rrset_order_element)); - if (roe == NULL) - panic("memget failed in new_rrset_order_element", NULL); - roe->class = class ; - roe->type = type ; - roe->name = name; - roe->order = order; - - i = strlen(roe->name) - 1; - INSIST (i >= 0); - if (roe->name[i - 1] == '.') { - /* We compare from right to left so we don't need a dot on - the end. */ - roe->name[i - 1] = '\0' ; - } - - return roe ; -} - - -/* - * IP Matching Lists - */ - -ip_match_list -new_ip_match_list() { - ip_match_list iml; - - iml = (ip_match_list)memget(sizeof (struct ip_match_list)); - if (iml == NULL) - panic("memget failed in new_ip_match_list", NULL); - iml->first = NULL; - iml->last = NULL; - return (iml); -} - -void -free_ip_match_list(ip_match_list iml) { - ip_match_element ime, next_element; - - for (ime = iml->first; ime != NULL; ime = next_element) { - next_element = ime->next; - memput(ime, sizeof *ime); - } - memput(iml, sizeof *iml); -} - -ip_match_element -new_ip_match_pattern(struct in_addr address, u_int mask_bits) { - ip_match_element ime; - u_int32_t mask; - - ime = (ip_match_element)memget(sizeof (struct ip_match_element)); - if (ime == NULL) - panic("memget failed in new_ip_match_pattern", NULL); - ime->type = ip_match_pattern; - ime->flags = 0; - ime->u.direct.address = address; - if (mask_bits == 0) - /* can't shift >= the size of a type in bits, so - we deal with an empty mask here */ - mask = 0; - else { - /* set the 'mask_bits' most significant bits */ - mask = 0xffffffffU; - mask >>= (32 - mask_bits); - mask <<= (32 - mask_bits); - } - mask = ntohl(mask); - ime->u.direct.mask.s_addr = mask; - ime->next = NULL; - if (!ina_onnet(ime->u.direct.address, ime->u.direct.address, - ime->u.direct.mask)) { - memput(ime, sizeof *ime); - ime = NULL; - } - return (ime); -} - -ip_match_element -new_ip_match_mask(struct in_addr address, struct in_addr mask) { - ip_match_element ime; - - ime = (ip_match_element)memget(sizeof (struct ip_match_element)); - if (ime == NULL) - panic("memget failed in new_ip_match_pattern", NULL); - ime->type = ip_match_pattern; - ime->flags = 0; - ime->u.direct.address = address; - ime->u.direct.mask = mask; - ime->next = NULL; - if (!ina_onnet(ime->u.direct.address, ime->u.direct.address, - ime->u.direct.mask)) { - memput(ime, sizeof *ime); - ime = NULL; - } - return (ime); -} - -ip_match_element -new_ip_match_indirect(ip_match_list iml) { - ip_match_element ime; - - INSIST(iml != NULL); - - ime = (ip_match_element)memget(sizeof (struct ip_match_element)); - if (ime == NULL) - panic("memget failed in new_ip_match_indirect", NULL); - ime->type = ip_match_indirect; - ime->flags = 0; - ime->u.indirect.list = iml; - ime->next = NULL; - return (ime); -} - -ip_match_element -new_ip_match_key(DST_KEY *dst_key) { - ip_match_element ime; - - ime = (ip_match_element)memget(sizeof (struct ip_match_element)); - if (ime == NULL) - panic("memget failed in new_ip_match_key", NULL); - ime->type = ip_match_key; - ime->flags = 0; - ime->u.key.key = dst_key; - return (ime); -} - -ip_match_element -new_ip_match_localhost() { - ip_match_element ime; - - ime = (ip_match_element)memget(sizeof (struct ip_match_element)); - if (ime == NULL) - panic("memget failed in new_ip_match_localhost", NULL); - ime->type = ip_match_localhost; - ime->flags = 0; - ime->u.indirect.list = NULL; - ime->next = NULL; - return (ime); -} - -ip_match_element -new_ip_match_localnets() { - ip_match_element ime; - - ime = (ip_match_element)memget(sizeof (struct ip_match_element)); - if (ime == NULL) - panic("memget failed in new_ip_match_localnets", NULL); - ime->type = ip_match_localnets; - ime->flags = 0; - ime->u.indirect.list = NULL; - ime->next = NULL; - return (ime); -} - -void -ip_match_negate(ip_match_element ime) { - if (ime->flags & IP_MATCH_NEGATE) - ime->flags &= ~IP_MATCH_NEGATE; - else - ime->flags |= IP_MATCH_NEGATE; -} - -void -add_to_ip_match_list(ip_match_list iml, ip_match_element ime) { - INSIST(iml != NULL); - INSIST(ime != NULL); - - if (iml->last != NULL) - iml->last->next = ime; - ime->next = NULL; - iml->last = ime; - if (iml->first == NULL) - iml->first = ime; -} - -void -dprint_ip_match_list(int category, ip_match_list iml, int indent, - char *allow, char *deny) { - ip_match_element ime; - char spaces[40+1]; - char addr_text[sizeof "255.255.255.255"]; - char mask_text[sizeof "255.255.255.255"]; - - INSIST(iml != NULL); - - if (indent > 40) - indent = 40; - if (indent) - memset(spaces, ' ', indent); - spaces[indent] = '\0'; - - for (ime = iml->first; ime != NULL; ime = ime->next) { - switch (ime->type) { - case ip_match_pattern: - memset(addr_text, 0, sizeof addr_text); - strncpy(addr_text, inet_ntoa(ime->u.direct.address), - ((sizeof addr_text) - 1)); - memset(mask_text, 0, sizeof mask_text); - strncpy(mask_text, inet_ntoa(ime->u.direct.mask), - ((sizeof mask_text) - 1)); - ns_debug(category, 7, "%s%saddr: %s, mask: %s", - spaces, - (ime->flags & IP_MATCH_NEGATE) ? deny : allow, - addr_text, mask_text); - break; - case ip_match_localhost: - ns_debug(category, 7, "%s%slocalhost", spaces, - (ime->flags & IP_MATCH_NEGATE) ? - deny : allow); - break; - case ip_match_localnets: - ns_debug(category, 7, "%s%slocalnets", spaces, - (ime->flags & IP_MATCH_NEGATE) ? - deny : allow); - break; - case ip_match_indirect: - ns_debug(category, 7, "%s%sindirect list %p", spaces, - (ime->flags & IP_MATCH_NEGATE) ? deny : allow, - ime->u.indirect.list); - if (ime->u.indirect.list != NULL) - dprint_ip_match_list(category, - ime->u.indirect.list, - indent+2, allow, deny); - break; - case ip_match_key: - ns_debug(category, 7, "%s%skey %s", spaces, - (ime->flags & IP_MATCH_NEGATE) ? deny : allow, - ime->u.key.key->dk_key_name); - break; - default: - panic("unexpected ime type in dprint_ip_match_list()", - NULL); - } - } -} - -int -ip_match_addr_or_key(ip_match_list iml, struct in_addr address, - DST_KEY *key) -{ - ip_match_element ime; - int ret; - int indirect; - - INSIST(iml != NULL); - for (ime = iml->first; ime != NULL; ime = ime->next) { - switch (ime->type) { - case ip_match_pattern: - indirect = 0; - break; - case ip_match_indirect: - indirect = 1; - break; - case ip_match_localhost: - ime->u.indirect.list = local_addresses; - indirect = 1; - break; - case ip_match_localnets: - ime->u.indirect.list = local_networks; - indirect = 1; - break; - case ip_match_key: - if (key == NULL) { - indirect = 0; - break; - } - else { - if (ns_samename(ime->u.key.key->dk_key_name, - key->dk_key_name) == 1) - return (1); - else - continue; - } - default: - panic("unexpected ime type in ip_match_addr_or_key()", - NULL); - } - if (indirect) { - ret = ip_match_addr_or_key(ime->u.indirect.list, - address, key); - if (ret > 0) { - if (ime->flags & IP_MATCH_NEGATE) - ret = (ret) ? 0 : 1; - return (ret); - } - } else { - if (ina_onnet(address, ime->u.direct.address, - ime->u.direct.mask)) { - if (ime->flags & IP_MATCH_NEGATE) - return (0); - else - return (1); - } - } - } - return (-1); -} - -int -ip_match_address(ip_match_list iml, struct in_addr address) { - return ip_match_addr_or_key(iml, address, NULL); -} - -int -ip_addr_or_key_allowed(ip_match_list iml, struct in_addr address, - DST_KEY *key) -{ - int ret; - - if (iml == NULL) - return (0); - ret = ip_match_addr_or_key(iml, address, key); - if (ret < 0) - ret = 0; - return (ret); -} - -int -ip_address_allowed(ip_match_list iml, struct in_addr address) { - return(ip_addr_or_key_allowed(iml, address, NULL)); -} - -int -ip_match_network(ip_match_list iml, struct in_addr address, - struct in_addr mask) { - ip_match_element ime; - int ret; - int indirect; - - INSIST(iml != NULL); - for (ime = iml->first; ime != NULL; ime = ime->next) { - switch (ime->type) { - case ip_match_pattern: - indirect = 0; - break; - case ip_match_indirect: - indirect = 1; - break; - case ip_match_localhost: - ime->u.indirect.list = local_addresses; - indirect = 1; - break; - case ip_match_localnets: - ime->u.indirect.list = local_networks; - indirect = 1; - break; - case ip_match_key: - indirect = 0; - break; - default: - indirect = 0; /* Make gcc happy. */ - panic("unexpected ime type in ip_match_network()", - NULL); - } - if (indirect) { - ret = ip_match_network(ime->u.indirect.list, - address, mask); - if (ret >= 0) { - if (ime->flags & IP_MATCH_NEGATE) - ret = (ret) ? 0 : 1; - return (ret); - } - } else { - if (address.s_addr == ime->u.direct.address.s_addr && - mask.s_addr == ime->u.direct.mask.s_addr) { - if (ime->flags & IP_MATCH_NEGATE) - return (0); - else - return (1); - } - } - } - return (-1); -} - -int -distance_of_address(ip_match_list iml, struct in_addr address) { - ip_match_element ime; - int ret; - int indirect; - int distance; - - INSIST(iml != NULL); - for (distance = 1, ime = iml->first; - ime != NULL; ime = ime->next, distance++) { - switch (ime->type) { - case ip_match_pattern: - indirect = 0; - break; - case ip_match_indirect: - indirect = 1; - break; - case ip_match_localhost: - ime->u.indirect.list = local_addresses; - indirect = 1; - break; - case ip_match_localnets: - ime->u.indirect.list = local_networks; - indirect = 1; - break; - case ip_match_key: - indirect = 0; - return (-1); - default: - indirect = 0; /* Make gcc happy. */ - panic("unexpected ime type in distance_of_address()", - NULL); - } - if (indirect) { - ret = ip_match_address(ime->u.indirect.list, address); - if (ret >= 0) { - if (ime->flags & IP_MATCH_NEGATE) - ret = (ret) ? 0 : 1; - if (distance > MAX_TOPOLOGY_DISTANCE) - distance = MAX_TOPOLOGY_DISTANCE; - if (ret) - return (distance); - else - return (MAX_TOPOLOGY_DISTANCE); - } - } else { - if (ina_onnet(address, ime->u.direct.address, - ime->u.direct.mask)) { - if (distance > MAX_TOPOLOGY_DISTANCE) - distance = MAX_TOPOLOGY_DISTANCE; - if (ime->flags & IP_MATCH_NEGATE) - return (MAX_TOPOLOGY_DISTANCE); - else - return (distance); - } - } - } - return (UNKNOWN_TOPOLOGY_DISTANCE); -} - -int -ip_match_is_none(ip_match_list iml) { - ip_match_element ime; - - if ((iml == NULL) || (iml->first == NULL)) - return (1); - ime = iml->first; - if (ime->type == ip_match_indirect) { - if (ime->flags & IP_MATCH_NEGATE) - return (0); - iml = ime->u.indirect.list; - if ((iml == NULL) || (iml->first == NULL)) - return (0); - ime = iml->first; - } - if (ime->type == ip_match_pattern) { - if ((ime->flags & IP_MATCH_NEGATE) && - ime->u.direct.address.s_addr == 0 && - ime->u.direct.mask.s_addr == 0) - return (1); - } - return (0); -} - -/* - * find_forwarder finds the fwddata structure for an address, - * allocating one if we can't find one already existing. - */ - -static struct fwddata * -find_forwarder(struct in_addr address) -{ - struct fwddata *fdp; - struct databuf *ns, *nsdata; - register int i; - - for (i=0;i<fwddata_count; i++) { - fdp=fwddata[i]; - if (memcmp(&fdp->fwdaddr.sin_addr,&address,sizeof(address))==0) { - fdp->ref_count++; - return fdp; - } - } - - fdp = (struct fwddata *)memget(sizeof(struct fwddata)); - if (!fdp) - panic("memget failed in find_forwarder", NULL); - fdp->fwdaddr.sin_family = AF_INET; - fdp->fwdaddr.sin_addr = address; - fdp->fwdaddr.sin_port = ns_port; - ns = fdp->ns = (struct databuf *)memget(sizeof(*ns)); - if (!ns) - panic("memget failed in find_forwarder", NULL); - memset(ns,0,sizeof(*ns)); - nsdata = fdp->nsdata = (struct databuf *)memget(sizeof(*nsdata)); - if (!nsdata) - panic("memget failed in find_forwarder", NULL); - memset(nsdata,0,sizeof(*nsdata)); - ns->d_type = T_NS; - ns->d_class = C_IN; - ns->d_rcnt=1; - nsdata->d_type = T_A; - nsdata->d_class = C_IN; - nsdata->d_nstime = 1 + (int)(25.0*rand()/(RAND_MAX + 1.0)); - nsdata->d_rcnt=1; - fdp->ref_count=1; - - i=0; - if (fwddata == NULL) { - fwddata = memget(sizeof *fwddata); - if (fwddata == NULL) - i = 1; - } else { - register size_t size; - register struct fwddata **an_tmp; - size = fwddata_count * sizeof *fwddata; - an_tmp = memget(size + sizeof *fwddata); - if (an_tmp == NULL) { - i = 1; - } else { - memcpy(an_tmp, fwddata, size); - memput(fwddata, size); - fwddata = an_tmp; - } - } - - if (i == 0) { - fwddata[fwddata_count] = fdp; - fwddata_count++; - } else { - ns_warning(ns_log_config, - "forwarder add failed (memget) [%s]", - inet_ntoa(address)); - } - - return fdp; -} -/* - * Forwarder glue - * - * XXX This will go away when the rest of bind understands - * forward zones. - */ - -static void -add_forwarder(struct fwdinfo **fipp, struct in_addr address) { - struct fwdinfo *fip = *fipp, *ftp = NULL; - struct fwddata *fdp; - -#ifdef FWD_LOOP - if (aIsUs(address)) { - ns_error(ns_log_config, "forwarder '%s' ignored, my address", - inet_ntoa(address)); - return; - } -#endif /* FWD_LOOP */ - - /* On multiple forwarder lines, move to end of the list. */ - while (fip != NULL && fip->next != NULL) - fip = fip->next; - - fdp = find_forwarder(address); - ftp = (struct fwdinfo *)memget(sizeof(struct fwdinfo)); - if (!ftp) - panic("memget failed in add_forwarder", NULL); - ftp->fwddata = fdp; - ftp->next = NULL; - if (fip == NULL) - *fipp = ftp; /* First time only */ - else - fip->next = ftp; -} - -void -free_also_notify(options op) { -#ifdef BIND_NOTIFY - memput(op->also_notify, op->notify_count * sizeof *op->also_notify); - op->also_notify = NULL; - op->notify_count = 0; -#endif -} - -int -add_global_also_notify(options op, struct in_addr address) { -#ifdef BIND_NOTIFY - int i; - - INSIST(op != NULL); - - ns_debug(ns_log_config, 2, "adding global notify %s", - inet_ntoa(address)); - - /* Check for duplicates. */ - - for (i = 0; i < op->notify_count; i++) { - if (memcmp(op->also_notify + i, - &address, sizeof address) == 0) { - ns_warning(ns_log_config, - "duplicate global also-notify address ignored [%s]", - inet_ntoa(address)); - return (1); - } - } - i = 0; - - if (op->also_notify == NULL) { - op->also_notify = memget(sizeof *op->also_notify); - if (op->also_notify == NULL) - i = 1; - } else { - register size_t size; - register struct in_addr *an_tmp; - size = op->notify_count * sizeof *op->also_notify; - an_tmp = memget(size + sizeof *op->also_notify); - if (an_tmp == NULL) { - i = 1; - } else { - memcpy(an_tmp, op->also_notify, size); - memput(op->also_notify, size); - op->also_notify = an_tmp; - } - } - if (i == 0) { - op->also_notify[op->notify_count] = address; - op->notify_count++; - } else { - ns_warning(ns_log_config, - "global also-notify add failed (memget) [%s]", - inet_ntoa(address)); - } -#endif - return (1); -} - -void -add_global_forwarder(options op, struct in_addr address) { - - INSIST(op != NULL); - - ns_debug(ns_log_config, 2, "adding default forwarder %s", - inet_ntoa(address)); - - add_forwarder(&op->fwdtab, address); -} - -void -set_zone_forward(zone_config zh) { - struct zoneinfo *zp; - zp = zh.opaque; - - zp->z_flags |= Z_FORWARD_SET; - set_zone_boolean_option(zh, OPTION_FORWARD_ONLY, 0); -} - -void -add_zone_forwarder(zone_config zh, struct in_addr address) { - struct zoneinfo *zp; - char *zname; - - zp = zh.opaque; - INSIST(zp != NULL); - - zname = (zp->z_origin[0] == '\0') ? "." : zp->z_origin; - ns_debug(ns_log_config, 2, "adding forwarder %s for zone zone '%s'", - inet_ntoa(address), zname); - - zp->z_flags |= Z_FORWARD_SET; - - add_forwarder(&zp->z_fwdtab, address); -} - -void -free_forwarders(struct fwdinfo *fwdtab) { - struct fwdinfo *ftp, *fnext; - - for (ftp = fwdtab; ftp != NULL; ftp = fnext) { - fnext = ftp->next; - if (!--ftp->fwddata->ref_count) { - memput(ftp->fwddata->ns, sizeof *ftp->fwddata->ns); - memput(ftp->fwddata->nsdata, - sizeof *ftp->fwddata->nsdata); - memput(ftp->fwddata,sizeof *ftp->fwddata); - } - memput(ftp, sizeof *ftp); - } - fwdtab = NULL; -} - -/* - * Servers - */ - -static server_info -new_server(struct in_addr address) { - server_info si; - - si = (server_info)memget(sizeof (struct server_info)); - if (si == NULL) - panic("memget failed in new_server()", NULL); - si->address = address; - si->flags = 0U; - si->transfers = 0; - si->transfer_format = axfr_use_default; - si->key_list = NULL; - si->next = NULL; - if (server_options->flags & OPTION_MAINTAIN_IXFR_BASE) - si->flags |= SERVER_INFO_SUPPORT_IXFR; - else - si->flags &= ~SERVER_INFO_SUPPORT_IXFR; - return (si); -} - -static void -free_server(server_info si) { - /* Don't free key; it'll be done when the auth table is freed. */ - memput(si, sizeof *si); -} - -server_info -find_server(struct in_addr address) { - server_info si; - - for (si = nameserver_info; si != NULL; si = si->next) - if (si->address.s_addr == address.s_addr) - break; - return (si); -} - -static void -add_server(server_info si) { - ip_match_element ime; - - si->next = nameserver_info; - nameserver_info = si; - - /* - * To ease transition, we'll add bogus nameservers to an - * ip matching list. This will probably be redone when the - * merging of nameserver data structures occurs. - */ - if (si->flags & SERVER_INFO_BOGUS) { - ime = new_ip_match_pattern(si->address, 32); - INSIST(ime != NULL); - add_to_ip_match_list(bogus_nameservers, ime); - } - ns_debug(ns_log_config, 3, "server %s: flags %08x transfers %d", - inet_ntoa(si->address), si->flags, si->transfers); - if (si->key_list != NULL) - dprint_key_info_list(si->key_list); -} - -static void -free_nameserver_info() { - server_info si_next, si; - - for (si = nameserver_info; si != NULL; si = si_next) { - si_next = si->next; - free_server(si); - } - nameserver_info = NULL; - if (bogus_nameservers != NULL) { - free_ip_match_list(bogus_nameservers); - bogus_nameservers = NULL; - } -} - -static void -free_secretkey_info() { - if (secretkey_info != NULL) { - free_key_info_list(secretkey_info); - secretkey_info = NULL; - } -} - -server_config -begin_server(struct in_addr address) { - server_config sc; - - sc.opaque = new_server(address); - return (sc); -} - -void -end_server(server_config sc, int should_install) { - server_info si; - - si = sc.opaque; - - INSIST(si != NULL); - - if (should_install) - add_server(si); - else - free_server(si); - sc.opaque = NULL; -} - -void -set_server_option(server_config sc, int bool_opt, int value) { - server_info si; - - si = sc.opaque; - - INSIST(si != NULL); - - switch (bool_opt) { - case SERVER_INFO_BOGUS: - case SERVER_INFO_SUPPORT_IXFR: - if (value) - si->flags |= bool_opt; - else - si->flags &= ~bool_opt; - break; - default: - panic("unexpected option in set_server_option", NULL); - } -} - -void -set_server_transfers(server_config sc, int transfers) { - server_info si; - - si = sc.opaque; - - INSIST(si != NULL); - - if (transfers < 0) - transfers = 0; - si->transfers = transfers; -} - -void -set_server_transfer_format(server_config sc, - enum axfr_format transfer_format) { - server_info si; - - si = sc.opaque; - - INSIST(si != NULL); - - si->transfer_format = transfer_format; -} - -void -add_server_key_info(server_config sc, DST_KEY *dst_key) { - server_info si; - - si = sc.opaque; - - INSIST(si != NULL); - - if (si->key_list == NULL) - si->key_list = new_key_info_list(); - add_to_key_info_list(si->key_list, dst_key); -} - -/* - * Keys - */ - -DST_KEY * -new_key_info(char *name, char *algorithm, char *secret) { - DST_KEY *dst_key; - int alg, blen; - u_char buffer[1024]; - - INSIST(name != NULL); - INSIST(algorithm != NULL); - INSIST(secret != NULL); - alg = tsig_alg_value(algorithm); - if (alg == -1) { - ns_warning(ns_log_config, "Unsupported TSIG algorithm %s", - algorithm); - return (NULL); - } - - blen = b64_pton(secret, buffer, sizeof(buffer)); - if (blen < 0) { - ns_warning(ns_log_config, "Invalid TSIG secret \"%s\"", secret); - return (NULL); - } - dst_key = dst_buffer_to_key(name, alg, - NS_KEY_TYPE_AUTH_ONLY|NS_KEY_NAME_ENTITY, - NS_KEY_PROT_ANY, buffer, blen); - if (dst_key == NULL) - ns_warning(ns_log_config, - "dst_buffer_to_key failed in new_key_info"); - return (dst_key); -} - -void -free_key_info(DST_KEY *dst_key) { - INSIST(dst_key != NULL); - dst_free_key(dst_key); -} - -DST_KEY * -find_key(char *name, char *algorithm) { - key_list_element ke; - - if (secretkey_info == NULL) - return (NULL); - - for (ke = secretkey_info->first; ke != NULL; ke = ke->next) { - DST_KEY *dst_key = ke->key; - - if (ns_samename(name, dst_key->dk_key_name) != 1) - continue; - if (algorithm == NULL || - dst_key->dk_alg == tsig_alg_value(algorithm)) - break; - } - if (ke == NULL) - return (NULL); - return (ke->key); -} - -void -dprint_key_info(DST_KEY *dst_key) { - INSIST(dst_key != NULL); - ns_debug(ns_log_config, 7, "key %s", dst_key->dk_key_name); - ns_debug(ns_log_config, 7, " algorithm %d", dst_key->dk_alg); -} - -key_info_list -new_key_info_list() { - key_info_list kil; - - kil = (key_info_list)memget(sizeof (struct key_info_list)); - if (kil == NULL) - panic("memget failed in new_key_info_list()", NULL); - kil->first = NULL; - kil->last = NULL; - return (kil); -} - -void -free_key_info_list(key_info_list kil) { - key_list_element kle, kle_next; - - INSIST(kil != NULL); - for (kle = kil->first; kle != NULL; kle = kle_next) { - kle_next = kle->next; - /* note we do NOT free kle->info */ - memput(kle, sizeof *kle); - } - memput(kil, sizeof *kil); -} - -void -add_to_key_info_list(key_info_list kil, DST_KEY *dst_key) { - key_list_element kle; - - INSIST(kil != NULL); - INSIST(dst_key != NULL); - - kle = (key_list_element)memget(sizeof (struct key_list_element)); - if (kle == NULL) - panic("memget failed in add_to_key_info_list()", NULL); - kle->key = dst_key; - if (kil->last != NULL) - kil->last->next = kle; - kle->next = NULL; - kil->last = kle; - if (kil->first == NULL) - kil->first = kle; -} - -void -dprint_key_info_list(key_info_list kil) { - key_list_element kle; - - INSIST(kil != NULL); - - for (kle = kil->first; kle != NULL; kle = kle->next) - dprint_key_info(kle->key); -} - -/* - * Logging. - */ - -log_config -begin_logging() { - log_config log_cfg; - log_context lc; - - log_cfg = (log_config)memget(sizeof (struct log_config)); - if (log_cfg == NULL) - ns_panic(ns_log_config, 0, - "memget failed creating log_config"); - if (log_new_context(ns_log_max_category, logging_categories, &lc) < 0) - ns_panic(ns_log_config, 0, - "log_new_context() failed: %s", strerror(errno)); - log_cfg->log_ctx = lc; - log_cfg->eventlib_channel = NULL; - log_cfg->packet_channel = NULL; - log_cfg->default_debug_active = 0; - return (log_cfg); -} - -void -add_log_channel(log_config log_cfg, int category, log_channel chan) { - log_channel_type type; - - INSIST(log_cfg != NULL); - - type = log_get_channel_type(chan); - if (category == ns_log_eventlib) { - if (type != log_file && type != log_null) { - ns_error(ns_log_config, - "must specify a file or null channel for the eventlib category"); - return; - } - if (log_cfg->eventlib_channel != NULL) { - ns_error(ns_log_config, - "only one channel allowed for the eventlib category"); - return; - } - log_cfg->eventlib_channel = chan; - } - if (category == ns_log_packet) { - if (type != log_file && type != log_null) { - ns_error(ns_log_config, - "must specify a file or null channel for the packet category"); - return; - } - if (log_cfg->packet_channel != NULL) { - ns_error(ns_log_config, - "only one channel allowed for the packet category"); - return; - } - log_cfg->packet_channel = chan; - } - - if (log_add_channel(log_cfg->log_ctx, category, chan) < 0) { - ns_error(ns_log_config, "log_add_channel() failed"); - return; - } - - if (chan == debug_channel) - log_cfg->default_debug_active = 1; -} - -void -open_special_channels() { - int using_null = 0; - - if (log_open_stream(eventlib_channel) == NULL) { - eventlib_channel = null_channel; - using_null = 1; - } - if (log_open_stream(packet_channel) == NULL) { - packet_channel = null_channel; - using_null = 1; - } - - if (using_null && - log_open_stream(null_channel) == NULL) - ns_panic(ns_log_config, 1, "couldn't open null channel"); -} - -void -set_logging(log_config log_cfg, int is_default) { - log_context lc; - - INSIST(log_cfg != NULL); - lc = log_cfg->log_ctx; - - /* - * Add the default category if it's not in the context already. - */ - if (!log_category_is_active(lc, ns_log_default)) { - add_log_channel(log_cfg, ns_log_default, debug_channel); - add_log_channel(log_cfg, ns_log_default, syslog_channel); - } - - /* - * Add the panic category if it's not in the context already. - */ - if (!log_category_is_active(lc, ns_log_panic)) { - add_log_channel(log_cfg, ns_log_panic, stderr_channel); - add_log_channel(log_cfg, ns_log_panic, syslog_channel); - } - - /* - * Add the eventlib category if it's not in the context already. - */ - if (!log_category_is_active(lc, ns_log_eventlib)) - add_log_channel(log_cfg, ns_log_eventlib, debug_channel); - - /* - * Add the packet category if it's not in the context already. - */ - if (!log_category_is_active(lc, ns_log_packet)) - add_log_channel(log_cfg, ns_log_packet, debug_channel); - -#ifdef DEBUG - /* - * Preserve debugging state. - */ - log_option(lc, LOG_OPTION_DEBUG, debug); - log_option(lc, LOG_OPTION_LEVEL, debug); -#endif - - /* - * Special case for query-log, so we can co-exist with the command - * line option and SIGWINCH. - */ - if (log_category_is_active(lc, ns_log_queries)) - qrylog = 1; - - /* - * Cleanup the old context. - */ - if (need_logging_free) - log_free_context(log_ctx); - - /* - * The default file channels will never have their reference counts - * drop to zero, and so they will not be closed by the logging system - * when log_free_context() is called. We don't want to keep files - * open unnecessarily, and we want them to behave like user-created - * channels, so we close them here. - */ - if (log_get_stream(debug_channel) != stderr) - (void)log_close_stream(debug_channel); - (void)log_close_stream(null_channel); - - /* - * Install the new context. - */ - log_ctx = lc; - eventlib_channel = log_cfg->eventlib_channel; - packet_channel = log_cfg->packet_channel; - -#ifdef DEBUG - if (debug) { - open_special_channels(); - evSetDebug(ev, debug, log_get_stream(eventlib_channel)); - } -#endif - - log_ctx_valid = 1; - need_logging_free = 1; - logging_installed = 1; - default_logging_installed = is_default; -} - -void -end_logging(log_config log_cfg, int should_install) { - if (should_install) - set_logging(log_cfg, 0); - else - log_free_context(log_cfg->log_ctx); - memput(log_cfg, sizeof (struct log_config)); -} - -void -use_default_logging() { - log_config log_cfg; - - log_cfg = begin_logging(); - set_logging(log_cfg, 1); - memput(log_cfg, sizeof (struct log_config)); -} - -static void -init_default_log_channels() { - u_int flags; - char *name; - FILE *stream; - - syslog_channel = log_new_syslog_channel(0, log_info, LOG_DAEMON); - if (syslog_channel == NULL || log_inc_references(syslog_channel) < 0) - ns_panic(ns_log_config, 0, "couldn't create syslog_channel"); - - flags = LOG_USE_CONTEXT_LEVEL|LOG_REQUIRE_DEBUG; - if (foreground) { - name = NULL; - stream = stderr; - } else { - name = _PATH_DEBUG; - stream = NULL; - } - debug_channel = log_new_file_channel(flags, log_info, name, stream, - 0, ULONG_MAX); - if (debug_channel == NULL || log_inc_references(debug_channel) < 0) - ns_panic(ns_log_config, 0, "couldn't create debug_channel"); - log_set_file_owner(debug_channel, user_id, group_id); - - stderr_channel = log_new_file_channel(0, log_info, NULL, stderr, - 0, ULONG_MAX); - if (stderr_channel == NULL || log_inc_references(stderr_channel) < 0) - ns_panic(ns_log_config, 0, "couldn't create stderr_channel"); - log_set_file_owner(stderr_channel, user_id, group_id); - - null_channel = log_new_file_channel(LOG_CHANNEL_OFF, log_info, - _PATH_DEVNULL, NULL, 0, ULONG_MAX); - if (null_channel == NULL || log_inc_references(null_channel) < 0) - ns_panic(ns_log_config, 0, "couldn't create null_channel"); - log_set_file_owner(null_channel, user_id, group_id); -} - -static void -shutdown_default_log_channels() { - log_free_channel(syslog_channel); - log_free_channel(debug_channel); - log_free_channel(stderr_channel); - log_free_channel(null_channel); -} - -void -init_logging() { - int size; - const struct ns_sym *s; - char category_name[256]; - - size = ns_log_max_category * (sizeof (char *)); - - logging_categories = (char **)memget(size); - if (logging_categories == NULL) - ns_panic(ns_log_config, 0, "memget failed in init_logging"); - memset(logging_categories, 0, size); - for (s = category_constants; s != NULL && s->name != NULL; s++) { - sprintf(category_name, "%s: ", s->name); - logging_categories[s->number] = savestr(category_name, 1); - } - - init_default_log_channels(); - use_default_logging(); -} - -void -shutdown_logging() { - int size; - const struct ns_sym *s; - - evSetDebug(ev, 0, NULL); - shutdown_default_log_channels(); - log_free_context(log_ctx); - - for (s = category_constants; s != NULL && s->name != NULL; s++) - freestr(logging_categories[s->number]); - size = ns_log_max_category * (sizeof (char *)); - memput(logging_categories, size); - logging_categories = NULL; -} - -/* - * Main Loader - */ - -void -init_configuration() { - /* - * Remember initial limits for use if "default" is specified in - * a config file. - */ -#ifdef HAVE_GETRUSAGE - get_initial_limits(); -#endif - zone_symbol_table = new_symbol_table(ZONE_SYM_TABLE_SIZE, NULL); - use_default_options(); - parser_initialize(); - ns_ctl_initialize(); - config_initialized = 1; -} - -void -shutdown_configuration() { - REQUIRE(config_initialized); - - ns_ctl_shutdown(); - if (server_options != NULL) { - free_options(server_options); - server_options = NULL; - } - if (current_pid_filename != NULL) - freestr(current_pid_filename); - free_nameserver_info(); - free_secretkey_info(); - free_symbol_table(zone_symbol_table); - parser_shutdown(); - config_initialized = 0; -} - -void -load_configuration(const char *filename) { - REQUIRE(config_initialized); - - ns_debug(ns_log_config, 3, "load configuration %s", filename); - - loading = 1; - - /* - * Clean up any previous configuration and initialize - * global data structures we'll be updating. - */ - free_nameserver_info(); - free_secretkey_info(); - bogus_nameservers = new_ip_match_list(); - - options_installed = 0; - logging_installed = 0; - - parse_configuration(filename); - - /* - * If the user didn't specify logging or options, but they previously - * had specified one or both of them, then we need to - * re-establish the default environment. We have to be careful - * about when we install default options because the parser - * must respect limits (e.g. data-size, number of open files) - * specified in the options file. In the ordinary case where the - * options section isn't changing on a zone reload, it would be bad - * to lower these limits temporarily, because we might not survive - * to the point where they get raised back again. The logging case - * has similar motivation -- we don't want to override the existing - * logging scheme (perhaps causing log messages to go somewhere - * unexpected) when the user hasn't expressed a desire for a new - * scheme. - */ - if (!logging_installed) - use_default_logging(); - if (!options_installed && !default_options_installed) { - use_default_options(); - ns_warning(ns_log_config, "re-establishing default options"); - } - - update_pid_file(); - - /* Init or reinit the interface/port list and associated sockets. */ - getnetconf(0); - opensocket_f(); - - initial_configuration = 0; - loading = 0; - /* release queued notifies */ - notify_afterload(); -} diff --git a/contrib/bind/bin/named/ns_ctl.c b/contrib/bind/bin/named/ns_ctl.c deleted file mode 100644 index 66cb8625b4fb3..0000000000000 --- a/contrib/bind/bin/named/ns_ctl.c +++ /dev/null @@ -1,937 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_ctl.c,v 8.34 2000/04/21 06:54:05 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1997-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* Extern. */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> -#include <unistd.h> -#include <fcntl.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" - -/* Defs. */ - -#define CONTROL_FOUND 0x0001 /* for mark and sweep. */ -#define MAX_STR_LEN 500 - -struct control { - LINK(struct control) link; - enum { t_dead, t_inet, t_unix } type; - struct ctl_sctx *sctx; - u_int flags; - union { - struct { - struct sockaddr_in in; - ip_match_list allow; - } v_inet; -#ifndef NO_SOCKADDR_UN - struct { - struct sockaddr_un un; - mode_t mode; - uid_t owner; - gid_t group; - } v_unix; -#endif - } var; -}; - -/* Forward. */ - -static struct ctl_sctx *mksrvr(control, const struct sockaddr *, size_t); -static control new_control(void); -static void free_control(controls *, control); -static void free_controls(controls *); -static int match_control(control, control); -static control find_control(controls, control); -static void propagate_changes(const control, control); -static void install(control); -static void install_inet(control); -static void install_unix(control); -static void logger(enum ctl_severity, const char *fmt, ...); -static void verb_connect(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_getpid(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void getpid_closure(struct ctl_sctx *, struct ctl_sess *, - void *); -static void verb_status(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void status_closure(struct ctl_sctx *, struct ctl_sess *, - void *); -static void verb_stop(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_exec(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_reload(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_reconfig(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_dumpdb(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_stats(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_trace(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void trace_closure(struct ctl_sctx *, struct ctl_sess *, - void *); -static void verb_notrace(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_querylog(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_help(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); -static void verb_quit(struct ctl_sctx *, struct ctl_sess *, - const struct ctl_verb *, - const char *, u_int, void *, void *); - -/* Private data. */ - -static controls server_controls; - -static struct ctl_verb verbs[] = { - { "", verb_connect, ""}, - { "getpid", verb_getpid, "getpid"}, - { "status", verb_status, "status"}, - { "stop", verb_stop, "stop"}, - { "exec", verb_exec, "exec"}, - { "reload", verb_reload, "reload [zone] ..."}, - { "reconfig", verb_reconfig, "reconfig [-noexpired] (just sees new/gone zones)"}, - { "dumpdb", verb_dumpdb, "dumpdb"}, - { "stats", verb_stats, "stats"}, - { "trace", verb_trace, "trace [level]"}, - { "notrace", verb_notrace, "notrace"}, - { "querylog", verb_querylog, "querylog"}, - { "qrylog", verb_querylog, "qrylog"}, - { "help", verb_help, "help"}, - { "quit", verb_quit, "quit"}, - { NULL, NULL, NULL} -}; - -/* Public functions. */ - -void -ns_ctl_initialize(void) { - INIT_LIST(server_controls); -} - -void -ns_ctl_shutdown(void) { - if (!EMPTY(server_controls)) - free_controls(&server_controls); -} - -void -ns_ctl_defaults(controls *list) { -#ifdef NO_SOCKADDR_UN - struct in_addr saddr; - ip_match_list iml; - ip_match_element ime; - - /* - * If the operating system does not support local domain sockets, - * connect with ndc on 127.0.0.1, port 101, and only allow - * connections from 127.0.0.1. - */ - saddr.s_addr = htonl (INADDR_LOOPBACK); - iml = new_ip_match_list(); - ime = new_ip_match_pattern(saddr, 32); - add_to_ip_match_list(iml, ime); - - ns_ctl_add(list, ns_ctl_new_inet(saddr, htons (101), iml)); -#else -#ifdef NEED_SECURE_DIRECTORY - ns_ctl_add(list, ns_ctl_new_unix(_PATH_NDCSOCK, 0700, 0, 0)); -#else - ns_ctl_add(list, ns_ctl_new_unix(_PATH_NDCSOCK, 0600, 0, 0)); -#endif -#endif /*NO_SOCKADDR_UN*/ -} - -void -ns_ctl_add(controls *list, control new) { - if (!find_control(*list, new)) - APPEND(*list, new, link); -} - -control -ns_ctl_new_inet(struct in_addr saddr, u_int sport, ip_match_list allow) { - control new = new_control(); - - INIT_LINK(new, link); - new->type = t_inet; - memset(&new->var.v_inet.in, 0, sizeof new->var.v_inet.in); - new->var.v_inet.in.sin_family = AF_INET; - new->var.v_inet.in.sin_addr = saddr; - new->var.v_inet.in.sin_port = sport; - new->var.v_inet.allow = allow; - return (new); -} - -#ifndef NO_SOCKADDR_UN -control -ns_ctl_new_unix(char *path, mode_t mode, uid_t owner, gid_t group) { - control new = new_control(); - - INIT_LINK(new, link); - new->type = t_unix; - memset(&new->var.v_unix.un, 0, sizeof new->var.v_unix.un); - new->var.v_unix.un.sun_family = AF_UNIX; - strncpy(new->var.v_unix.un.sun_path, path, - sizeof new->var.v_unix.un.sun_path - 1); - new->var.v_unix.mode = mode; - new->var.v_unix.owner = owner; - new->var.v_unix.group = group; - return (new); -} -#endif - -void -ns_ctl_install(controls *new) { - control ctl, old, next; - - /* Find all the controls which aren't new or deleted. */ - for (ctl = HEAD(server_controls); ctl != NULL; ctl = NEXT(ctl, link)) - ctl->flags &= ~CONTROL_FOUND; - for (ctl = HEAD(*new); ctl != NULL; ctl = next) { - next = NEXT(ctl, link); - old = find_control(server_controls, ctl); - if (old != NULL) { - old->flags |= CONTROL_FOUND; - propagate_changes(ctl, old); - if (old->sctx == NULL) - free_control(&server_controls, old); - free_control(new, ctl); - } - } - - /* Destroy any old controls which weren't found. */ - for (ctl = HEAD(server_controls); ctl != NULL; ctl = next) { - next = NEXT(ctl, link); - if ((ctl->flags & CONTROL_FOUND) == 0) - free_control(&server_controls, ctl); - } - - /* Add any new controls which were found. */ - for (ctl = HEAD(*new); ctl != NULL; ctl = next) { - next = NEXT(ctl, link); - APPEND(server_controls, ctl, link); - install(ctl); - if (ctl->sctx == NULL) - free_control(&server_controls, ctl); - } -} - -/* Private functions. */ - -static struct ctl_sctx * -mksrvr(control ctl, const struct sockaddr *sa, size_t salen) { - return (ctl_server(ev, sa, salen, verbs, 500, 222, - 600, 5, 10, logger, ctl)); -} - -static control -new_control(void) { - control new = memget(sizeof *new); - - if (new == NULL) - panic("memget failed in new_control()", NULL); - new->type = t_dead; - new->sctx = NULL; - return (new); -} - -static void -free_control(controls *list, control this) { - int was_live = 0; - struct stat sb; - - if (this->sctx != NULL) { - ctl_endserver(this->sctx); - this->sctx = NULL; - was_live = 1; - } - switch (this->type) { - case t_inet: - if (this->var.v_inet.allow != NULL) { - free_ip_match_list(this->var.v_inet.allow); - this->var.v_inet.allow = NULL; - } - break; -#ifndef NO_SOCKADDR_UN - case t_unix: - /* XXX Race condition. */ - if (was_live && - stat(this->var.v_unix.un.sun_path, &sb) == 0 && - (S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) { - /* XXX Race condition. */ - unlink(this->var.v_unix.un.sun_path); - } - break; -#endif - default: - panic("impossible type in free_control", NULL); - /* NOTREACHED */ - } - UNLINK(*list, this, link); - memput(this, sizeof *this); -} - -static void -free_controls(controls *list) { - control ctl, next; - - for (ctl = HEAD(*list); ctl != NULL; ctl = next) { - next = NEXT(ctl, link); - free_control(list, ctl); - } - INIT_LIST(*list); -} - -static int -match_control(control l, control r) { - int match = 1; - - if (l->type != r->type) - match = 0; - else - switch (l->type) { - case t_inet: - if (l->var.v_inet.in.sin_family != - r->var.v_inet.in.sin_family || - l->var.v_inet.in.sin_port != - r->var.v_inet.in.sin_port || - l->var.v_inet.in.sin_addr.s_addr != - r->var.v_inet.in.sin_addr.s_addr) - match = 0; - break; -#ifndef NO_SOCKADDR_UN - case t_unix: - if (l->var.v_unix.un.sun_family != - r->var.v_unix.un.sun_family || - strcmp(l->var.v_unix.un.sun_path, - r->var.v_unix.un.sun_path) != 0) - match = 0; - break; -#endif - default: - panic("impossible type in match_control", NULL); - /* NOTREACHED */ - } - ns_debug(ns_log_config, 20, "match_control(): %d", match); - return (match); -} - -static control -find_control(controls list, control new) { - control ctl; - - for (ctl = HEAD(list); ctl != NULL; ctl = NEXT(ctl, link)) - if (match_control(ctl, new)) - return (ctl); - return (NULL); -} - -static void -propagate_changes(const control diff, control base) { - int need_install = 0; - - switch (base->type) { - case t_inet: - if (base->var.v_inet.allow != NULL) - free_ip_match_list(base->var.v_inet.allow); - base->var.v_inet.allow = diff->var.v_inet.allow; - diff->var.v_inet.allow = NULL; - need_install++; - break; -#ifndef NO_SOCKADDR_UN - case t_unix: - if (base->var.v_unix.mode != diff->var.v_unix.mode) { - base->var.v_unix.mode = diff->var.v_unix.mode; - need_install++; - } - if (base->var.v_unix.owner != diff->var.v_unix.owner) { - base->var.v_unix.owner = diff->var.v_unix.owner; - need_install++; - } - if (base->var.v_unix.group != diff->var.v_unix.group) { - base->var.v_unix.group = diff->var.v_unix.group; - need_install++; - } - break; -#endif - default: - panic("impossible type in ns_ctl::propagate_changes", NULL); - /* NOTREACHED */ - } - if (need_install) - install(base); -} - -static void -install(control ctl) { - switch (ctl->type) { - case t_inet: - install_inet(ctl); - break; -#ifndef NO_SOCKADDR_UN - case t_unix: - install_unix(ctl); - break; -#endif - default: - panic("impossible type in ns_ctl::install", NULL); - /* NOTREACHED */ - } -} - -static void -install_inet(control ctl) { - if (ctl->sctx == NULL) { - ctl->sctx = mksrvr(ctl, - (struct sockaddr *)&ctl->var.v_inet.in, - sizeof ctl->var.v_inet.in); - } -} - -#ifndef NO_SOCKADDR_UN -/* - * Unattach an old unix domain socket if it exists. - */ -static void -unattach(control ctl) { - int s; - struct stat sb; - - s = socket(AF_UNIX, SOCK_STREAM, 0); - if (s < 0) { - ns_warning(ns_log_config, - "unix control \"%s\" socket failed: %s", - ctl->var.v_unix.un.sun_path, - strerror(errno)); - return; - } - - if (stat(ctl->var.v_unix.un.sun_path, &sb) < 0) { - switch (errno) { - case ENOENT: /* We exited cleanly last time */ - break; - default: - ns_warning(ns_log_config, - "unix control \"%s\" stat failed: %s", - ctl->var.v_unix.un.sun_path, - strerror(errno)); - break; - } - goto cleanup; - } - - if (!(S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) { - ns_warning(ns_log_config, "unix control \"%s\" not socket", - ctl->var.v_unix.un.sun_path); - goto cleanup; - } - - if (connect(s, (struct sockaddr *)&ctl->var.v_unix.un, - sizeof ctl->var.v_unix.un) < 0) { - switch (errno) { - case ECONNREFUSED: - case ECONNRESET: - if (unlink(ctl->var.v_unix.un.sun_path) < 0) - ns_warning(ns_log_config, - "unix control \"%s\" unlink failed: %s", - ctl->var.v_unix.un.sun_path, - strerror(errno)); - break; - default: - ns_warning(ns_log_config, - "unix control \"%s\" connect failed: %s", - ctl->var.v_unix.un.sun_path, - strerror(errno)); - break; - } - } - cleanup: - close(s); -} - -static void -install_unix(control ctl) { - char *path; -#ifdef NEED_SECURE_DIRECTORY - char *slash; - - path = savestr(ctl->var.v_unix.un.sun_path, 1); - - slash = strrchr(path, '/'); - if (slash != NULL) { - if (slash != path) - *slash = '\0'; - else { - freestr(path); - path = savestr("/", 1); - } - } else { - freestr(path); - path = savestr(".", 1); - } - if (mkdir(path, ctl->var.v_unix.mode) < 0) { - if (errno != EEXIST) { - ns_warning(ns_log_config, - "unix control \"%s\" mkdir failed: %s", - path, strerror(errno)); - } - } -#else - path = ctl->var.v_unix.un.sun_path; -#endif - - if (ctl->sctx == NULL) { - unattach(ctl); - ctl->sctx = mksrvr(ctl, - (struct sockaddr *)&ctl->var.v_unix.un, - sizeof ctl->var.v_unix.un); - } - if (ctl->sctx != NULL) { - /* XXX Race condition. */ - if (chmod(path, ctl->var.v_unix.mode) < 0) { - ns_warning(ns_log_config, "chmod(\"%s\", 0%03o): %s", - ctl->var.v_unix.un.sun_path, - ctl->var.v_unix.mode, - strerror(errno)); - } - if (chown(path, ctl->var.v_unix.owner, - ctl->var.v_unix.group) < 0) { - ns_warning(ns_log_config, "chown(\"%s\", %d, %d): %s", - ctl->var.v_unix.un.sun_path, - ctl->var.v_unix.owner, - ctl->var.v_unix.group, - strerror(errno)); - } - } -#ifdef NEED_SECURE_DIRECTORY - freestr(path); -#endif -} -#endif - -static void -logger(enum ctl_severity ctlsev, const char *format, ...) { - va_list args; - int logsev; - - switch (ctlsev) { - case ctl_debug: logsev = log_debug(5); break; - case ctl_warning: logsev = log_warning; break; - case ctl_error: logsev = log_error; break; - default: panic("invalid ctlsev in logger", NULL); - } - if (!log_ctx_valid) - return; - va_start(args, format); - log_vwrite(log_ctx, ns_log_control, logsev, format, args); - va_end(args); -} - -static void -verb_connect(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - const struct sockaddr *sa = (struct sockaddr *)respctx; - control nsctl = (control)uctx; - - if (sa->sa_family == AF_INET) { - const struct sockaddr_in *in = (struct sockaddr_in *)sa; - const ip_match_list acl = nsctl->var.v_inet.allow; - - if (!ip_address_allowed(acl, in->sin_addr)) { - ctl_response(sess, 502, "Permission denied.", - CTL_EXIT, NULL, NULL, NULL, NULL, 0); - return; - } - } - ctl_response(sess, 220, server_options->version, 0, NULL, NULL, NULL, - NULL, 0); -} - -static void -verb_getpid(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - char *msg = memget(MAX_STR_LEN); - - if (msg == NULL) { - ctl_response(sess, 503, "(out of memory)", 0, - NULL, NULL, NULL, NULL, 0); - return; - } - sprintf(msg, "my pid is <%ld>", (long)getpid()); - ctl_response(sess, 250, msg, 0, NULL, getpid_closure, msg, NULL, 0); -} - -static void -getpid_closure(struct ctl_sctx *sctx, struct ctl_sess *sess, void *uap) { - char *msg = uap; - - memput(msg, MAX_STR_LEN); -} - -enum state { - e_version = 0, - e_nzones, - e_debug, - e_xfersrun, - e_xfersdfr, - e_qserials, - e_qrylog, - e_priming, - e_loading, - e_finito -}; - -struct pvt_status { - enum state state; - char text[MAX_STR_LEN]; -}; - -static void -verb_status(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct pvt_status *pvt = ctl_getcsctx(sess); - - if (pvt == NULL) { - pvt = memget(sizeof *pvt); - if (pvt == NULL) { - ctl_response(sess, 505, "(out of memory)", - 0, NULL, NULL, NULL, NULL, 0); - return; - } - pvt->state = e_version; - (void)ctl_setcsctx(sess, pvt); - } - switch (pvt->state++) { - case e_version: - strncpy(pvt->text, Version, sizeof pvt->text); - pvt->text[sizeof pvt->text - 1] = '\0'; - break; - case e_nzones: - sprintf(pvt->text, "number of zones allocated: %d", nzones); - break; - case e_debug: - sprintf(pvt->text, "debug level: %d", debug); - break; - case e_xfersrun: - sprintf(pvt->text, "xfers running: %d", xfers_running); - break; - case e_xfersdfr: - sprintf(pvt->text, "xfers deferred: %d", xfers_deferred); - break; - case e_qserials: - sprintf(pvt->text, "soa queries in progress: %d", - qserials_running); - break; - case e_qrylog: - sprintf(pvt->text, "query logging is %s", - qrylog ? "ON" : "OFF"); - break; - case e_priming: - sprintf(pvt->text, "server is %s priming", - priming ? "STILL" : "DONE"); - break; - case e_loading: - sprintf(pvt->text, "server %s loading its configuration", - loading ? "IS" : "IS NOT"); - break; - case e_finito: - return; - } - ctl_response(sess, 250, pvt->text, - (pvt->state == e_finito) ? 0 : CTL_MORE, - NULL, status_closure, NULL, NULL, 0); -} - -static void -status_closure(struct ctl_sctx *sctx, struct ctl_sess *sess, void *uap) { - struct pvt_status *pvt = ctl_getcsctx(sess); - - memput(pvt, sizeof *pvt); - ctl_setcsctx(sess, NULL); -} - -static void -verb_stop(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - ns_need(main_need_exit); - ctl_response(sess, 250, "Shutdown initiated.", 0, NULL, NULL, NULL, - NULL, 0); -} - -static void -verb_exec(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - struct stat sb; - - if (rest != NULL && *rest != '\0') { - if (stat(rest, &sb) < 0) { - ctl_response(sess, 503, strerror(errno), - 0, NULL, NULL, NULL, NULL, 0); - return; - } - saved_argv[0] = savestr(rest, 1); /* Never strfreed. */ - } - - if (stat(saved_argv[0], &sb) < 0) { - const char *save = strerror(errno); - - ns_warning(ns_log_default, "can't exec, %s: %s", - saved_argv[0], save); - ctl_response(sess, 502, save, 0, NULL, NULL, NULL, - NULL, 0); - } else { - ns_need(main_need_restart); - ctl_response(sess, 250, "Restart initiated.", 0, NULL, - NULL, NULL, NULL, 0); - } -} - -static void -verb_reload(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - static const char spaces[] = " \t"; - struct zoneinfo *zp; - char *tmp = NULL, *x; - const char *msg; - int class, code, success; - - /* If there are no args, this is a classic reload of the config. */ - if (rest == NULL || *rest == '\0') { - ns_need(main_need_reload); - code = 250; - msg = "Reload initiated."; - goto respond; - } - - /* Look for optional zclass argument. Default is "in". */ - tmp = savestr(rest, 1); - x = tmp + strcspn(tmp, spaces); - if (*x != '\0') { - *x++ = '\0'; - x += strspn(x, spaces); - } - if (x == NULL || *x == '\0') - x = "in"; - class = sym_ston(__p_class_syms, x, &success); - if (!success) { - code = 507; - msg = "unrecognized class"; - goto respond; - } - - /* Look for the zone, and do the right thing to it. */ - zp = find_zone(tmp, class); - if (zp == NULL) { - code = 506; - msg = "Zone not found."; - goto respond; - } - switch (zp->z_type) { - case z_master: - ns_stopxfrs(zp); - /*FALLTHROUGH*/ - case z_hint: - block_signals(); - code = 251; - msg = deferred_reload_unsafe(zp); - unblock_signals(); - break; - case z_slave: - case z_stub: - ns_stopxfrs(zp); - if (zonefile_changed_p(zp)) - zp->z_serial = 0; /* force xfer */ - addxfer(zp); - code = 251; - msg = "Slave transfer queued."; - goto respond; - case z_forward: - case z_cache: - default: - msg = "Non reloadable zone."; - code = 507; - break; - } - - respond: - ctl_response(sess, code, msg, 0, NULL, NULL, NULL, NULL, 0); - if (tmp != NULL) - freestr(tmp); -} - -static void -verb_reconfig(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - if (strcmp(rest, "-noexpired") != 0) - ns_need(main_need_reconfig); - else - ns_need(main_need_noexpired); - ctl_response(sess, 250, "Reconfig initiated.", - 0, NULL, NULL, NULL, NULL, 0); -} - -static void -verb_dumpdb(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - ns_need(main_need_dump); - ctl_response(sess, 250, "Database dump initiated.", 0, NULL, - NULL, NULL, NULL, 0); -} - -static void -verb_stats(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - ns_need(main_need_statsdump); - ctl_response(sess, 250, "Statistics dump initiated.", - 0, NULL, NULL, NULL, NULL, 0); -} - -static void -verb_trace(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - int i = atoi(rest); - char *msg = memget(MAX_STR_LEN); - - if (msg == NULL) { - ctl_response(sess, 503, "(out of memory)", 0, - NULL, NULL, NULL, NULL, 0); - return; - } - if (i > 0) - desired_debug = i; - else - desired_debug++; - ns_need(main_need_debug); - sprintf(msg, "Debug level: %d", desired_debug); - ctl_response(sess, 250, msg, 0, NULL, trace_closure, msg, NULL, 0); -} - -static void -trace_closure(struct ctl_sctx *sctx, struct ctl_sess *sess, void *uap) { - char *msg = uap; - - memput(msg, MAX_STR_LEN); -} - -static void -verb_notrace(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - desired_debug = 0; - ns_need(main_need_debug); - ctl_response(sess, 250, "Debugging turned off.", - 0, NULL, NULL, NULL, NULL, 0); -} - -static void -verb_querylog(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - static const char on[] = "Query logging is now on.", - off[] = "Query logging is now off."; - - toggle_qrylog(); - ctl_response(sess, 250, qrylog ? on : off, - 0, NULL, NULL, NULL, NULL, 0); -} - -static void -verb_help(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - ctl_sendhelp(sess, 214); -} - -static void -verb_quit(struct ctl_sctx *ctl, struct ctl_sess *sess, - const struct ctl_verb *verb, const char *rest, - u_int respflags, void *respctx, void *uctx) -{ - ctl_response(sess, 221, "End of control session.", CTL_EXIT, NULL, - NULL, NULL, NULL, 0); -} diff --git a/contrib/bind/bin/named/ns_defs.h b/contrib/bind/bin/named/ns_defs.h deleted file mode 100644 index 56b50fed20d9f..0000000000000 --- a/contrib/bind/bin/named/ns_defs.h +++ /dev/null @@ -1,901 +0,0 @@ -/* - * from ns.h 4.33 (Berkeley) 8/23/90 - * $Id: ns_defs.h,v 8.96 2000/04/21 06:54:06 vixie Exp $ - */ - -/* - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Check Point Software Technologies Incorporated not be used - * in advertising or publicity pertaining to distribution of the document - * or software without specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND CHECK POINT SOFTWARE TECHNOLOGIES - * INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL CHECK POINT SOFTWARE TECHNOLOGIES INCORPRATED - * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Global definitions for the name server. - */ - -/* - * Effort has been expended here to make all structure members 32 bits or - * larger land on 32-bit boundaries; smaller structure members have been - * deliberately shuffled and smaller integer sizes chosen where possible - * to make sure this happens. This is all meant to avoid structure member - * padding which can cost a _lot_ of memory when you have hundreds of - * thousands of entries in your cache. - */ - -/* - * Timeout time should be around 1 minute or so. Using the - * the current simplistic backoff strategy, the sequence - * retrys after 4, 8, and 16 seconds. With 3 servers, this - * dies out in a little more than a minute. - * (sequence RETRYBASE, 2*RETRYBASE, 4*RETRYBASE... for MAXRETRY) - */ -#define NEWZONES 64 /* must be a power of two. */ -#define MINROOTS 2 /* min number of root hints */ -#define NSMAX 16 /* max number of NS addrs to try ([0..255]) */ -#define RETRYBASE 4 /* base time between retries */ -#define MAXCLASS 255 /* XXX - may belong elsewhere */ -#define MAXRETRY 3 /* max number of retries per addr */ -#define MAXCNAMES 8 /* max # of CNAMES tried per addr */ -#define MAXQUERIES 20 /* max # of queries to be made */ -#define MAXQSERIAL 4 /* max # of outstanding QSERIAL's */ - /* (prevent "recursive" loops) */ -#define INIT_REFRESH 600 /* retry time for initial secondary */ - /* contact (10 minutes) */ -#define MIN_REFRESH 2 /* never refresh more frequently than once */ - /* every MIN_REFRESH seconds */ -#define MIN_RETRY 1 /* never retry more frequently than once */ - /* every MIN_RETRY seconds */ -#define MAX_REFRESH 2419200 /* perform a refresh query at least */ - /* every 4 weeks*/ -#define MAX_RETRY 1209600 /* perform a retry after no more than 2 weeks */ -#define MAX_EXPIRE 31536000 /* expire a zone if we have not talked to */ - /* the primary in 1 year */ -#define NADDRECS 20 /* max addt'l rr's per resp */ - -#define XFER_TIMER 120 /* named-xfer's connect timeout */ -#define MAX_XFER_TIME 60*60*2 /* default max seconds for an xfer */ -#define XFER_TIME_FUDGE 10 /* MAX_XFER_TIME fudge */ -#define MAX_XFERS_RUNNING 20 /* max value of transfers_in */ -#define DEFAULT_XFERS_RUNNING 10 /* default value of transfers_in */ -#define DEFAULT_XFERS_PER_NS 2 /* default # of xfers per peer nameserver */ -#define XFER_BUFSIZE (16*1024) /* arbitrary but bigger than most MTU's */ - - /* maximum time to cache negative answers */ -#define DEFAULT_MAX_NCACHE_TTL (3*60*60) - -#define ALPHA 0.7 /* How much to preserve of old response time */ -#define BETA 1.2 /* How much to penalize response time on failure */ -#define GAMMA 0.98 /* How much to decay unused response times */ - - /* What maintainance operations need to be performed sometime soon? */ -typedef enum need { - main_need_zreload = 0, /* ns_zreload() needed. */ - main_need_reload, /* ns_reload() needed. */ - main_need_reconfig, /* ns_reconfig() needed. */ - main_need_endxfer, /* endxfer() needed. */ - main_need_zoneload, /* loadxfer() needed. */ - main_need_dump, /* doadump() needed. */ - main_need_statsdump, /* ns_stats() needed. */ - main_need_exit, /* exit() needed. */ - main_need_qrylog, /* toggle_qrylog() needed. */ - main_need_debug, /* use_desired_debug() needed. */ - main_need_restart, /* exec() needed. */ - main_need_reap, /* need to reap dead children */ - main_need_noexpired, /* ns_reconfig() needed w/ noexpired set */ - main_need_num, /* number of needs, used for array bound. */ - main_need_tick /* tick every second to poll for cleanup (NT)*/ -} main_need; - - /* What global options are set? */ -#define OPTION_NORECURSE 0x0001 /* Don't recurse even if asked. */ -#define OPTION_NOFETCHGLUE 0x0002 /* Don't fetch missing glue. */ -#define OPTION_FORWARD_ONLY 0x0004 /* Don't use NS RR's, just forward. */ -#define OPTION_FAKE_IQUERY 0x0008 /* Fake up bogus response to IQUERY. */ -#ifdef BIND_NOTIFY -#define OPTION_NONOTIFY 0x0010 /* Turn off notify */ -#endif -#define OPTION_NONAUTH_NXDOMAIN 0x0020 /* Generate non-auth NXDOMAINs? */ -#define OPTION_MULTIPLE_CNAMES 0x0040 /* Allow a name to have multiple - * CNAME RRs */ -#define OPTION_HOSTSTATS 0x0080 /* Maintain per-host statistics? */ -#define OPTION_DEALLOC_ON_EXIT 0x0100 /* Deallocate everything on exit? */ -#define OPTION_NODIALUP 0x0200 /* Turn off dialup support */ -#define OPTION_NORFC2308_TYPE1 0x0400 /* Prevent type1 respones (RFC 2308) - * to cached negative respones */ -#define OPTION_USE_ID_POOL 0x0800 /* Use the memory hogging query ID */ -#define OPTION_TREAT_CR_AS_SPACE 0x1000 /* Treat CR in zone files as space */ -#define OPTION_USE_IXFR 0x2000 /* Use by delault ixfr in zone transfer */ -#define OPTION_MAINTAIN_IXFR_BASE 0x4000 /* Part of IXFR file name logic. */ - -#define DEFAULT_OPTION_FLAGS (OPTION_NODIALUP|OPTION_NONAUTH_NXDOMAIN|\ - OPTION_USE_ID_POOL|OPTION_NORFC2308_TYPE1) - -#ifdef BIND_UPDATE -#define SOAINCRINTVL 300 /* default value for the time after which - * the zone serial number must be incremented - * after a successful update has occurred */ -#define DUMPINTVL 3600 /* default interval at which to dump changed zones - * randomized, not exact */ -#define DEFERUPDCNT 100 /* default number of updates that can happen - * before the zone serial number will be - * incremented */ -#define UPDATE_TIMER XFER_TIMER -#endif /* BIND_UPDATE */ - -#define USE_MINIMUM 0xffffffff -#define MAXIMUM_TTL 0x7fffffff - -#define CLEAN_TIMER 0x01 -#define INTERFACE_TIMER 0x02 -#define STATS_TIMER 0x04 -#define HEARTBEAT_TIMER 0x08 - - /* IP address accessor, network byte order. */ -#define ina_ulong(ina) (ina.s_addr) - - /* IP address accessor, host byte order, read only. */ -#define ina_hlong(ina) ntohl(ina.s_addr) - - /* IP address equality. */ - /* XXX: assumes that network byte order won't affect equality. */ -#define ina_equal(a, b) (ina_ulong(a) == ina_ulong(b)) - - /* IP address equality with a mask. */ -#define ina_onnet(h, n, m) ((ina_ulong(h) & ina_ulong(m)) == ina_ulong(n)) - - /* Sequence space arithmetic. */ -#define SEQ_GT(a,b) ((int32_t)((a)-(b)) > 0) - -#define NS_OPTION_P(option) ((server_options == NULL) ? \ - (panic(panic_msg_no_options, NULL), 0) : \ - ((server_options->flags & option) != 0)) - -#define NS_ZOPTION_P(zp, option) \ - (((zp) != NULL && (((zp)->z_optset & option) != 0)) ? \ - (((zp)->z_options & option) != 0) : NS_OPTION_P(option)) - -#define NS_ZFWDTAB(zp) (((zp) == NULL) ? \ - server_options->fwdtab : (zp)->z_fwdtab) - -#define NS_INCRSTAT(addr, which) \ - do { \ - if ((int)which >= (int)nssLast) \ - ns_panic(ns_log_insist, 1, panic_msg_bad_which, \ - __FILE__, __LINE__, #which); \ - else { \ - if (NS_OPTION_P(OPTION_HOSTSTATS)) { \ - struct nameser *ns = \ - nameserFind(addr, NS_F_INSERT); \ - if (ns != NULL) \ - ns->stats[(int)which]++; \ - } \ - globalStats[(int)which]++; \ - } \ - } while (0) - -enum severity { ignore, warn, fail, not_set }; - -#ifdef BIND_NOTIFY -enum znotify { znotify_use_default=0, znotify_yes, znotify_no }; -#endif - -enum zdialup { zdialup_use_default=0, zdialup_yes, zdialup_no }; - -enum axfr_format { axfr_use_default=0, axfr_one_answer, axfr_many_answers }; - -struct ip_match_direct { - struct in_addr address; - struct in_addr mask; -}; - -struct ip_match_indirect { - struct ip_match_list *list; -}; - -struct ip_match_key { - struct dst_key *key; -}; - -typedef enum { ip_match_pattern, ip_match_indirect, ip_match_localhost, - ip_match_localnets, ip_match_key } ip_match_type; - -typedef struct ip_match_element { - ip_match_type type; - u_int flags; - union { - struct ip_match_direct direct; - struct ip_match_indirect indirect; - struct ip_match_key key; - } u; - struct ip_match_element *next; -} *ip_match_element; - -/* Flags for ip_match_element */ -#define IP_MATCH_NEGATE 0x01 /* match means deny access */ - -typedef struct ip_match_list { - ip_match_element first; - ip_match_element last; -} *ip_match_list; - -typedef struct ztimer_info { - char *name; - int class; - int type; -} *ztimer_info; - -/* - * These fields are ordered to maintain word-alignment; - * be careful about changing them. - */ -struct zoneinfo { - char *z_origin; /* root domain name of zone */ - time_t z_time; /* time for next refresh */ - time_t z_lastupdate; /* time of last soa serial increment */ - u_int32_t z_refresh; /* refresh interval */ - u_int32_t z_retry; /* refresh retry interval */ - u_int32_t z_expire; /* expiration time for cached info */ - u_int32_t z_minimum; /* minimum TTL value */ - u_int32_t z_serial; /* changes if zone modified */ - char *z_source; /* source location of data */ - time_t z_ftime; /* modification time of source file */ - struct in_addr z_axfr_src; /* bind() the axfr socket to this */ - struct in_addr z_addr[NSMAX]; /* list of master servers for zone */ - u_char z_addrcnt; /* number of entries in z_addr[] */ - struct in_addr z_xaddr[NSMAX]; /* list of master servers for xfer */ - u_char z_xaddrcnt; /* number of entries in z_xaddr[] */ - u_char z_type; /* type of zone; see below */ - u_int32_t z_flags; /* state bits; see below */ - pid_t z_xferpid; /* xfer child pid */ - u_int z_options; /* options set specific to this zone */ - u_int z_optset; /* which opts override global opts */ - int z_class; /* class of zone */ - int z_numxfrs; /* Ref count of concurrent xfrs. */ - enum severity z_checknames; /* How to handle non-RFC-compliant names */ -#ifdef BIND_UPDATE - time_t z_dumptime; /* randomized time for next zone dump - * if Z_NEED_DUMP is set */ - u_int32_t z_dumpintvl; /* time interval between zone dumps */ - time_t z_soaincrintvl; /* interval for updating soa serial */ - time_t z_soaincrtime; /* time for soa increment */ - u_int32_t z_deferupdcnt; /* max number of updates before SOA - * serial number incremented */ - u_int32_t z_updatecnt; /* number of update requests processed - * since the last SOA serial update */ - char *z_updatelog; /* log file for updates */ -#endif - ip_match_list z_update_acl; /* list of who can issue dynamic - updates */ - ip_match_list z_query_acl; /* sites we'll answer questions for */ - ip_match_list z_transfer_acl; /* sites that may get a zone transfer - from us */ - long z_max_transfer_time_in; /* max num seconds for AXFR */ -#ifdef BIND_NOTIFY - enum znotify z_notify; /* Notify mode */ - struct in_addr *z_also_notify; /* More nameservers to notify */ - int z_notify_count; -#endif - enum zdialup z_dialup; /* secondaries over a dialup link */ - char *z_ixfr_base; /* where to find the history of the zone */ - char *z_ixfr_tmp; /* tmp file for the ixfr */ - int z_maintain_ixfr_base; - long z_max_log_size_ixfr; - u_int32_t z_serial_ixfr_start; - evTimerID z_timer; /* maintenance timer */ - ztimer_info z_timerinfo; /* UAP associated with timer */ - time_t z_nextmaint; /* time of next maintenance */ - u_int16_t z_port; /* perform AXFR to this port */ - struct fwdinfo *z_fwdtab; /* zone-specific forwarders */ - LINK(struct zoneinfo) z_freelink; /* if it's on the free list. */ - LINK(struct zoneinfo) z_reloadlink; /* if it's on the reload list. */ -}; - - /* zone types (z_type) */ -enum zonetype { z_nil, z_master, z_slave, z_hint, z_stub, z_forward, - z_cache, z_any }; -#define Z_NIL z_nil /* XXX */ -#define Z_MASTER z_master /* XXX */ -#define Z_PRIMARY z_master /* XXX */ -#define Z_SLAVE z_slave /* XXX */ -#define Z_SECONDARY z_slave /* XXX */ -#define Z_HINT z_hint /* XXX */ -#define Z_CACHE z_cache /* XXX */ -#define Z_STUB z_stub /* XXX */ -#define Z_FORWARD z_forward /* XXX */ -#define Z_ANY z_any /* XXX*2 */ - - /* zone state bits (32 bits) */ -#define Z_AUTH 0x00000001 /* zone is authoritative */ -#define Z_NEED_XFER 0x00000002 /* waiting to do xfer */ -#define Z_XFER_RUNNING 0x00000004 /* asynch. xfer is running */ -#define Z_NEED_RELOAD 0x00000008 /* waiting to do reload */ -#define Z_SYSLOGGED 0x00000010 /* have logged timeout */ -#define Z_QSERIAL 0x00000020 /* sysquery()'ing for serial number */ -#define Z_FOUND 0x00000040 /* found in boot file when reloading */ -#define Z_INCLUDE 0x00000080 /* set if include used in file */ -#define Z_DB_BAD 0x00000100 /* errors when loading file */ -#define Z_TMP_FILE 0x00000200 /* backup file for xfer is temporary */ -#ifdef BIND_UPDATE -#define Z_DYNAMIC 0x00000400 /* allow dynamic updates */ -#define Z_NEED_DUMP 0x00000800 /* zone has changed, needs a dump */ -#define Z_NEED_SOAUPDATE 0x00001000 /* soa serial number needs increment */ -#endif /* BIND_UPDATE */ -#define Z_XFER_ABORTED 0x00002000 /* zone transfer has been aborted */ -#define Z_XFER_GONE 0x00004000 /* zone transfer process is gone */ -#define Z_TIMER_SET 0x00008000 /* z_timer contains a valid id */ -#ifdef BIND_NOTIFY -#define Z_NOTIFY 0x00010000 /* has an outbound notify executing */ -#endif -#define Z_NEED_QSERIAL 0x00020000 /* we need to re-call qserial() */ -#define Z_PARENT_RELOAD 0x00040000 /* we need to reload this as parent */ -#define Z_FORWARD_SET 0x00080000 /* has forwarders been set */ -#define Z_EXPIRED 0x00100000 /* expire timer has gone off */ - - /* named_xfer exit codes */ -#define XFER_UPTODATE 0 /* zone is up-to-date */ -#define XFER_SUCCESS 1 /* performed transfer successfully */ -#define XFER_TIMEOUT 2 /* no server reachable/xfer timeout */ -#define XFER_FAIL 3 /* other failure, has been logged */ -#define XFER_SUCCESSAXFR 4 /* named-xfr recived a xfr */ -#define XFER_SUCCESSIXFR 5 /* named-xfr recived a ixfr */ -#define XFER_SUCCESSAXFRIXFRFILE 6 /* named-xfr received AXFR for IXFR */ -#define XFER_ISAXFR -1 /* the last XFR is AXFR */ -#define XFER_ISIXFR -2 /* the last XFR is IXFR */ -#define XFER_ISAXFRIXFR -3 /* the last XFR is AXFR but we must create IXFR base */ - -struct qserv { - struct sockaddr_in - ns_addr; /* address of NS */ - struct databuf *ns; /* databuf for NS record */ - struct databuf *nsdata; /* databuf for server address */ - struct timeval stime; /* time first query started */ - unsigned int forwarder:1; /* this entry is for a forwarder */ - unsigned int nretry:31; /* # of times addr retried */ - u_int32_t serial; /* valid if Q_ZSERIAL */ -}; - -/* - * Structure for recording info on forwarded or generated queries. - */ -struct qinfo { - u_int16_t q_id; /* id of query */ - u_int16_t q_nsid; /* id of forwarded query */ - struct sockaddr_in - q_from; /* requestor's address */ - u_char *q_msg, /* the message */ - *q_cmsg; /* the cname message */ - int16_t q_msglen, /* len of message */ - q_msgsize, /* allocated size of message */ - q_cmsglen, /* len of cname message */ - q_cmsgsize; /* allocated size of cname message */ - int16_t q_dfd; /* UDP file descriptor */ - time_t q_time; /* time to retry */ - time_t q_expire; /* time to expire */ - struct qinfo *q_next; /* rexmit list (sorted by time) */ - struct qinfo *q_link; /* storage list (random order) */ - struct databuf *q_usedns[NSMAX]; /* databuf for NS that we've tried */ - struct qserv q_addr[NSMAX]; /* addresses of NS's */ -#ifdef notyet - struct nameser *q_ns[NSMAX]; /* name servers */ -#endif - u_char q_naddr; /* number of addr's in q_addr */ - u_char q_curaddr; /* last addr sent to */ - u_char q_nusedns; /* number of elements in q_usedns[] */ - u_int8_t q_flags; /* see below */ - int16_t q_cname; /* # of cnames found */ - int16_t q_nqueries; /* # of queries required */ - struct qstream *q_stream; /* TCP stream, null if UDP */ - struct zoneinfo *q_zquery; /* Zone query is about (Q_ZSERIAL) */ - struct zoneinfo *q_fzone; /* Forwarding zone, if any */ - char *q_domain; /* domain of most enclosing zone cut */ - char *q_name; /* domain of query */ - u_int16_t q_class; /* class of query */ - u_int16_t q_type; /* type of query */ -#ifdef BIND_NOTIFY - int q_notifyzone; /* zone which needs another znotify() - * when the reply to this comes in. - */ -#endif - struct tsig_record *q_tsig; /* forwarded query's TSIG record */ - struct tsig_record *q_nstsig; /* forwarded query's TSIG record */ -}; - - /* q_flags bits (8 bits) */ -#define Q_SYSTEM 0x01 /* is a system query */ -#define Q_PRIMING 0x02 /* generated during priming phase */ -#define Q_ZSERIAL 0x04 /* getting zone serial for xfer test */ -#define Q_USEVC 0x08 /* forward using tcp not udp */ - -#define Q_NEXTADDR(qp,n) (&(qp)->q_addr[n].ns_addr) - -#define RETRY_TIMEOUT 45 - -/* - * Return codes from ns_forw: - */ -#define FW_OK 0 -#define FW_DUP 1 -#define FW_NOSERVER 2 -#define FW_SERVFAIL 3 - -typedef void (*sq_closure)(struct qstream *qs); - -#ifdef BIND_UPDATE -struct fdlist { - int fd; - struct fdlist *next; -}; -#endif - - -typedef struct ns_delta { - LINK(struct ns_delta) d_link; - ns_updque d_changes; -} ns_delta; - -typedef LIST(ns_delta) ns_deltalist; - -typedef struct _interface { - int dfd, /* Datagram file descriptor */ - sfd; /* Stream file descriptor. */ - time_t gen; /* Generation number. */ - struct in_addr addr; /* Interface address. */ - u_int16_t port; /* Interface port. */ - u_int16_t flags; /* Valid bits for evXXXXID. */ - evFileID evID_d; /* Datagram read-event. */ - evConnID evID_s; /* Stream listen-event. */ - LINK(struct _interface) link; -} interface; - -#define INTERFACE_FILE_VALID 0x01 -#define INTERFACE_CONN_VALID 0x02 -#define INTERFACE_FORWARDING 0x04 - -struct qstream { - int s_rfd; /* stream file descriptor */ - int s_size; /* expected amount of data to rcv */ - int s_bufsize; /* amount of data received in s_buf */ - u_char *s_buf; /* buffer of received data */ - u_char *s_wbuf; /* send buffer */ - u_char *s_wbuf_send; /* next sendable byte of send buffer */ - u_char *s_wbuf_free; /* next free byte of send buffer */ - u_char *s_wbuf_end; /* byte after end of send buffer */ - sq_closure s_wbuf_closure; /* callback for writable descriptor */ - struct qstream *s_next; /* next stream */ - struct sockaddr_in - s_from; /* address query came from */ - interface *s_ifp; /* interface query came from */ - time_t s_time; /* time stamp of last transaction */ - int s_refcnt; /* number of outstanding queries */ - u_char s_temp[HFIXEDSZ]; -#ifdef BIND_UPDATE - int s_opcode; /* type of request */ - int s_linkcnt; /* number of client connections using - * this connection to forward updates - * to the primary */ - struct fdlist *s_fds; /* linked list of connections to the - * primaries that have been used by - * the server to forward this client's - * update requests */ -#endif - evStreamID evID_r; /* read event. */ - evFileID evID_w; /* writable event handle. */ - evConnID evID_c; /* connect event handle */ - u_int flags; /* see below */ - struct qstream_xfr { - enum { s_x_base, s_x_firstsoa, s_x_zone, - s_x_lastsoa, s_x_done, s_x_adding, - s_x_deleting, s_x_addsoa, s_x_deletesoa } - state; /* state of transfer. */ - u_char *msg, /* current assembly message. */ - *cp, /* where are we in msg? */ - *eom, /* end of msg. */ - *ptrs[128]; /* ptrs for dn_comp(). */ - int class, /* class of an XFR. */ - type, /* type of XFR. */ - id, /* id of an XFR. */ - opcode; /* opcode of an XFR. */ - u_int zone; /* zone being XFR'd. */ - union { - struct namebuf *axfr; /* top np of an AXFR. */ - ns_deltalist *ixfr; /* top udp of an IXFR. */ - } top; - int ixfr_zone; - u_int32_t serial; /* serial number requested in IXFR */ - ns_tcp_tsig_state *tsig_state; /* used by ns_sign_tcp */ - int tsig_skip; /* skip calling ns_sign_tcp - * during the next flush */ - struct qs_x_lev { /* decompose the recursion. */ - enum {sxl_ns, sxl_all, sxl_sub} - state; /* what's this level doing? */ - int flags; /* see below (SXL_*). */ - char dname[MAXDNAME]; - struct namebuf *np, /* this node. */ - *nnp, /* next node to process. */ - **npp, /* subs. */ - **npe; /* end of subs. */ - struct databuf *dp; /* current rr. */ - struct qs_x_lev *next; /* link. */ - } *lev; /* LIFO. */ - enum axfr_format transfer_format; - } xfr; -}; -#define SXL_GLUING 0x01 -#define SXL_ZONECUT 0x02 - - /* flags */ -#define STREAM_MALLOC 0x01 -#define STREAM_WRITE_EV 0x02 -#define STREAM_READ_EV 0x04 -#define STREAM_CONNECT_EV 0x08 -#define STREAM_DONE_CLOSE 0x10 -#define STREAM_AXFR 0x20 -#define STREAM_AXFRIXFR 0x40 - -#define ALLOW_NETS 0x0001 -#define ALLOW_HOSTS 0x0002 -#define ALLOW_ALL (ALLOW_NETS | ALLOW_HOSTS) - -struct fwddata { - struct sockaddr_in - fwdaddr; /* address of NS */ - struct databuf *ns; /* databuf for NS record */ - struct databuf *nsdata; /* databuf for server address */ - int ref_count; /* how many users of this */ -}; - -struct fwdinfo { - struct fwdinfo *next; - struct fwddata *fwddata; -}; - -enum nameserStats { nssRcvdR, /* sent us an answer */ - nssRcvdNXD, /* sent us a negative response */ - nssRcvdFwdR, /* sent us a response we had to fwd */ - nssRcvdDupR, /* sent us an extra answer */ - nssRcvdFail, /* sent us a SERVFAIL */ - nssRcvdFErr, /* sent us a FORMERR */ - nssRcvdErr, /* sent us some other error */ - nssRcvdAXFR, /* sent us an AXFR */ - nssRcvdLDel, /* sent us a lame delegation */ - nssRcvdOpts, /* sent us some IP options */ - nssSentSysQ, /* sent them a sysquery */ - nssSentAns, /* sent them an answer */ - nssSentFwdQ, /* fwdd a query to them */ - nssSentDupQ, /* sent them a retry */ - nssSendtoErr, /* error in sendto */ - nssRcvdQ, /* sent us a query */ - nssRcvdIQ, /* sent us an inverse query */ - nssRcvdFwdQ, /* sent us a query we had to fwd */ - nssRcvdDupQ, /* sent us a retry */ - nssRcvdTCP, /* sent us a query using TCP */ - nssSentFwdR, /* fwdd a response to them */ - nssSentFail, /* sent them a SERVFAIL */ - nssSentFErr, /* sent them a FORMERR */ - nssSentNaAns, /* sent them a non autoritative answer */ - nssSentNXD, /* sent them a negative response */ - nssRcvdUQ, /* sent us an unapproved query */ - nssRcvdURQ, /* sent us an unapproved recursive query */ - nssRcvdUXFR, /* sent us an unapproved AXFR or IXFR */ - nssRcvdUUpd, /* sent us an unapproved update */ - nssLast }; - -struct nameser { - struct in_addr addr; /* key */ - u_long stats[nssLast]; /* statistics */ -#ifdef notyet - u_int32_t rtt; /* round trip time */ - /* XXX - need to add more stuff from "struct qserv", and use our rtt */ - u_int16_t flags; /* see below */ -#endif - u_int8_t xfers; /* #/xfers running right now */ -}; - -enum transport { primary_trans, secondary_trans, response_trans, update_trans, - num_trans }; - -/* types used by the parser or config routines */ - -typedef struct zone_config { - void *opaque; -} zone_config; - -typedef struct listen_info { - u_short port; - ip_match_list list; - struct listen_info *next; -} *listen_info; - -typedef struct listen_info_list { - listen_info first; - listen_info last; -} *listen_info_list; - -#ifndef RLIMIT_TYPE -#define RLIMIT_TYPE u_long -#endif -typedef RLIMIT_TYPE rlimit_type; - -struct control; -typedef struct control *control; -typedef LIST(struct control) controls; - -enum ordering { unknown_order, fixed_order, cyclic_order, random_order }; - -#define DEFAULT_ORDERING cyclic_order - -typedef struct rrset_order_element { - int class; - int type; - char *name; - enum ordering order; - struct rrset_order_element *next; -} *rrset_order_element ; - -typedef struct rrset_order_list { - rrset_order_element first; - rrset_order_element last; -} *rrset_order_list; - - -typedef struct options { - u_int flags; - char *version; - char *directory; - char *dump_filename; - char *pid_filename; - char *stats_filename; - char *memstats_filename; - char *named_xfer; - int transfers_in; - int transfers_per_ns; - int transfers_out; - int serial_queries; - int max_log_size_ixfr; - enum axfr_format transfer_format; - long max_transfer_time_in; - struct sockaddr_in query_source; - struct in_addr axfr_src; -#ifdef BIND_NOTIFY - int notify_count; - struct in_addr *also_notify; -#endif - ip_match_list query_acl; - ip_match_list recursion_acl; - ip_match_list transfer_acl; - ip_match_list blackhole_acl; - ip_match_list topology; - ip_match_list sortlist; - enum severity check_names[num_trans]; - u_long data_size; - u_long stack_size; - u_long core_size; - u_long files; - listen_info_list listen_list; - struct fwdinfo *fwdtab; - /* XXX need to add forward option */ - int clean_interval; - int interface_interval; - int stats_interval; - rrset_order_list ordering; - int heartbeat_interval; - u_int max_ncache_ttl; - u_int lame_ttl; - int minroots; -} *options; - -typedef struct key_list_element { - struct dst_key *key; - struct key_list_element *next; -} *key_list_element; - -typedef struct key_info_list { - key_list_element first; - key_list_element last; -} *key_info_list; - -typedef struct topology_config { - void *opaque; -} topology_config; - -#define UNKNOWN_TOPOLOGY_DISTANCE 9998 -#define MAX_TOPOLOGY_DISTANCE 9999 - -typedef struct topology_distance { - ip_match_list patterns; - struct topology_distance *next; -} *topology_distance; - -typedef struct topology_context { - topology_distance first; - topology_distance last; -} *topology_context; - -typedef struct acl_table_entry { - char *name; - ip_match_list list; - struct acl_table_entry *next; -} *acl_table_entry; - -typedef struct server_config { - void *opaque; -} server_config; - -#define SERVER_INFO_BOGUS 0x01 -#define SERVER_INFO_SUPPORT_IXFR 0x02 - -typedef struct server_info { - struct in_addr address; - u_int flags; - int transfers; - enum axfr_format transfer_format; - key_info_list key_list; - /* could move statistics to here, too */ - struct server_info *next; -} *server_info; - -/* - * enum <--> name translation - */ - -struct ns_sym { - int number; /* Identifying number, like ns_log_default */ - char * name; /* Its symbolic name, like "default" */ -}; - -/* - * Logging options - */ - -typedef enum ns_logging_categories { - ns_log_default = 0, - ns_log_config, - ns_log_parser, - ns_log_queries, - ns_log_lame_servers, - ns_log_statistics, - ns_log_panic, - ns_log_update, - ns_log_ncache, - ns_log_xfer_in, - ns_log_xfer_out, - ns_log_db, - ns_log_eventlib, - ns_log_packet, -#ifdef BIND_NOTIFY - ns_log_notify, -#endif - ns_log_cname, - ns_log_security, - ns_log_os, - ns_log_insist, - ns_log_maint, - ns_log_load, - ns_log_resp_checks, - ns_log_control, - ns_log_max_category -} ns_logging_categories; - -typedef struct log_config { - log_context log_ctx; - log_channel eventlib_channel; - log_channel packet_channel; - int default_debug_active; -} *log_config; - -struct map { - char * token; - int val; -}; - -#define NOERROR_NODATA 15 /* only used internally by the server, used for - * -ve $ing non-existence of records. 15 is not - * a code used as yet anyway. - */ - -#define NTTL 600 /* ttl for negative data: 10 minutes? */ - -#define VQEXPIRY 900 /* a VQ entry expires in 15*60 = 900 seconds */ - -#ifdef BIND_UPDATE -enum req_action { Finish, Refuse, Return }; -#endif - -#ifdef INIT - error "INIT already defined, check system include files" -#endif -#ifdef DECL - error "DECL already defined, check system include files" -#endif - -#ifdef MAIN_PROGRAM -#define INIT(x) = x -#define DECL -#else -#define INIT(x) -#define DECL extern -#endif diff --git a/contrib/bind/bin/named/ns_forw.c b/contrib/bind/bin/named/ns_forw.c deleted file mode 100644 index beb919c147133..0000000000000 --- a/contrib/bind/bin/named/ns_forw.c +++ /dev/null @@ -1,1272 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)ns_forw.c 4.32 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: ns_forw.c,v 8.75 2000/05/09 07:12:58 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <errno.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" - -struct complaint { - u_long tag1, tag2; - time_t expire; - struct complaint *next; -}; - -static struct complaint *complaints = NULL; -static int retry_timer_set = 0; - -/* - * Forward the query to get the answer since its not in the database. - * Returns FW_OK if a request struct is allocated and the query sent. - * Returns FW_DUP if this is a duplicate of a pending request. - * Returns FW_NOSERVER if there were no addresses for the nameservers. - * Returns FW_SERVFAIL on memory allocation error or if asked to do something - * dangerous, such as fwd to ourselves or fwd to the host that asked us. - * - * (no action is taken on errors and qpp is not filled in.) - */ -int -ns_forw(struct databuf *nsp[], u_char *msg, int msglen, - struct sockaddr_in from, struct qstream *qsp, int dfd, - struct qinfo **qpp, const char *dname, int class, int type, - struct namebuf *np, int use_tcp, struct tsig_record *in_tsig) -{ - struct qinfo *qp; - char tmpdomain[MAXDNAME]; - struct sockaddr_in *nsa; - HEADER *hp; - u_int16_t id; - int sendto_errno = 0; - int n, has_tsig, oldqlen; - u_char *oldqbuf; - u_char *smsg; - int smsglen, smsgsize, siglen; - u_char sig[TSIG_SIG_SIZE]; - DST_KEY *key; - - ns_debug(ns_log_default, 3, "ns_forw()"); - - hp = (HEADER *) msg; - id = hp->id; - /* Look at them all */ - for (qp = nsqhead; qp != NULL; qp = qp->q_link) { - if (qp->q_id == id && - memcmp(&qp->q_from, &from, sizeof qp->q_from) == 0 && - ((qp->q_cmsglen == 0 && qp->q_msglen == msglen && - memcmp(qp->q_msg + 2, msg + 2, msglen - 2) == 0) || - (qp->q_cmsglen == msglen && - memcmp(qp->q_cmsg + 2, msg + 2, msglen - 2) == 0) - )) { - ns_debug(ns_log_default, 3, "forw: dropped DUP id=%d", - ntohs(id)); - nameserIncr(from.sin_addr, nssRcvdDupQ); - return (FW_DUP); - } - } - - qp = qnew(dname, class, type, 1); - getname(np, tmpdomain, sizeof tmpdomain); - qp->q_domain = savestr(tmpdomain, 1); - qp->q_from = from; /* nslookup wants to know this */ - if (NS_ZFWDTAB(qp->q_fzone)) - nsfwdadd(qp, NS_ZFWDTAB(qp->q_fzone)); - if (NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) - n = 0; - else - n = nslookup(nsp, qp, dname, "ns_forw"); - if (n < 0) { - if (n == -1) - ns_debug(ns_log_default, 2, - "forw: nslookup reports danger"); - ns_freeqry(qp); - return (FW_SERVFAIL); - } - if (n == 0 && !NS_ZFWDTAB(qp->q_fzone)) { - ns_debug(ns_log_default, 2, "forw: no nameservers found"); - ns_freeqry(qp); - return (FW_NOSERVER); - } - qp->q_stream = qsp; - qp->q_curaddr = 0; - qp->q_dfd = dfd; - qp->q_id = id; - qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2; - if (in_tsig != NULL) - qp->q_tsig = new_tsig(in_tsig->key, in_tsig->sig, - in_tsig->siglen); - if (use_tcp) - qp->q_flags |= Q_USEVC; - hp->id = qp->q_nsid = htons(nsid_next()); - hp->ancount = htons(0); - hp->nscount = htons(0); - hp->arcount = htons(0); - if ((qp->q_msg = (u_char *)memget((unsigned)msglen)) == NULL) { - ns_notice(ns_log_default, "forw: memget: %s", - strerror(errno)); - ns_freeqry(qp); - return (FW_SERVFAIL); - } - qp->q_msgsize = msglen; - memcpy(qp->q_msg, msg, qp->q_msglen = msglen); - hp = (HEADER *) qp->q_msg; - hp->rd = (qp->q_addr[0].forwarder ? 1 : 0); - qp->q_addr[0].stime = tt; - - schedretry(qp, retrytime(qp)); - - nsa = Q_NEXTADDR(qp, 0); - ns_debug(ns_log_default, 1, - "forw: forw -> [%s].%d ds=%d nsid=%d id=%d %dms retry %dsec", - inet_ntoa(nsa->sin_addr), - ntohs(nsa->sin_port), ds, - ntohs(qp->q_nsid), ntohs(qp->q_id), - (qp->q_addr[0].nsdata != NULL) - ? qp->q_addr[0].nsdata->d_nstime - : -1, - (int)(qp->q_time - tt.tv_sec)); - -#ifdef DEBUG - if (debug >= 10) - res_pquery(&res, msg, msglen, log_get_stream(packet_channel)); -#endif - key = tsig_key_from_addr(nsa->sin_addr); - if (key != NULL) { - smsgsize = qp->q_msglen + TSIG_BUF_SIZE; - smsg = memget(smsgsize); - if (smsg == NULL) - ns_panic(ns_log_default, 1, "ns_forw: memget failed"); - smsglen = qp->q_msglen; - siglen = sizeof(sig); - memcpy(smsg, qp->q_msg, qp->q_msglen); - n = ns_sign(smsg, &smsglen, smsgsize, NOERROR, key, NULL, 0, - sig, &siglen, 0); - if (n == 0) { - oldqbuf = qp->q_msg; - oldqlen = qp->q_msglen; - qp->q_msglen = smsglen; - qp->q_msg = smsg; - hp = (HEADER *) qp->q_msg; - has_tsig = 1; - qp->q_nstsig = new_tsig(key, sig, siglen); - } - else { - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - INSIST(0); - } - } - else { - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - } - - if (qp->q_flags & Q_USEVC) { - if (tcp_send(qp) != NOERROR) { - if (!haveComplained(ina_ulong(nsa->sin_addr), - (u_long)tcpsendStr)) - ns_info(ns_log_default, - "ns_forw: tcp_send(%s) failed: %s", - sin_ntoa(*nsa), strerror(errno)); - } - } else if (sendto(ds, (char *)qp->q_msg, qp->q_msglen, 0, - (struct sockaddr *)nsa, - sizeof(struct sockaddr_in)) < 0) { - sendto_errno = errno; - if (!haveComplained(ina_ulong(nsa->sin_addr), - (u_long)sendtoStr)) - ns_info(ns_log_default, "ns_forw: sendto(%s): %s", - sin_ntoa(*nsa), strerror(errno)); - nameserIncr(nsa->sin_addr, nssSendtoErr); - } - if (has_tsig == 1) { - memput(qp->q_msg, smsgsize); - qp->q_msg = oldqbuf; - qp->q_msglen = oldqlen; - hp = (HEADER *) qp->q_msg; - } - - nameserIncr(from.sin_addr, nssRcvdFwdQ); - nameserIncr(nsa->sin_addr, nssSentFwdQ); - if (qpp) - *qpp = qp; - hp->rd = 1; - switch (sendto_errno) { - case ENETDOWN: - case ENETUNREACH: - case EHOSTDOWN: - case EHOSTUNREACH: - unsched(qp); - schedretry(qp, (time_t) 0); - } - return (0); -} - -/* haveComplained(tag1, tag2) - * check to see if we have complained about (tag1,tag2) recently - * returns: - * boolean: have we complained recently? - * side-effects: - * outdated complaint records removed from our static list - * author: - * Paul Vixie (DECWRL) April 1991 - */ -int -haveComplained(u_long tag1, u_long tag2) { - struct complaint *cur, *next, *prev; - int r = 0; - - for (cur = complaints, prev = NULL; - cur != NULL; - prev = cur, cur = next) { - next = cur->next; - if (tt.tv_sec > cur->expire) { - if (prev) - prev->next = next; - else - complaints = next; - memput(cur, sizeof *cur); - cur = prev; - } else if (tag1 == cur->tag1 && tag2 == cur->tag2) - r++; - } - if (!r) { - cur = (struct complaint *)memget(sizeof(struct complaint)); - if (cur) { - cur->tag1 = tag1; - cur->tag2 = tag2; - cur->expire = tt.tv_sec + INIT_REFRESH; /* "10:00" */ - cur->next = NULL; - if (prev) - prev->next = cur; - else - complaints = cur; - } - } - return (r); -} - -void -freeComplaints(void) { - struct complaint *cur, *next; - - for (cur = complaints; cur != NULL; cur = next) { - next = cur->next; - memput(cur, sizeof *cur); - } - complaints = NULL; -} - -/* void - * nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr) - * Issue a complaint about a dangerous situation found by nslookup(). - * params: - * sysloginfo is a string identifying the complainant. - * queryname is the domain name associated with the problem. - * complaint is a string describing what is wrong. - * dname and a_rr are the problematic other name server. - */ -static void -nslookupComplain(const char *sysloginfo, const char *queryname, - const char *complaint, const char *dname, - const struct databuf *a_rr, const struct databuf *nsdp) -{ - char *a, *ns; - const char *a_type; - int print_a; - - ns_debug(ns_log_default, 2, "NS '%s' %s", dname, complaint); - if (sysloginfo && queryname && !haveComplained((u_long)queryname, - (u_long)complaint)) { - a = ns = (char *)NULL; - print_a = (a_rr->d_type == T_A); - a_type = p_type(a_rr->d_type); - if (a_rr->d_rcode) { - print_a = 0; - switch(a_rr->d_rcode) { - case NXDOMAIN: - a_type = "NXDOMAIN"; - break; - case NOERROR_NODATA: - a_type = "NODATA"; - break; - } - } - if (NS_OPTION_P(OPTION_HOSTSTATS)) { - char nsbuf[20], abuf[20]; - - if (nsdp != NULL) { - if (nsdp->d_ns != NULL) { - strcpy(nsbuf, - inet_ntoa(nsdp->d_ns->addr)); - ns = nsbuf; - } else { - ns = zones[nsdp->d_zone].z_origin; - } - } - if (a_rr->d_ns != NULL) { - strcpy(abuf, inet_ntoa(a_rr->d_ns->addr)); - a = abuf; - } else { - a = zones[a_rr->d_zone].z_origin; - } - } - if (a != NULL || ns != NULL) - ns_info(ns_log_default, - "%s: query(%s) %s (%s:%s) learnt (%s=%s:NS=%s)", - sysloginfo, queryname, - complaint, dname, - print_a ? - inet_ntoa(ina_get(a_rr->d_data)) : "", - a_type, - a ? a : "<Not Available>", - ns ? ns : "<Not Available>" ); - else - ns_info(ns_log_default, "%s: query(%s) %s (%s:%s)", - sysloginfo, queryname, - complaint, dname, - print_a ? - inet_ntoa(ina_get(a_rr->d_data)) : ""); - } -} - -/* - * nslookup(nsp, qp, syslogdname, sysloginfo) - * Lookup the address for each nameserver in `nsp' and add it to - * the list saved in the qinfo structure pointed to by `qp'. - * Omits information about nameservers that we shouldn't ask. - * Detects the following dangerous operations: - * One of the A records for one of the nameservers in nsp - * refers to the address of one of our own interfaces; - * One of the A records refers to the nameserver port on - * the host that asked us this question. - * returns: the number of addresses added, or -1 if a dangerous operation - * is detected. - * side effects: - * logs if a dangerous situation is detected and - * (syslogdname && sysloginfo) - */ -int -nslookup(struct databuf *nsp[], struct qinfo *qp, - const char *syslogdname, const char *sysloginfo) -{ - struct namebuf *np; - struct databuf *dp, *nsdp; - struct qserv *qs; - int n; - u_int i; - struct hashbuf *tmphtp; - char *dname; - const char *fname; - int oldn, naddr, class, found_arr, potential_ns, lame_ns; - time_t curtime; - - ns_debug(ns_log_default, 3, "nslookup(nsp=%#x, qp=%#x, \"%s\")", - nsp, qp, syslogdname); - - lame_ns = potential_ns = 0; - naddr = n = qp->q_naddr; - curtime = (u_long) tt.tv_sec; - while ((nsdp = *nsp++) != NULL && n < NSMAX) { - class = nsdp->d_class; - dname = (char *)nsdp->d_data; - ns_debug(ns_log_default, 3, - "nslookup: NS \"%s\" c=%d t=%d (flags 0x%lu)", - dname, class, nsdp->d_type, (u_long)nsdp->d_flags); - - /* don't put in servers we have tried */ - for (i = 0; i < qp->q_nusedns; i++) { - if (qp->q_usedns[i] == nsdp) { - ns_debug(ns_log_default, 2, - "skipping used NS w/name %s", - nsdp->d_data); - goto skipserver; - } - } - - /* skip lame servers */ - if ((nsdp->d_flags & DB_F_LAME) != 0) { - time_t when; - when = db_lame_find(qp->q_domain, nsdp); - if (when != 0 && when > tt.tv_sec) { - ns_debug(ns_log_default, 3, - "skipping lame NS"); - lame_ns++; - goto skipserver; - } - } - - tmphtp = ((nsdp->d_flags & DB_F_HINT) ?fcachetab :hashtab); - np = nlookup(dname, &tmphtp, &fname, 0); - if (np == NULL) { - ns_debug(ns_log_default, 3, "%s: not found %s %#x", - dname, fname, np); - found_arr = 0; - goto need_sysquery; - } - if (fname != dname) { - found_arr = 0; - goto need_sysquery; - } - found_arr = 0; - oldn = n; - - /* look for name server addresses */ - (void)delete_stale(np); - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - struct in_addr nsa; - - if (dp->d_type == T_CNAME && dp->d_class == class) { - static const char *complaint = - "NS points to CNAME"; - if (dp->d_rcode) - continue; - nslookupComplain(sysloginfo, syslogdname, - complaint, dname, dp, nsdp); - goto skipserver; - } - if (dp->d_type != T_A || dp->d_class != class) - continue; - if (dp->d_rcode) { - /* Negative caching element. */ - goto skipserver; - } - if (ina_hlong(ina_get(dp->d_data)) == INADDR_ANY) { - static const char *complaint = - "Bogus (0.0.0.0) A RR"; - nslookupComplain(sysloginfo, syslogdname, - complaint, dname, dp, nsdp); - continue; - } -#ifdef INADDR_LOOPBACK - if (ina_hlong(ina_get(dp->d_data))==INADDR_LOOPBACK) { - static const char *complaint = - "Bogus LOOPBACK A RR"; - nslookupComplain(sysloginfo, syslogdname, - complaint, dname, dp, nsdp); - continue; - } -#endif -#ifdef INADDR_BROADCAST - if (ina_hlong(ina_get(dp->d_data))==INADDR_BROADCAST){ - static const char *complaint = - "Bogus BROADCAST A RR"; - nslookupComplain(sysloginfo, syslogdname, - complaint, dname, dp, nsdp); - continue; - } -#endif -#ifdef IN_MULTICAST - if (IN_MULTICAST(ina_hlong(ina_get(dp->d_data)))) { - static const char *complaint = - "Bogus MULTICAST A RR"; - nslookupComplain(sysloginfo, syslogdname, - complaint, dname, dp, nsdp); - continue; - } -#endif - /* - * Don't use records that may become invalid to - * reference later when we do the rtt computation. - * Never delete our safety-belt information! - */ - if ((dp->d_zone == DB_Z_CACHE) && - (dp->d_ttl < (u_int32_t)curtime) && - !(dp->d_flags & DB_F_HINT) ) - { - ns_debug(ns_log_default, 1, - "nslookup: stale '%s'", - NAME(*np)); - n = oldn; - found_arr = 0; - goto need_sysquery; - } - - found_arr++; - nsa = ina_get(dp->d_data); - /* don't put in duplicates */ - qs = qp->q_addr; - for (i = 0; i < (u_int)n; i++, qs++) - if (ina_equal(qs->ns_addr.sin_addr, nsa)) - goto skipaddr; - qs->ns_addr.sin_family = AF_INET; - qs->ns_addr.sin_port = ns_port; - qs->ns_addr.sin_addr = nsa; - qs->ns = nsdp; - qs->nsdata = dp; - qs->forwarder = 0; - qs->nretry = 0; - /* - * If this A RR has no RTT, initialize its RTT to a - * small random value. - */ - if (dp->d_nstime == 0) - dp->d_nstime = 1 + - (int)(25.0*rand()/(RAND_MAX + 1.0)); - /* - * if we are being asked to fwd a query whose - * nameserver list includes our own name/address(es), - * then we have detected a lame delegation and rather - * than melt down the network and hose down the other - * servers (who will hose us in return), we'll return - * -1 here which will cause SERVFAIL to be sent to - * the client's resolver which will hopefully then - * shut up. - * - * (originally done in nsContainsUs by vix@dec mar92; - * moved into nslookup by apb@und jan1993) - * - * try to limp along instead of denying service - * gdonl mar96 - */ - if (aIsUs(nsa)) { - static char *complaint = "contains our address"; - nslookupComplain(sysloginfo, syslogdname, - complaint, dname, dp, nsdp); - continue; - } - /* - * If we want to forward to a host that asked us - * this question then either we or they are sick - * (unless they asked from some port other than - * their nameserver port). (apb@und jan1993) - * - * try to limp along instead of denying service - * gdonl mar96 - */ - if (memcmp(&qp->q_from, &qs->ns_addr, - sizeof(qp->q_from)) == 0) - { - static char *complaint = "forwarding loop"; - nslookupComplain(sysloginfo, syslogdname, - complaint, dname, dp, nsdp); - continue; - } -#ifdef BOGUSNS - /* - * Don't forward queries to bogus servers. Note - * that this is unlike the previous tests, which - * are fatal to the query. Here we just skip the - * server, which is only fatal if it's the last - * server. Note also that we antialias here -- all - * A RR's of a server are considered the same server, - * and if any of them is bogus we skip the whole - * server. Those of you using multiple A RR's to - * load-balance your servers will (rightfully) lose - * here. But (unfortunately) only if they are bogus. - */ - if (ip_match_address(bogus_nameservers, nsa) > 0) - goto skipserver; -#endif - if (server_options->blackhole_acl != NULL && - ip_match_address(server_options->blackhole_acl, - nsa) == 1) - continue; - - n++; - if (n >= NSMAX) - break; - skipaddr: - (void)NULL; - } - ns_debug(ns_log_default, 8, "nslookup: %d ns addrs", n); - need_sysquery: - if (found_arr == 0) { - potential_ns++; - if (!(qp->q_flags & Q_SYSTEM)) - (void) sysquery(dname, class, T_A, NULL, 0, - ns_port, QUERY); - } - skipserver: - (void)NULL; - } - out: - ns_debug(ns_log_default, 3, "nslookup: %d ns addrs total", n); - qp->q_naddr = n; - if (n == 0 && potential_ns == 0 && !NS_ZFWDTAB(qp->q_fzone)) { - static char *complaint = "No possible A RRs"; - if (lame_ns != 0) - complaint = "All possible A RR's lame"; - if (sysloginfo && syslogdname && - !haveComplained((u_long)syslogdname, (u_long)complaint)) - { - ns_info(ns_log_default, "%s: query(%s) %s", - sysloginfo, syslogdname, complaint); - } - return ((lame_ns == 0) ? -1 : -2); - } - /* Update the refcounts before the sort. */ - for (i = naddr; i < (u_int)n; i++) { - DRCNTINC(qp->q_addr[i].nsdata); - DRCNTINC(qp->q_addr[i].ns); - } - /* Just sort the NS RR's we added, since the forwarders may - * be ahead of us (naddr > 0) - */ - if (n > naddr) { - qsort((char *)(qp->q_addr+naddr), n-naddr, sizeof(struct qserv), - (int (*)(const void *, const void *))qcomp); - } - return (n - naddr); -} - -/* - * qcomp - compare two NS addresses, and return a negative, zero, or - * positive value depending on whether the first NS address is - * "better than", "equally good as", or "inferior to" the second - * NS address. - * - * How "goodness" is defined (for the purposes of this routine): - * - If the estimated round trip times differ by an amount deemed significant - * then the one with the smaller estimate is preferred; else - * - If we can determine which one is topologically closer then the - * closer one is preferred; else - * - The one with the smaller estimated round trip time is preferred - * (zero is returned if the two estimates are identical). - * - * How "topological closeness" is defined (for the purposes of this routine): - * Ideally, named could consult some magic map of the Internet and - * determine the length of the path to an arbitrary destination. Sadly, - * no such magic map exists. However, named does have a little bit of - * topological information in the form of the sortlist (which includes - * the directly connected subnet(s), the directly connected net(s), and - * any additional nets that the administrator has added using the "sortlist" - * directive in the bootfile. Thus, if only one of the addresses matches - * something in the sortlist then it is considered to be topologically - * closer. If both match, but match different entries in the sortlist, - * then the one that matches the entry closer to the beginning of the - * sorlist is considered to be topologically closer. In all other cases, - * topological closeness is ignored because it's either indeterminate or - * equal. - * - * How times are compared: - * Both times are rounded to the closest multiple of the NOISE constant - * defined below and then compared. If the rounded values are equal - * then the difference in the times is deemed insignificant. Rounding - * is used instead of merely taking the absolute value of the difference - * because doing the latter would make the ordering defined by this - * routine be incomplete in the mathematical sense (e.g. A > B and - * B > C would not imply A > C). The mathematics are important in - * practice to avoid core dumps in qsort(). - * - * XXX: this doesn't solve the European root nameserver problem very well. - * XXX: we should detect and mark as inferior nameservers that give bogus - * answers - * - * (this was originally vixie's stuff but almquist fixed fatal bugs in it - * and wrote the above documentation) - */ - -/* - * RTT delta deemed to be significant, in milliseconds. With the current - * definition of RTTROUND it must be a power of 2. - */ -#define NOISE 64 - -#define RTTROUND(rtt) (((rtt) + (NOISE >> 1)) & ~(NOISE - 1)) - -int -qcomp(struct qserv *qs1, struct qserv *qs2) { - u_int rtt1, rtt2, rttr1, rttr2; - - if (qs1->nsdata == NULL || qs2->nsdata == NULL) { - rtt1 = 0; - rttr1 = 0; - rtt2 = 0; - rttr2 = 0; - } else { - rtt1 = qs1->nsdata->d_nstime; - rttr1 = RTTROUND(rtt1); - rtt2 = qs2->nsdata->d_nstime; - rttr2 = RTTROUND(rtt2); - } - -#ifdef DEBUG - if (debug >= 10) { - char t[sizeof "255.255.255.255"]; - - strcpy(t, inet_ntoa(qs1->ns_addr.sin_addr)); - ns_debug(ns_log_default, 10, - "qcomp(%s, %s) %lu (%lu) - %lu (%lu) = %lu", - t, inet_ntoa(qs2->ns_addr.sin_addr), - rtt1, rttr1, rtt2, rttr2, rtt1 - rtt2); - } -#endif - if (rttr1 == rttr2) { - int pos1, pos2, pdiff; - - pos1 = distance_of_address(server_options->topology, - qs1->ns_addr.sin_addr); - pos2 = distance_of_address(server_options->topology, - qs2->ns_addr.sin_addr); - pdiff = pos1 - pos2; - ns_debug(ns_log_default, 10, "\tpos1=%d, pos2=%d", pos1, pos2); - if (pdiff != 0) - return (pdiff); - } - return (rtt1 - rtt2); -} -#undef RTTROUND - -/* - * Arrange that forwarded query (qp) is retried after t seconds. - * Query list will be sorted after z_time is updated. - */ -void -schedretry(struct qinfo *qp, time_t t) { - struct qinfo *qp1, *qp2; - - ns_debug(ns_log_default, 4, "schedretry(%#x, %ld sec)", qp, (long)t); - if (qp->q_time) - ns_debug(ns_log_default, 4, - "WARNING: schedretry(%#lx, %ld) q_time already %ld", - (u_long)qp, (long)t, (long)qp->q_time); - gettime(&tt); - t += (u_long) tt.tv_sec; - qp->q_time = t; - - if ((qp1 = retryqp) == NULL) { - retryqp = qp; - qp->q_next = NULL; - goto done; - } - if (t < qp1->q_time) { - qp->q_next = qp1; - retryqp = qp; - goto done; - } - while ((qp2 = qp1->q_next) != NULL && qp2->q_time < t) - qp1 = qp2; - qp1->q_next = qp; - qp->q_next = qp2; - done: - reset_retrytimer(); -} - -/* - * Unsched is called to remove a forwarded query entry. - */ -void -unsched(struct qinfo *qp) { - struct qinfo *np; - - ns_debug(ns_log_default, 3, "unsched(%#lx, %d)", - (u_long)qp, ntohs(qp->q_id)); - if (retryqp == qp) { - retryqp = qp->q_next; - } else { - for (np = retryqp; np->q_next != NULL; np = np->q_next) { - if (np->q_next != qp) - continue; - np->q_next = qp->q_next; /* dequeue */ - break; - } - } - qp->q_next = NULL; /* sanity check */ - qp->q_time = 0; - reset_retrytimer(); -} - -void -reset_retrytimer() { - static evTimerID id; - - if (retry_timer_set) { - (void) evClearTimer(ev, id); - retry_timer_set = 0; - } - - if (retryqp) { - evSetTimer(ev, retrytimer, NULL, - evConsTime(retryqp->q_time, 0), - evConsTime(0, 0), &id); - retry_timer_set = 1; - } else - memset(&id, 0, sizeof id); -} - -void -retrytimer(evContext ctx, void *uap, struct timespec due, - struct timespec ival) { - retry_timer_set = 0; - retry(retryqp); -} - -/* - * Retry is called to retransmit query 'qp'. - */ -void -retry(struct qinfo *qp) { - int n, has_tsig, oldqlen; - HEADER *hp; - struct sockaddr_in *nsa; - int sendto_errno = 0; - u_char *oldqbuf; - u_char *smsg; - int smsglen, smsgsize, siglen; - u_char sig[TSIG_SIG_SIZE]; - DST_KEY *key; - - ns_debug(ns_log_default, 3, "retry(%#lx) id=%d", (u_long)qp, - ntohs(qp->q_id)); - - if (qp->q_msg == NULL) { - qremove(qp); - return; - } - - if (qp->q_expire < tt.tv_sec) { - ns_debug(ns_log_default, 1, - "retry(%#lx): expired @ %lu (%d secs before now (%lu))", - (u_long)qp, (u_long)qp->q_expire, - (int)(tt.tv_sec - qp->q_expire), - (u_long)tt.tv_sec); - goto fail; - } - - /* Try next address. */ - n = qp->q_curaddr; - if (qp->q_naddr > 0) { - ++qp->q_addr[n].nretry; - do { - if (++n >= (int)qp->q_naddr) - n = 0; - if ((qp->q_flags & Q_ZSERIAL) != 0 && - qp->q_addr[n].serial != 0) - continue; - if (qp->q_addr[n].nretry < MAXRETRY) - goto found; - } while (n != qp->q_curaddr); - if ((qp->q_flags & Q_ZSERIAL) != 0) { - qremove(qp); - return; - } - } - fail: - /* - * Give up. Can't reach destination. - */ - hp = (HEADER *)(qp->q_cmsg ? qp->q_cmsg : qp->q_msg); - if ((qp->q_flags & Q_PRIMING) != 0) { - /* Can't give up priming */ - if (qp->q_expire < tt.tv_sec) { - /* - * The query has expired. Reset it and retry from - * the beginning. - */ - hp->rcode = NOERROR; - hp->qr = hp->aa = 0; - for (n = 0; n < (int)qp->q_naddr; n++) - qp->q_addr[n].nretry = 0; - n = 0; - qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2; - goto found; - } - /* - * The query hasn't expired yet; it probably ran out - * of servers or forwarders. Wait up to 60 seconds - * past the expire time. - */ - unsched(qp); - schedretry(qp, (time_t)(qp->q_expire - tt.tv_sec + 60)); - return; - } - ns_debug(ns_log_default, 5, "give up"); - if ((qp->q_flags & Q_SYSTEM) == 0) { - n = ((HEADER *)qp->q_cmsg ? qp->q_cmsglen : qp->q_msglen); - hp->id = qp->q_id; - hp->qr = 1; - hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0); - hp->rd = 1; - hp->rcode = SERVFAIL; -#ifdef DEBUG - if (debug >= 10) - res_pquery(&res, qp->q_msg, n, - log_get_stream(packet_channel)); -#endif - if (send_msg((u_char *)hp, n, qp)) { - ns_debug(ns_log_default, 1, - "gave up retry(%#lx) nsid=%d id=%d", - (u_long)qp, - ntohs(qp->q_nsid), ntohs(qp->q_id)); - } - if (NS_OPTION_P(OPTION_HOSTSTATS)) - nameserIncr(qp->q_from.sin_addr, nssSentFail); - } - qremove(qp); - return; - - found: - if (qp->q_addr[n].nretry == 0) - qp->q_addr[n].stime = tt; - qp->q_curaddr = n; - hp = (HEADER *)qp->q_msg; - hp->rd = (qp->q_addr[n].forwarder ? 1 : 0); - nsa = Q_NEXTADDR(qp, n); - ns_debug(ns_log_default, 1, - "%s(addr=%d n=%d) -> [%s].%d ds=%d nsid=%d id=%d %dms", - (qp->q_addr[n].forwarder ? "reforw" : "resend"), - n, qp->q_addr[n].nretry, - inet_ntoa(nsa->sin_addr), - ntohs(nsa->sin_port), ds, - ntohs(qp->q_nsid), ntohs(qp->q_id), - (qp->q_addr[n].nsdata != 0) - ? qp->q_addr[n].nsdata->d_nstime - : (-1)); -#ifdef DEBUG - if (debug >= 10) - res_pquery(&res, qp->q_msg, qp->q_msglen, - log_get_stream(packet_channel)); -#endif - key = tsig_key_from_addr(nsa->sin_addr); - if (key != NULL) { - smsgsize = qp->q_msglen + TSIG_BUF_SIZE; - smsg = memget(smsgsize); - smsglen = qp->q_msglen; - siglen = sizeof(sig); - memcpy(smsg, qp->q_msg, qp->q_msglen); - n = ns_sign(smsg, &smsglen, smsgsize, NOERROR, key, NULL, 0, - sig, &siglen, 0); - if (n == 0) { - oldqbuf = qp->q_msg; - oldqlen = qp->q_msglen; - qp->q_msglen = smsglen; - qp->q_msg = smsg; - has_tsig = 1; - qp->q_nstsig = new_tsig(key, sig, siglen); - } - else { - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - INSIST(0); - } - } else { - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - } - - if (qp->q_flags & Q_USEVC) { - if (tcp_send(qp) != NOERROR) - ns_debug(ns_log_default, 3, - "error resending tcp msg: %s", - strerror(errno)); - } else if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0, - (struct sockaddr *)nsa, - sizeof(struct sockaddr_in)) < 0) - { - sendto_errno = errno; - ns_debug(ns_log_default, 3, "error resending msg: %s", - strerror(errno)); - } - if (has_tsig == 1) { - memput(qp->q_msg, smsgsize); - qp->q_msg = oldqbuf; - qp->q_msglen = oldqlen; - } - hp->rd = 1; /* leave set to 1 for dup detection */ - nameserIncr(nsa->sin_addr, nssSentDupQ); - unsched(qp); - switch (sendto_errno) { - case ENETDOWN: - case ENETUNREACH: - case EHOSTDOWN: - case EHOSTUNREACH: - schedretry(qp, (time_t) 0); - return; - } - schedretry(qp, retrytime(qp)); -} - -/* - * Compute retry time for the next server for a query. - * Use a minimum time of RETRYBASE (4 sec.) or twice the estimated - * service time; * back off exponentially on retries, but place a 45-sec. - * ceiling on retry times for now. (This is because we don't hold a reference - * on servers or their addresses, and we have to finish before they time out.) - */ -time_t -retrytime(struct qinfo *qp) { - time_t t, u, v; - struct qserv *ns = &qp->q_addr[qp->q_curaddr]; - - if (ns->nsdata != NULL) - t = (time_t) MAX(RETRYBASE, 2 * ns->nsdata->d_nstime / 1000); - else - t = (time_t) RETRYBASE; - u = t << ns->nretry; - v = MIN(u, RETRY_TIMEOUT); /* max. retry timeout for now */ - ns_debug(ns_log_default, 3, - "retrytime: nstime%ldms t%ld nretry%ld u%ld : v%ld", - ns->nsdata ? (long)(ns->nsdata->d_nstime / 1000) : (long)-1, - (long)t, (long)ns->nretry, (long)u, (long)v); - return (v); -} - -void -qflush() { - while (nsqhead) - qremove(nsqhead); - nsqhead = NULL; - priming = 0; -} - -void -qremove(struct qinfo *qp) { - ns_debug(ns_log_default, 3, "qremove(%#lx)", (u_long)qp); - - if ((qp->q_flags & Q_ZSERIAL) != 0) - qserial_answer(qp); - unsched(qp); - ns_freeqry(qp); -} - -struct qinfo * -qfindid(u_int16_t id) { - struct qinfo *qp; - - for (qp = nsqhead; qp != NULL; qp = qp->q_link) - if (qp->q_nsid == id) - break; - ns_debug(ns_log_default, 3, "qfindid(%d) -> %#lx", ntohs(id), - (u_long)qp); - return (qp); -} - -struct qinfo * -qnew(const char *name, int class, int type, int forward) { - struct qinfo *qp; - const char *s; - int escape = 0; - - qp = (struct qinfo *)memget(sizeof *qp); - if (qp == NULL) - ns_panic(ns_log_default, 1, "qnew: memget failed"); - memset(qp, 0, sizeof *qp); - ns_debug(ns_log_default, 5, "qnew(%#lx)", (u_long)qp); -#ifdef BIND_NOTIFY - qp->q_notifyzone = DB_Z_CACHE; -#endif - qp->q_link = nsqhead; - nsqhead = qp; - qp->q_name = savestr(name, 1); - qp->q_class = (u_int16_t)class; - qp->q_type = (u_int16_t)type; - qp->q_flags = 0; - s = name; - qp->q_fzone = NULL; - for (;forward;) { /* find forwarding zone, if any */ - if ((qp->q_fzone = find_zone(s, class)) != NULL && - (qp->q_fzone->z_flags & Z_FORWARD_SET) != 0) - break; - qp->q_fzone = NULL; - if (*s == '\0') - break; - while (*s != '\0' && (escape || *s != '.')) { - escape = escape ? 0 : (*s == '\\'); - s++; - } - if (*s != '\0') - s++; - } - return (qp); -} - -void -ns_freeqns(struct qinfo *qp, char *where) { - static const char freed[] = "freed", busy[] = "busy"; - const char *result; - struct databuf *dp; - int i; - - for (i = 0 ; i < (int)qp->q_naddr ; i++) { - dp = qp->q_addr[i].ns; - if (dp) { - DRCNTDEC(dp); - result = (dp->d_rcnt) ? busy : freed; - ns_debug(ns_log_default, 3, "%s: ns %s rcnt %d (%s)", - where, dp->d_data, dp->d_rcnt, result); - if (result == freed) - db_freedata(dp); - } - dp = qp->q_addr[i].nsdata; - if (dp) { - DRCNTDEC(dp); - result = (dp->d_rcnt) ? busy : freed; - ns_debug(ns_log_default, 3, - "%s: nsdata %s rcnt %d (%s)", - where, inet_ntoa(ina_get(dp->d_data)), - dp->d_rcnt, result); - if (result == freed) - db_freedata(dp); - } - } -} - -void -ns_freeqry(struct qinfo *qp) { - struct qinfo *np; - - ns_debug(ns_log_default, 3, "ns_freeqry(%#lx)", (u_long)qp); - if (qp->q_next) - ns_debug(ns_log_default, 1, - "WARNING: ns_freeqry of linked ptr %#lx", (u_long)qp); - if (qp->q_msg != NULL) - memput(qp->q_msg, qp->q_msgsize); - if (qp->q_cmsg != NULL) - memput(qp->q_cmsg, qp->q_cmsgsize); - if (qp->q_domain != NULL) - freestr(qp->q_domain); - if (qp->q_name != NULL) - freestr(qp->q_name); - if (qp->q_tsig != NULL) - memput(qp->q_tsig, sizeof(struct tsig_record)); - if (qp->q_nstsig != NULL) - memput(qp->q_nstsig, sizeof(struct tsig_record)); - ns_freeqns(qp, "ns_freeqry"); - if (nsqhead == qp) - nsqhead = qp->q_link; - else { - for(np = nsqhead; - np->q_link != NULL; - np = np->q_link) { - if (np->q_link != qp) - continue; - np->q_link = qp->q_link; /* dequeue */ - break; - } - } - memput(qp, sizeof *qp); -} - -void -nsfwdadd(struct qinfo *qp, struct fwdinfo *fwd) { - int i, n; - struct qserv *qs; - - n = qp->q_naddr; - while (fwd != NULL && n < NSMAX) { - qs = qp->q_addr; - for (i = 0; i < (u_int)n; i++, qs++) - if (ina_equal(qs->ns_addr.sin_addr, - fwd->fwddata->fwdaddr.sin_addr)) - goto nextfwd; - qs->ns_addr = fwd->fwddata->fwdaddr; - qs->ns = fwd->fwddata->ns; - qs->nsdata = fwd->fwddata->nsdata; - qs->forwarder = 1; - qs->nretry = 0; - n++; - nextfwd: - fwd = fwd->next; - } - qp->q_naddr = n; - - /* Update the refcounts before the sort. */ - for (i = 0; i < (u_int)n; i++) { - DRCNTINC(qp->q_addr[i].nsdata); - DRCNTINC(qp->q_addr[i].ns); - } - if (n > 1) { - qsort((char *)qp->q_addr, n, sizeof(struct qserv), - (int (*)(const void *, const void *))qcomp); - } -} diff --git a/contrib/bind/bin/named/ns_func.h b/contrib/bind/bin/named/ns_func.h deleted file mode 100644 index 760266d3ff719..0000000000000 --- a/contrib/bind/bin/named/ns_func.h +++ /dev/null @@ -1,503 +0,0 @@ -/* - * Copyright (c) 1985, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Check Point Software Technologies Incorporated not be used - * in advertising or publicity pertaining to distribution of the document - * or software without specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND CHECK POINT SOFTWARE TECHNOLOGIES - * INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL CHECK POINT SOFTWARE TECHNOLOGIES INCORPRATED - * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* ns_func.h - declarations for ns_*.c's externally visible functions - * - * $Id: ns_func.h,v 8.96 2000/04/21 06:54:06 vixie Exp $ - */ - -/* ++from ns_glue.c++ */ -extern struct in_addr ina_get(const u_char *data); -extern const char *sin_ntoa(struct sockaddr_in); -extern int ns_wouldlog(int category, int level); -extern void ns_debug(int, int, const char *, ...), - ns_info(int, const char *, ...), - ns_notice(int, const char *, ...), - ns_warning(int, const char *, ...), - ns_error(int, const char *, ...), - ns_panic(int, int, const char *, ...), - ns_assertion_failed(char *file, int line, - assertion_type type, char *cond, - int print_errno); -extern void panic(const char *, const void *), - gettime(struct timeval *); -extern int nlabels(const char *), - my_close(int), - my_fclose(FILE *); -extern void __freestr(char *); -extern char *__newstr(size_t, int), - *__savestr(const char *, int), - *checked_ctime(const time_t *t), - *ctimel(long); -extern void __freestr_record(char *, char *, int); -extern char *__newstr_record(size_t, int, char *, int); -extern char *__savestr_record(const char *, int, char *, int); -extern u_char *ina_put(struct in_addr ina, u_char *data), - *savebuf(const u_char *, size_t, int); -extern void dprintf(int level, const char *format, ...); -#ifdef DEBUG_STRINGS -extern char *debug_newstr(size_t, int, const char *, int), - *debug_savestr(const char *, int, const char *, int); -extern void debug_freestr(char *, const char *, int); -#define newstr(l, n) debug_newstr((l), (n), __FILE__, __LINE__) -#define savestr(s, n) debug_savestr((s), (n), __FILE__, __LINE__) -#define freestr(s) debug_freestr((s), __FILE__, __LINE__) -#else -#ifdef RECORD_STRINGS -#define newstr(l, n) __newstr_record((l), (n), __FILE__, __LINE__) -#define savestr(s, n) __savestr_record((s), (n), __FILE__, __LINE__) -#define freestr(s) __freestr_record((s), __FILE__, __LINE__) -#else -#define newstr(l, n) __newstr((l), (n)) -#define savestr(s, n) __savestr((s), (n)) -#define freestr(s) __freestr((s)) -#endif -#endif /* DEBUG_STRINGS */ -int movefile(const char *, const char *); -/* --from ns_glue.c-- */ - -/* ++from ns_notify.c++ */ -#ifdef BIND_NOTIFY -void ns_notify(const char *, ns_class, ns_type); -void notify_afterload(void); -void ns_unnotify(void); -void ns_stopnotify(const char *, ns_class); -#endif -/* --from ns_notify.c-- */ - -/* ++from ns_resp.c++ */ -extern void ns_resp(u_char *, int, struct sockaddr_in, - struct qstream *), - prime_cache(void), - delete_all(struct namebuf *, int, int); -extern int delete_stale(struct namebuf *); -extern struct qinfo *sysquery(const char *, int, int, - struct in_addr *, int, u_int16_t, int); -extern int doupdate(u_char *, u_char *, struct databuf **, - int, int, int, u_int, struct sockaddr_in), - send_msg(u_char *, int, struct qinfo *), - findns(struct namebuf **, int, - struct databuf **, int *, int), - finddata(struct namebuf *, int, int, HEADER *, - char **, int *, int *), - add_data(struct namebuf *, - struct databuf **, - u_char *, int, int *), - trunc_adjust(u_char *, int, int); -/* --from ns_resp.c-- */ - -/* ++from ns_req.c++ */ -extern void ns_req(u_char *, int, int, - struct qstream *, - struct sockaddr_in, - int), - free_addinfo(void), - free_nsp(struct databuf **); -extern int stale(struct databuf *), - make_rr(const char *, struct databuf *, - u_char *, int, int, - u_char **, u_char **, int), - doaddinfo(HEADER *, u_char *, int), - doaddauth(HEADER *, u_char *, int, - struct namebuf *, - struct databuf *); -#ifdef BIND_NOTIFY -extern int findZonePri(const struct zoneinfo *, - const struct sockaddr_in); -#endif -/* --from ns_req.c-- */ - -/* ++from ns_xfr.c++ */ -void ns_xfr(struct qstream *qsp, struct namebuf *znp, - int zone, int class, int type, - int id, int opcode, u_int32_t serial_ixfr, - struct tsig_record *in_tsig), - ns_stopxfrs(struct zoneinfo *), - ns_freexfr(struct qstream *), - sx_newmsg(struct qstream *qsp), - sx_sendlev(struct qstream *qsp), - sx_sendsoa(struct qstream *qsp); -/* --from ns_xfr.c-- */ - -/* ++from ns_ctl.c++ */ -void ns_ctl_initialize(void); -void ns_ctl_shutdown(void); -void ns_ctl_defaults(controls *); -void ns_ctl_add(controls *, control); -control ns_ctl_new_inet(struct in_addr, u_int, ip_match_list); -#ifndef WINNT -control ns_ctl_new_unix(char *, mode_t, uid_t, gid_t); -#endif -void ns_ctl_install(controls *); -/* --from ns_ctl.c-- */ - -/* ++from ns_ixfr.c++ */ -void sx_send_ixfr(struct qstream *qsp); -/* --from ns_ixfr.c-- */ - -/* ++from ns_forw.c++ */ -extern time_t retrytime(struct qinfo *); -extern int ns_forw(struct databuf *nsp[], - u_char *msg, - int msglen, - struct sockaddr_in from, - struct qstream *qsp, - int dfd, - struct qinfo **qpp, - const char *dname, - int class, - int type, - struct namebuf *np, - int use_tcp, - struct tsig_record *in_tsig), - haveComplained(u_long, u_long), - nslookup(struct databuf *nsp[], - struct qinfo *qp, - const char *syslogdname, - const char *sysloginfo), - qcomp(struct qserv *, struct qserv *); -extern void schedretry(struct qinfo *, time_t), - unsched(struct qinfo *), - reset_retrytimer(void), - retrytimer(evContext ctx, void *uap, - struct timespec due, struct timespec ival), - retry(struct qinfo *), - qflush(void), - qremove(struct qinfo *), - ns_freeqns(struct qinfo *, char *), - ns_freeqry(struct qinfo *), - freeComplaints(void), - nsfwdadd(struct qinfo *, struct fwdinfo *); -extern struct qinfo *qfindid(u_int16_t), - *qnew(const char *, int, int, int); -/* --from ns_forw.c-- */ - -/* ++from ns_main.c++ */ -extern struct in_addr net_mask(struct in_addr); -extern void sq_remove(struct qstream *), - sq_flushw(struct qstream *), - sq_flush(struct qstream *allbut), - dq_remove_gen(time_t gen), - dq_remove_all(), - sq_done(struct qstream *), - ns_setproctitle(char *, int), - getnetconf(int), - nsid_init(void), - ns_setoption(int option), - writestream(struct qstream *, const u_char *, int), - ns_need_unsafe(enum need), - ns_need(enum need), - opensocket_f(void), - nsid_hash(u_char *, size_t); -extern u_int16_t nsid_next(void); -extern int sq_openw(struct qstream *, int), - sq_writeh(struct qstream *, sq_closure), - sq_write(struct qstream *, const u_char *, int), - tcp_send(struct qinfo *), - aIsUs(struct in_addr); -/* --from ns_main.c-- */ - -/* ++from ns_maint.c++ */ -extern void zone_maint(struct zoneinfo *), - sched_zone_maint(struct zoneinfo *), - ns_cleancache(evContext ctx, void *uap, - struct timespec due, - struct timespec inter), - clean_cache_from(char *dname, struct hashbuf *htp), - remove_zone(struct zoneinfo *, const char *), - purge_zone(const char *, struct hashbuf *, int), - loadxfer(void), - qserial_retrytime(struct zoneinfo *, time_t), - qserial_query(struct zoneinfo *), - qserial_answer(struct qinfo *), -#ifdef DEBUG - printzoneinfo(int, int, int), -#endif - endxfer(void), - addxfer(struct zoneinfo *), - ns_zreload(void), - ns_reload(void), - ns_reconfig(void), - ns_noexpired(void); -#if 0 -extern int reload_all_unsafe(void); -#endif -extern int zonefile_changed_p(struct zoneinfo *); -int reload_master(struct zoneinfo *); -extern const char * deferred_reload_unsafe(struct zoneinfo *); -extern struct namebuf * purge_node(struct hashbuf *htp, struct namebuf *np); -extern int clean_cache(struct hashbuf *, int); -extern void reapchild(void); -extern const char * zoneTypeString(unsigned int); -extern void ns_heartbeat(evContext ctx, void *uap, - struct timespec, struct timespec); -extern void make_new_zones(void); -extern void free_zone(struct zoneinfo *); -extern struct zoneinfo *find_auth_zone(const char *, ns_class); -extern int purge_nonglue(const char *dname, struct hashbuf *htp, - int class); -/* --from ns_maint.c-- */ - -/* ++from ns_sort.c++ */ -extern void sort_response(u_char *, u_char *, int, - struct sockaddr_in *); -/* --from ns_sort.c-- */ - -/* ++from ns_init.c++ */ -extern void ns_refreshtime(struct zoneinfo *, time_t); -extern void ns_retrytime(struct zoneinfo *, time_t); -extern void ns_init(const char *); -extern void purgeandload(struct zoneinfo *zp); -extern enum context ns_ptrcontext(const char *owner); -extern enum context ns_ownercontext(int type, enum transport); -extern int ns_nameok(const struct qinfo *qry, const char *name, - int class, struct zoneinfo *zp, - enum transport, enum context, - const char *owner, - struct in_addr source); -extern int ns_wildcard(const char *name); -extern void zoneinit(struct zoneinfo *); -extern void do_reload(const char *, int, int, int); -extern void ns_shutdown(void); -/* --from ns_init.c-- */ - -/* ++from ns_ncache.c++ */ -extern void cache_n_resp(u_char *, int, struct sockaddr_in, - const char *, int, int); -/* --from ns_ncache.c-- */ - -/* ++from ns_udp.c++ */ -extern void ns_udp(void); -/* --from ns_udp.c-- */ - -/* ++from ns_stats.c++ */ -extern void ns_stats(void), - ns_freestats(void); -extern void ns_logstats(evContext ctx, void *uap, - struct timespec, struct timespec); -extern void qtypeIncr(int qtype); -extern struct nameser *nameserFind(struct in_addr addr, int flags); -#define NS_F_INSERT 0x0001 -#define nameserIncr(a,w) NS_INCRSTAT(a,w) /* XXX should change name. */ -/* --from ns_stats.c-- */ - -/* ++from ns_update.c++ */ -void free_rrecp(ns_updque *, int rcode, struct sockaddr_in); -int findzone(const char *, int, int, int *, int); -u_char * findsoaserial(u_char *data); -u_int32_t get_serial_unchecked(struct zoneinfo *zp); -u_int32_t get_serial(struct zoneinfo *zp); -void set_serial(struct zoneinfo *zp, u_int32_t serial); -int schedule_soa_update(struct zoneinfo *, int); -int schedule_dump(struct zoneinfo *); -int incr_serial(struct zoneinfo *zp); -int merge_logs(struct zoneinfo *zp, char *logname); -int zonedump(struct zoneinfo *zp, int isixfr); -void dynamic_about_to_exit(void); -enum req_action req_update(HEADER *hp, u_char *cp, u_char *eom, - u_char *msg, struct qstream *qsp, - int dfd, struct sockaddr_in from, - struct tsig_record *in_tsig); -void rdata_dump(struct databuf *dp, FILE *fp); -/* --from ns_update.c-- */ - -/* ++from ns_config.c++ */ -void free_zone_timerinfo(struct zoneinfo *); -void free_zone_contents(struct zoneinfo *, int); -struct zoneinfo * find_zone(const char *, int); -zone_config begin_zone(char *, int); -void end_zone(zone_config, int); -int set_zone_type(zone_config, int); -int set_zone_filename(zone_config, char *); -int set_zone_checknames(zone_config, enum severity); -#ifdef BIND_NOTIFY -int set_zone_notify(zone_config, int value); -#endif -int set_zone_maintain_ixfr_base(zone_config, int value); -int set_zone_update_acl(zone_config, ip_match_list); -int set_zone_query_acl(zone_config, ip_match_list); -int set_zone_transfer_acl(zone_config, ip_match_list); -int set_zone_transfer_source(zone_config, struct in_addr); -int set_zone_pubkey(zone_config, const int, const int, - const int, const char *); -int set_zone_transfer_time_in(zone_config, long); -int add_zone_master(zone_config, struct in_addr); -#ifdef BIND_NOTIFY -int add_zone_notify(zone_config, struct in_addr); -#endif -void set_zone_forward(zone_config); -void add_zone_forwarder(zone_config, struct in_addr); -void set_zone_boolean_option(zone_config, int, int); -options new_options(void); -void free_options(options); -void free_rrset_order_list(rrset_order_list); -void set_global_boolean_option(options, int, int); -listen_info_list new_listen_info_list(void); -void free_listen_info_list(listen_info_list); -void add_listen_on(options, u_short, ip_match_list); -FILE * write_open(char *filename); -void update_pid_file(void); -void set_options(options, int); -void use_default_options(void); -enum ordering lookup_ordering(const char *); -rrset_order_list new_rrset_order_list(void); -rrset_order_element new_rrset_order_element(int, int, char *, enum ordering); -ip_match_list new_ip_match_list(void); -void free_ip_match_list(ip_match_list); -ip_match_element new_ip_match_pattern(struct in_addr, u_int); -ip_match_element new_ip_match_mask(struct in_addr, struct in_addr); -ip_match_element new_ip_match_indirect(ip_match_list); -ip_match_element new_ip_match_key(struct dst_key *dst_key); -ip_match_element new_ip_match_localhost(void); -ip_match_element new_ip_match_localnets(void); -void ip_match_negate(ip_match_element); -void add_to_ip_match_list(ip_match_list, ip_match_element); -void dprint_ip_match_list(int, ip_match_list, int, char *, - char *); -int ip_match_address(ip_match_list, struct in_addr); -int ip_match_addr_or_key(ip_match_list, struct in_addr, - struct dst_key *key); -int ip_address_allowed(ip_match_list, struct in_addr); -int ip_addr_or_key_allowed(ip_match_list iml, - struct in_addr, - struct dst_key *key); -int ip_match_network(ip_match_list, struct in_addr, - struct in_addr); -int ip_match_key_name(ip_match_list iml, char *name); -int distance_of_address(ip_match_list, struct in_addr); -int ip_match_is_none(ip_match_list); -#ifdef BIND_NOTIFY -void free_also_notify(options); -int add_global_also_notify(options, struct in_addr); -#endif -void add_global_forwarder(options, struct in_addr); -void free_forwarders(struct fwdinfo *); -server_info find_server(struct in_addr); -server_config begin_server(struct in_addr); -void end_server(server_config, int); -void set_server_option(server_config, int, int); -void set_server_transfers(server_config, int); -void set_server_transfer_format(server_config, - enum axfr_format); -void add_server_key_info(server_config, struct dst_key *); -struct dst_key *new_key_info(char *, char *, char *); -void free_key_info(struct dst_key *); -struct dst_key *find_key(char *name, char *algorithm); -void dprint_key_info(struct dst_key *); -key_info_list new_key_info_list(void); -void free_key_info_list(key_info_list); -void add_to_key_info_list(key_info_list, struct dst_key *); -void dprint_key_info_list(key_info_list); -log_config begin_logging(void); -void add_log_channel(log_config, int, log_channel); -void open_special_channels(void); -void set_logging(log_config, int); -void end_logging(log_config, int); -void use_default_logging(void); -void init_logging(void); -void shutdown_logging(void); -void init_configuration(void); -void shutdown_configuration(void); -void load_configuration(const char *); -/* --from ns_config.c-- */ -/* ++from parser.y++ */ -ip_match_list lookup_acl(char *); -void define_acl(char *, ip_match_list); -struct dst_key *lookup_key(char *); -void define_key(char *, struct dst_key *); -void parse_configuration(const char *); -void parser_initialize(void); -void parser_shutdown(void); -/* --from parser.y-- */ -/* ++from ns_signal.c++ */ -void init_signals(void); -void block_signals(void); -void unblock_signals(void); -/* --from ns_signal.c-- */ diff --git a/contrib/bind/bin/named/ns_glob.h b/contrib/bind/bin/named/ns_glob.h deleted file mode 100644 index e9f70e7685678..0000000000000 --- a/contrib/bind/bin/named/ns_glob.h +++ /dev/null @@ -1,341 +0,0 @@ -/* - * from ns.h 4.33 (Berkeley) 8/23/90 - * $Id: ns_glob.h,v 8.55 2000/07/20 22:50:38 vixie Exp $ - */ - -/* - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Global variables for the name server. - */ - - /* original argv[] from main() */ -DECL char **saved_argv; - -#ifdef DEBUG -DECL int debug INIT(0); -DECL int desired_debug INIT(0); -#endif - - /* global event context */ -DECL evContext ev; - - /* global resolver context. */ -DECL struct __res_state res; - - /* list of open streams */ -DECL struct qstream *streamq; - - /* often set to the current time */ -DECL struct timeval tt; - - /* head of allocated queries */ -DECL struct qinfo *nsqhead; - - /* datagram socket for sysquery() and ns_forw(). */ -DECL int ds INIT(-1); - - /* event ID for reads of "ds". */ -DECL evFileID ds_evID; - -#ifdef QRYLOG - /* is query logging turned on? */ -DECL int qrylog; -#endif /*QRYLOG*/ - - /* port to which we send queries */ -DECL u_int16_t ns_port; - - /* Source addr of our internal resolver. */ -DECL struct sockaddr_in source_addr; /* INITs to <INADDR_ANY, 0>. */ - - /* Used by ns_stats */ -DECL time_t boottime; - -DECL time_t resettime; - - /* next query to retry */ -DECL struct qinfo *retryqp; - - /* default configuration file */ -DECL char *conffile; - - /* default debug output file */ -DECL char *debugfile; - - /* zone information */ -DECL struct zoneinfo *zones; - - /* number of zones allocated */ -DECL int nzones; - - /* free list of unused zones[] elements. */ -DECL LIST(struct zoneinfo) freezones; - - /* list of zones that have a reload pending. */ -DECL LIST(struct zoneinfo) reloadingzones; - - /* set if we need a priming */ -DECL int needs_prime_cache; - - /* is cache being primed */ -DECL int priming; - - /* ptrs to dnames in msg for dn_comp */ -DECL u_char *dnptrs[40]; - - /* end pointer for dnptrs */ -DECL u_char **dnptrs_end - INIT(dnptrs + sizeof dnptrs / sizeof(u_char*)); - - /* data about all forwarders */ -DECL struct fwddata **fwddata; - /* how many forwarders are there in fwddata? */ -DECL int fwddata_count; - - /* number of names in addinfo */ -DECL int addcount; - - /* name of cache file */ -DECL const char *cache_file; - -#ifdef BIND_UPDATE -DECL const char * LogSignature INIT(";BIND LOG V8\n"); -DECL const char * DumpSignature INIT(";BIND DUMP V8\n"); -DECL const char * DumpSuffix INIT(".dumptmp"); -#endif - -DECL const char sendtoStr[] INIT("sendto"); -DECL const char tcpsendStr[] INIT("tcp_send"); - - /* defined in version.c, can't use DECL/INIT */ -extern char Version[]; -extern char ShortVersion[]; - - /* If getnum() has an error, here will be the result. */ -DECL int getnum_error INIT(0); - -enum context { domain_ctx, owner_ctx, mailname_ctx, hostname_ctx }; -DECL const char *context_strings[] -#ifdef MAIN_PROGRAM - = { "domain", "owner", "mail", "host", NULL } -#endif -; - -DECL const char *transport_strings[] -#ifdef MAIN_PROGRAM - = { "primary", "secondary", "response", NULL } -#endif -; - -DECL const char *severity_strings[] -#ifdef MAIN_PROGRAM - = { "ignore", "warn", "fail", "not_set", NULL } -#endif -; - -DECL struct in_addr inaddr_any; /* Inits to 0.0.0.0 */ - -DECL options server_options INIT(NULL); - -DECL server_info nameserver_info INIT(NULL); -DECL key_info_list secretkey_info INIT(NULL); - -DECL ip_match_list bogus_nameservers INIT(NULL); - -DECL log_context log_ctx; -DECL int log_ctx_valid INIT(0); - -DECL log_channel syslog_channel INIT(NULL); -DECL log_channel debug_channel INIT(NULL); -DECL log_channel stderr_channel INIT(NULL); -DECL log_channel eventlib_channel INIT(NULL); -DECL log_channel packet_channel INIT(NULL); -DECL log_channel null_channel INIT(NULL); - -DECL ip_match_list local_addresses INIT(NULL); -DECL ip_match_list local_networks INIT(NULL); - - /* are we running in no-fork mode? */ -DECL int foreground INIT(0); - -DECL const struct ns_sym logging_constants[] -#ifdef MAIN_PROGRAM -= { - { log_info, "info" }, - { log_notice, "notice" }, - { log_warning, "warning" }, - { log_error, "error" }, - { log_critical, "critical" }, - { 0, NULL } -} -#endif -; - -DECL const struct ns_sym syslog_constants[] -#ifdef MAIN_PROGRAM -= { - { LOG_KERN, "kern" }, - { LOG_USER, "user" }, - { LOG_MAIL, "mail" }, - { LOG_DAEMON, "daemon" }, - { LOG_AUTH, "auth" }, - { LOG_SYSLOG, "syslog" }, - { LOG_LPR, "lpr" }, -#ifdef LOG_NEWS - { LOG_NEWS, "news" }, -#endif -#ifdef LOG_UUCP - { LOG_UUCP, "uucp" }, -#endif -#ifdef LOG_CRON - { LOG_CRON, "cron" }, -#endif -#ifdef LOG_AUTHPRIV - { LOG_AUTHPRIV, "authpriv" }, -#endif -#ifdef LOG_FTP - { LOG_FTP, "ftp" }, -#endif - { LOG_LOCAL0, "local0"}, - { LOG_LOCAL1, "local1"}, - { LOG_LOCAL2, "local2"}, - { LOG_LOCAL3, "local3"}, - { LOG_LOCAL4, "local4"}, - { LOG_LOCAL5, "local5"}, - { LOG_LOCAL6, "local6"}, - { LOG_LOCAL7, "local7"}, - { 0, NULL } -} -#endif -; - -DECL const struct ns_sym category_constants[] -#ifdef MAIN_PROGRAM -= { - { ns_log_default, "default" }, - { ns_log_config, "config" }, - { ns_log_parser, "parser" }, - { ns_log_queries, "queries" }, - { ns_log_lame_servers, "lame-servers" }, - { ns_log_statistics, "statistics" }, - { ns_log_panic, "panic" }, - { ns_log_update, "update" }, - { ns_log_ncache, "ncache" }, - { ns_log_xfer_in, "xfer-in" }, - { ns_log_xfer_out, "xfer-out" }, - { ns_log_db, "db" }, - { ns_log_eventlib, "eventlib" }, - { ns_log_packet, "packet" }, -#ifdef BIND_NOTIFY - { ns_log_notify, "notify" }, -#endif - { ns_log_cname, "cname" }, - { ns_log_security, "security" }, - { ns_log_os, "os" }, - { ns_log_insist, "insist" }, - { ns_log_maint, "maintenance" }, - { ns_log_load, "load" }, - { ns_log_resp_checks, "response-checks" }, - { ns_log_control, "control" }, - { 0, NULL } -} -#endif -; - -DECL const char panic_msg_no_options[] - INIT("no server_options in NS_OPTION_P"); - -DECL const char panic_msg_insist_failed[] - INIT("%s:%d: insist '%s' failed: %s"); - -DECL const char panic_msg_bad_which[] - INIT("%s:%d: INCRSTATS(%s): bad \"which\""); - -DECL u_long globalStats[nssLast]; - -DECL evTimerID clean_timer; -DECL evTimerID interface_timer; -DECL evTimerID stats_timer; -DECL evTimerID heartbeat_timer; -DECL int active_timers INIT(0); - -DECL uid_t user_id; -DECL char * user_name INIT(NULL); -DECL gid_t group_id; -DECL char * group_name INIT(NULL); -DECL char * chroot_dir INIT(NULL); - -DECL int loading INIT(0); - -DECL int xfers_running INIT(0); -DECL int xfers_deferred INIT(0); -DECL int qserials_running INIT(0); diff --git a/contrib/bind/bin/named/ns_glue.c b/contrib/bind/bin/named/ns_glue.c deleted file mode 100644 index 8360ad51c6003..0000000000000 --- a/contrib/bind/bin/named/ns_glue.c +++ /dev/null @@ -1,464 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_glue.c,v 8.17 2000/07/17 07:36:52 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996-2000 by Internet Software Consortium, Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <resolv.h> -#include <signal.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> -#include <stdarg.h> -#include <unistd.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" - -/* - * IP address from unaligned octets. - */ -struct in_addr -ina_get(const u_char *data) { - struct in_addr ret; - u_int32_t i; - - GETLONG(i, data); - ina_ulong(ret) = htonl(i); - return (ret); -} - -/* - * IP address to unaligned octets. - */ -u_char * -ina_put(struct in_addr ina, u_char *data) { - PUTLONG(ntohl(ina_ulong(ina)), data); - return (data); -} - -/* - * IP address to presentation format. - */ -const char * -sin_ntoa(struct sockaddr_in sin) { - static char ret[sizeof "[111.222.333.444].55555"]; - - sprintf(ret, "[%s].%u", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); - return (ret); -} - -/* - * Logging Support - */ - -int -ns_wouldlog(int category, int level) { - if (log_ctx_valid) - return (log_check(log_ctx, category, level)); - return (0); -} - -void -ns_debug(int category, int level, const char *format, ...) { - va_list args; - - if (!log_ctx_valid) - return; - va_start(args, format); - log_vwrite(log_ctx, category, log_debug(level), format, args); - va_end(args); -} - -void -ns_info(int category, const char *format, ...) { - va_list args; - - if (!log_ctx_valid) - return; - va_start(args, format); - log_vwrite(log_ctx, category, log_info, format, args); - va_end(args); -} - -void -ns_notice(int category, const char *format, ...) { - va_list args; - - if (!log_ctx_valid) - return; - va_start(args, format); - log_vwrite(log_ctx, category, log_notice, format, args); - va_end(args); -} - -void -ns_warning(int category, const char *format, ...) { - va_list args; - - if (!log_ctx_valid) - return; - va_start(args, format); - log_vwrite(log_ctx, category, log_warning, format, args); - va_end(args); -} - -void -ns_error(int category, const char *format, ...) { - va_list args; - - if (!log_ctx_valid) - return; - va_start(args, format); - log_vwrite(log_ctx, category, log_error, format, args); - va_end(args); -} - -void -ns_panic(int category, int dump_core, const char *format, ...) { - va_list args; - - if (!log_ctx_valid) - return; - va_start(args, format); - log_vwrite(log_ctx, category, log_critical, format, args); - va_end(args); - va_start(args, format); - log_vwrite(log_ctx, ns_log_panic, log_critical, format, args); - va_end(args); - if (dump_core) - abort(); - else - exit(1); -} - -void -ns_assertion_failed(char *file, int line, assertion_type type, char *cond, - int print_errno) -{ - ns_panic(ns_log_insist, 1, "%s:%d: %s(%s)%s%s failed.", - file, line, assertion_type_to_text(type), cond, - (print_errno) ? ": " : "", - (print_errno) ? strerror(errno) : ""); -} - -/* - * XXX This is for compatibility and should eventually be removed. - */ -void -panic(const char *msg, const void *arg) { - ns_panic(ns_log_default, 1, msg, arg); -} - -/* - * How many labels in this name? - * Note: the root label is not included in the count. - */ -int -nlabels(const char *dname) { - int count, i, found, escaped; - const char *tmpdname, *end_tmpdname; - int tmpdnamelen, c; - - INSIST(dname != NULL); - - count = 0; - tmpdname = dname; - tmpdnamelen = strlen(tmpdname); - /* - * Ignore a trailing label separator (i.e. an unescaped dot) - * in 'tmpdname'. - */ - if (tmpdnamelen && tmpdname[tmpdnamelen-1] == '.') { - escaped = 0; - /* note this loop doesn't get executed if tmpdnamelen==1 */ - for (i = tmpdnamelen - 2; i >= 0; i--) - if (tmpdname[i] == '\\') { - if (escaped) - escaped = 0; - else - escaped = 1; - } else - break; - if (!escaped) - tmpdnamelen--; - } - - end_tmpdname = tmpdname + tmpdnamelen; - - while(tmpdname != end_tmpdname) { - count++; - /* - * Strip off the first label if we're not already at - * the root label. - */ - for (escaped = found = 0; - (tmpdname != end_tmpdname) && !found; - tmpdname++) { - c = *tmpdname; - if (!escaped && (c == '.')) - found = 1; - - if (escaped) - escaped = 0; - else if (c == '\\') - escaped = 1; - } - } - - ns_debug(ns_log_default, 12, "nlabels of \"%s\" -> %d", dname, count); - return (count); -} - -/* - * Get current system time and put it in a global. - */ -void -gettime(struct timeval *ttp) { - if (gettimeofday(ttp, NULL) < 0) - ns_error(ns_log_default, "gettimeofday: %s", strerror(errno)); - INSIST(ttp->tv_usec >= 0 && ttp->tv_usec < 1000000); -} - -/* - * This is useful for tracking down lost file descriptors. - */ -int -my_close(int fd) { - int s; - - do { - errno = 0; - s = close(fd); - } while (s < 0 && errno == EINTR); - - if (s < 0 && errno != EBADF) - ns_info(ns_log_default, "close(%d) failed: %s", fd, - strerror(errno)); - else - ns_debug(ns_log_default, 3, "close(%d) succeeded", fd); - return (s); -} - -/* - * This is useful for tracking down lost file descriptors. - */ -int -my_fclose(FILE *fp) { - int fd = fileno(fp), - s = fclose(fp); - - if (s < 0) - ns_info(ns_log_default, "fclose(%d) failed: %s", fd, - strerror(errno)); - else - ns_debug(ns_log_default, 3, "fclose(%d) succeeded", fd); - return (s); -} - -/* - * Save a counted buffer and return a pointer to it. - */ -u_char * -savebuf(const u_char *buf, size_t len, int needpanic) { - u_char *bp = (u_char *)memget(len); - - if (bp == NULL) { - if (needpanic) - panic("savebuf: memget failed (%s)", strerror(errno)); - else - return (NULL); - } - memcpy(bp, buf, len); - return (bp); -} - -char * -__newstr(size_t len, int needpanic) { - return (__newstr_record(len, needpanic, __FILE__, __LINE__)); -} - -char * -__savestr(const char *str, int needpanic) { - return (__savestr_record(str, needpanic, __FILE__, __LINE__)); -} - -void -__freestr(char *str) { - __freestr_record(str, __FILE__, __LINE__); -} - -#ifdef DEBUG_STRINGS -char * -debug_newstr(size_t len, int needpanic, const char *file, int line) { - size_t size; - - size = len + 3; /* 2 length bytes + NUL. */ - printf("%s:%d: newstr %d\n", file, line, size); - return (__newstr_record(len, needpanic, file, line)); -} - -char * -debug_savestr(const char *str, int needpanic, const char *file, int line) { - size_t len; - - len = strlen(str); - len += 3; /* 2 length bytes + NUL. */ - printf("%s:%d: savestr %d %s\n", file, line, len, str); - return (__savestr_record(str, needpanic, file, line)); -} - -void -debug_freestr(char *str, const char *file, int line) { - u_char *buf, *bp; - size_t len; - - buf = (u_char *)str - 2/*Len*/; - bp = buf; - NS_GET16(len, bp); - len += 3; /* 2 length bytes + NUL. */ - printf("%s:%d: freestr %d %s\n", file, line, len, str); - __freestr_record(str, file, line); - return; -} -#endif /* DEBUG_STRINGS */ - -/* - * Return a counted string buffer big enough for a string of length 'len'. - */ -char * -__newstr_record(size_t len, int needpanic, char *file, int line) { - u_char *buf, *bp; - - REQUIRE(len <= 65536); - - buf = (u_char *)__memget_record(2/*Len*/ + len + 1/*Nul*/, file, line); - if (buf == NULL) { - if (needpanic) - panic("savestr: memget failed (%s)", strerror(errno)); - else - return (NULL); - } - bp = buf; - NS_PUT16(len, bp); - return ((char *)bp); -} - -/* - * Save a NUL terminated string and return a pointer to it. - */ -char * -__savestr_record(const char *str, int needpanic, char *file, int line) { - char *buf; - size_t len; - - len = strlen(str); - if (len > 65536) { - if (needpanic) - ns_panic(ns_log_default, 1, - "savestr: string too long"); - else - return (NULL); - } - buf = __newstr_record(len, needpanic, file, line); - memcpy(buf, str, len + 1); - return (buf); -} - -void -__freestr_record(char *str, char *file, int line) { - u_char *buf, *bp; - size_t len; - - buf = (u_char *)str - 2/*Len*/; - bp = buf; - NS_GET16(len, bp); - __memput_record(buf, 2/*Len*/ + len + 1/*Nul*/, file, line); -} - -char * -checked_ctime(const time_t *t) { - char *ctime_result; - - ctime_result = ctime(t); - if (ctime_result == NULL) { - ns_error(ns_log_default, "ctime() returned NULL!"); - ctime_result = "<unknown time>\n"; - } - - return (ctime_result); -} - -/* - * Since the fields in a "struct timeval" are longs, and the argument to ctime - * is a pointer to a time_t (which might not be a long), here's a bridge. - */ -char * -ctimel(long l) { - time_t t = (time_t)l; - - return (checked_ctime(&t)); -} - -/* - * rename() is lame (can't overwrite an existing file) on some systems. - * use movefile() instead, and let lame OS ports do what they need to. - */ -#ifndef HAVE_MOVEFILE -int -movefile(const char *oldname, const char *newname) { - return (rename(oldname, newname)); -} -#endif - -#ifdef ultrix -/* - * Some library routines in libc need to be able to see the res_send - * and res_close symbols with out __ prefix otherwise we get multiply - * defined symbol errors when linking named. - */ - -#undef res_send -int res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) { - return __res_send(buf, buflen, ans, anssiz); -} -#undef _res_close -void _res_close(void) { - __res_close(); -} -#endif diff --git a/contrib/bind/bin/named/ns_init.c b/contrib/bind/bin/named/ns_init.c deleted file mode 100644 index 66242a479c53a..0000000000000 --- a/contrib/bind/bin/named/ns_init.c +++ /dev/null @@ -1,579 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)ns_init.c 4.38 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: ns_init.c,v 8.68 2000/04/21 06:54:07 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" - -#ifdef DEBUG -static void content_zone(int, int); -#endif - -/* - * Set new refresh time for zone. Use a random number in the last half of - * the refresh limit; we want it to be substantially correct while still - * preventing slave synchronization. - */ -void -ns_refreshtime(struct zoneinfo *zp, time_t timebase) { - u_long refresh = (zp->z_refresh > 0) ? zp->z_refresh : INIT_REFRESH; - time_t half = (refresh + 1) / 2; - - zp->z_time = timebase + half + (rand() % half); -} - -/* - * Set new retry time for zone. - */ -void -ns_retrytime(struct zoneinfo *zp, time_t timebase) { - zp->z_time = timebase + zp->z_retry; -} - -/* - * Read configuration file and save it as internal state. - */ -void -ns_init(const char *conffile) { - struct zoneinfo *zp; - static int loads = 0; /* number of times loaded */ - - ns_debug(ns_log_config, 1, "ns_init(%s)", conffile); - gettime(&tt); - - if (loads == 0) { - /* Init zone data. */ - zones = NULL; - INIT_LIST(freezones); - INIT_LIST(reloadingzones); - nzones = 0; - make_new_zones(); - - /* Init cache. */ - zones[0].z_type = z_cache; - zones[0].z_origin = savestr("", 1); - - /* Allocate cache hash table, formerly the root hash table. */ - hashtab = savehash((struct hashbuf *)NULL); - - /* Allocate root-hints/file-cache hash table. */ - fcachetab = savehash((struct hashbuf *)NULL); - - /* Init other misc stuff. */ - dst_init(); - init_configuration(); - } else { - /* Mark previous zones as not yet found in boot file. */ - block_signals(); - for (zp = &zones[1]; zp < &zones[nzones]; zp++) - if (zp->z_type != z_nil) { - zp->z_flags &= ~Z_FOUND; - if (LINKED(zp, z_reloadlink)) - UNLINK(reloadingzones, zp, - z_reloadlink); - } - unblock_signals(); - } - -#ifdef DEBUG - if (debug >= 3) { - ns_debug(ns_log_config, 3, "content of zones before loading"); - content_zone(nzones - 1, 3); - } -#endif - - load_configuration(conffile); - - /* Erase all old zones that were not found. */ - for (zp = &zones[0]; zp < &zones[nzones]; zp++) { - if (zp->z_type == z_cache) - continue; - if (zp->z_type != z_nil && (zp->z_flags & Z_FOUND) == 0) - remove_zone(zp, "removed"); - } - /* Reload parent zones of zones removed */ - for (zp = &zones[0]; zp < &zones[nzones]; zp++) { - if (zp->z_type == z_cache) - continue; - if (zp->z_type != z_nil && - (zp->z_flags & Z_PARENT_RELOAD) != 0) { - zp->z_flags &= ~Z_PARENT_RELOAD; - purgeandload(zp); - } - } - -#ifdef DEBUG - if (debug >= 2) { - ns_debug(ns_log_config, 2, "content of zones after loading"); - content_zone(nzones-1, 2); - } -#endif - - ns_debug(ns_log_config, 1, "exit ns_init()"); - loads++; -} - -void -zoneinit(struct zoneinfo *zp) { - struct stat sb; - int result; - - /* - * Try to load zone from backup file, - * if one was specified and it exists. - * If not, or if the data are out of date, - * we will refresh the zone from a primary - * immediately. - */ - if (zp->z_source == NULL) - return; - result = stat(zp->z_source, &sb); - if (result != -1) { - ns_stopxfrs(zp); - purge_zone(zp->z_origin, hashtab, zp->z_class); - } - if (result == -1 || - db_load(zp->z_source, zp->z_origin, zp, NULL, ISNOTIXFR)) - { - /* - * Set zone to be refreshed immediately. - */ - zp->z_refresh = INIT_REFRESH; - zp->z_retry = INIT_REFRESH; - if ((zp->z_flags & (Z_QSERIAL|Z_XFER_RUNNING)) == 0) { - zp->z_time = tt.tv_sec; - sched_zone_maint(zp); - } - } else { - zp->z_flags |= Z_AUTH; - zp->z_flags &= ~(Z_NEED_RELOAD|Z_EXPIRED); - ns_refreshtime(zp, tt.tv_sec); - sched_zone_maint(zp); - } -} - -/* - * Purge the zone and reload all parent zones. This needs to be done when - * we unload a zone, since the child zone will have stomped the parent's - * delegation to that child when it was first loaded. - */ -void -do_reload(const char *domain, int type, int class, int mark) { - struct zoneinfo *zp; - - ns_debug(ns_log_config, 1, "do_reload: %s %d %d %d", - *domain ? domain : ".", type, class, mark); - - /* - * Check if the zone has changed type. If so, we might not need to - * do any purging or parent reloading. - * - * If the new zone is a master zone, then it will have purged the - * old data and loaded, so we don't need to do anything. - * - * If the new zone is a slave or stub zone and has successfully loaded, - * then we don't need to do anything either. - * - * NOTE: we take care not to match ourselves. - */ - zp = find_zone(domain, class); - if (zp != NULL && - (type != z_master && zp->z_type == z_master) || - (type != z_slave && zp->z_type == z_slave && zp->z_serial != 0) || - (type != z_stub && zp->z_type == z_stub && zp->z_serial != 0)) - return; - - /* - * Clean up any leftover data. - */ - ns_stopxfrs(zp); - purge_zone(domain, hashtab, class); - - /* - * Reload - */ - while (*domain) { - const char *s; - int escaped; - - /* - * XXX this is presentation level hair and belongs elsewhere. - */ - escaped = 0; - for (s = domain; *s != '\0'; s++) { - if (!escaped) { - if (*s == '.') - break; - else if (*s == '\\') - escaped = 1; - } else - escaped = 0; - } - - if (*s != '\0') - domain = s + 1; /* skip label and its separator */ - else - domain = ""; /* root zone */ - - zp = find_zone(domain, class); - if (zp != NULL) { - ns_debug(ns_log_config, 1, "do_reload: matched %s", - *domain ? domain : "."); - if (mark) - zp->z_flags |= Z_PARENT_RELOAD; - else - purgeandload(zp); - break; - } - } -} - -void -purgeandload(struct zoneinfo *zp) { - -#ifdef BIND_UPDATE - /* - * A dynamic zone might have changed, so we - * need to dump it before removing it. - */ - if (zp->z_type == Z_PRIMARY && - (zp->z_flags & Z_DYNAMIC) != 0 && - ((zp->z_flags & Z_NEED_SOAUPDATE) != 0 || - (zp->z_flags & Z_NEED_DUMP) != 0)) - (void) zonedump(zp, ISNOTIXFR); -#endif - ns_stopxfrs(zp); - - if (zp->z_type == Z_HINT) - purge_zone(zp->z_origin, fcachetab, zp->z_class); - else - purge_zone(zp->z_origin, hashtab, zp->z_class); - - zp->z_flags &= ~Z_AUTH; - - switch (zp->z_type) { - case Z_SECONDARY: - case Z_STUB: - zoneinit(zp); - break; - case Z_PRIMARY: - if (db_load(zp->z_source, zp->z_origin, zp, 0, ISNOTIXFR) == 0) - zp->z_flags |= Z_AUTH; - break; - case Z_HINT: - case Z_CACHE: - (void)db_load(zp->z_source, zp->z_origin, zp, 0, ISNOTIXFR); - break; - } -} - -#ifdef DEBUG -/* prints out the content of zones */ -static void -content_zone(int end, int level) { - int i; - - for (i = 0; i <= end; i++) { - printzoneinfo(i, ns_log_config, level); - } -} -#endif - -enum context -ns_ptrcontext(owner) - const char *owner; -{ - if (ns_samedomain(owner, "in-addr.arpa") || - ns_samedomain(owner, "ip6.int")) - return (hostname_ctx); - return (domain_ctx); -} - -enum context -ns_ownercontext(type, transport) - int type; - enum transport transport; -{ - enum context context = domain_ctx; - - switch (type) { - case T_A: - case T_WKS: - case T_MX: - switch (transport) { - case update_trans: - case primary_trans: - case secondary_trans: - context = owner_ctx; - break; - case response_trans: - context = hostname_ctx; - break; - default: - panic("impossible condition in ns_ownercontext()", - NULL); - } - break; - case T_MB: - case T_MG: - context = mailname_ctx; - break; - default: - /* Nothing to do. */ - break; - } - return (context); -} - -int -ns_nameok(const struct qinfo *qry, const char *name, int class, - struct zoneinfo *zp, enum transport transport, - enum context context, - const char *owner, - struct in_addr source) -{ - enum severity severity = not_set; - int ok = 1; - - if (zp != NULL) - severity = zp->z_checknames; - if (severity == not_set) - severity = server_options->check_names[transport]; - - if (severity == ignore) - return (1); - switch (context) { - case domain_ctx: - ok = (class != C_IN) || res_dnok(name); - break; - case owner_ctx: - ok = (class != C_IN) || res_ownok(name); - break; - case mailname_ctx: - ok = res_mailok(name); - break; - case hostname_ctx: - ok = res_hnok(name); - break; - default: - ns_panic(ns_log_default, 1, - "unexpected context %d in ns_nameok", (int)context); - } - if (!ok) { - char *q, *s, *o; - - if (source.s_addr == INADDR_ANY) - s = savestr(transport_strings[transport], 0); - else { - s = newstr(strlen(transport_strings[transport]) + - sizeof " from [000.000.000.000] for [000.000.000.000]", 0); - if (s) - if ( (transport == response_trans) && - (qry != NULL) ) { - - if ( qry->q_flags & Q_PRIMING ) { - sprintf(s, "%s from [%s] for priming", - transport_strings[transport], - inet_ntoa(source)); - } else if ( qry->q_flags & Q_ZSERIAL ) { - sprintf(s, "%s from [%s] for soacheck", - transport_strings[transport], - inet_ntoa(source)); - } else if ( qry->q_flags & Q_SYSTEM ) { - sprintf(s, "%s from [%s] for sysquery", - transport_strings[transport], - inet_ntoa(source)); - } else { - q=strdup(inet_ntoa(qry->q_from.sin_addr)); - sprintf(s, "%s from [%s] for [%s]", - transport_strings[transport], - inet_ntoa(source), - q != NULL ? q : "memget failed"); - free(q); - } - - } else { - sprintf(s, "%s from [%s]", - transport_strings[transport], - inet_ntoa(source)); - } - } - if (ns_samename(owner, name) == 1) - o = savestr("", 0); - else { - const char *t = (*owner == '\0') ? "." : owner; - - o = newstr(strlen(t) + sizeof " (owner \"\")", 0); - if (o) - sprintf(o, " (owner \"%s\")", t); - } - /* - * We use log_write directly here to avoid duplicating - * the message formatting and arguments. - */ - log_write(log_ctx, ns_log_default, - (transport != response_trans) || - (o == NULL) || (s == NULL) || - ( (qry != NULL) && - (qry->q_flags & (Q_PRIMING|Q_ZSERIAL)) ) ? - log_warning : log_info, - "%s name \"%s\"%s %s (%s) is invalid - %s", - context_strings[context], - name, o != NULL ? o : "[memget failed]", - p_class(class), - s != NULL ? s : "[memget failed]", - (severity == fail) ? - "rejecting" : "proceeding anyway"); - if (severity == warn) - ok = 1; - if (s != NULL) - freestr(s); - if (o != NULL) - freestr(o); - } - return (ok); -} - -int -ns_wildcard(const char *name) { - if (*name != '*') - return (0); - return (*++name == '\0'); -} - -void -ns_shutdown() { - struct zoneinfo *zp; - -#ifdef BIND_NOTIFY - ns_unnotify(); -#endif - /* Erase zones. */ - for (zp = &zones[0]; zp < &zones[nzones]; zp++) { - if (zp->z_type) { - if (zp->z_type != z_hint && zp->z_type != z_cache) { - ns_stopxfrs(zp); - purge_zone(zp->z_origin, hashtab, zp->z_class); - } else if (zp->z_type == z_hint) - purge_zone(zp->z_origin, fcachetab, - zp->z_class); - free_zone_contents(zp, 1); - } - } - - /* Erase the cache. */ - clean_cache(hashtab, 1); - hashtab->h_cnt = 0; /* ??? */ - rm_hash(hashtab); - hashtab = NULL; - clean_cache(fcachetab, 1); - fcachetab->h_cnt = 0; /* ??? */ - rm_hash(fcachetab); - fcachetab = NULL; - - if (zones != NULL) - memput(zones, nzones * sizeof *zones); - zones = NULL; - - freeComplaints(); - shutdown_configuration(); -} diff --git a/contrib/bind/bin/named/ns_ixfr.c b/contrib/bind/bin/named/ns_ixfr.c deleted file mode 100644 index 693dc6f30751e..0000000000000 --- a/contrib/bind/bin/named/ns_ixfr.c +++ /dev/null @@ -1,612 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_ixfr.c,v 8.19 2000/04/18 20:47:27 vixie Exp $"; -#endif /* not lint */ - -/* - * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Check Point Software Technologies Incorporated not be used - * in advertising or publicity pertaining to distribution of the document - * or software without specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND CHECK POINT SOFTWARE TECHNOLOGIES - * INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL CHECK POINT SOFTWARE TECHNOLOGIES INCORPRATED - * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <fcntl.h> -#include <resolv.h> -#include <res_update.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" - -static void sx_new_ixfrmsg(struct qstream * qsp); -void sx_send_ixfr(struct qstream * qsp); - -static int sx_flush(struct qstream * qsp), - sx_addrr(struct qstream * qsp, - const char *dname, - struct databuf * dp); - -/* - * u_char * sx_new_ixfrmsg(msg) init the header of a message, reset the - * compression pointers, and reset the write pointer to the first byte - * following the header. - */ -static void -sx_new_ixfrmsg(struct qstream *qsp) { - HEADER * hp = (HEADER *) qsp->xfr.msg; - - memset(hp, 0, HFIXEDSZ); - hp->id = htons(qsp->xfr.id); - hp->opcode = qsp->xfr.opcode; - hp->qr = 1; - hp->aa = 1; - hp->rcode = NOERROR; - - qsp->xfr.ptrs[0] = qsp->xfr.msg; - qsp->xfr.ptrs[1] = NULL; - - qsp->xfr.cp = qsp->xfr.msg + HFIXEDSZ; - if (qsp->xfr.ixfr_zone == 0) { - int count, n; - int buflen; - struct namebuf *np; - struct hashbuf *htp; - struct zoneinfo *zp; - struct databuf *dp; - const char * fname; - u_char ** edp = qsp->xfr.ptrs + - sizeof qsp->xfr.ptrs / sizeof(u_char *); - - qsp->xfr.ixfr_zone = qsp->xfr.zone; - zp = &zones[qsp->xfr.zone]; - n = dn_comp(zp->z_origin, qsp->xfr.cp, - XFER_BUFSIZE - (qsp->xfr.cp - qsp->xfr.msg), NULL, NULL); - qsp->xfr.cp += n; - PUTSHORT((u_int16_t) T_IXFR, qsp->xfr.cp); - PUTSHORT((u_int16_t) zp->z_class, qsp->xfr.cp); - hp->qdcount = htons(ntohs(hp->qdcount) + 1); - count = qsp->xfr.cp - qsp->xfr.msg; - htp = hashtab; - np = nlookup(zp->z_origin, &htp, &fname, 0); - buflen = XFER_BUFSIZE; - foreach_rr(dp, np, T_SOA, qsp->xfr.class, qsp->xfr.zone) { - n = make_rr(zp->z_origin, dp, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, 0, qsp->xfr.ptrs, edp, 0); - qsp->xfr.cp += n; - hp->ancount = htons(ntohs(hp->ancount) + 1); - } - } -} - -/* - * int - * sx_flush(qsp) - * flush the intermediate buffer out to the stream IO system. - * return: - * passed through from sq_write(). - */ -static int -sx_flush(struct qstream *qsp) { - int ret; - -#ifdef DEBUG - if (debug >= 10) - fp_nquery(qsp->xfr.msg, qsp->xfr.cp - qsp->xfr.msg, - log_get_stream(packet_channel)); -#endif - if (qsp->xfr.tsig_state != NULL && qsp->xfr.tsig_skip == 0) { - int msglen = qsp->xfr.cp - qsp->xfr.msg; - - ns_sign_tcp(qsp->xfr.msg, &msglen, qsp->xfr.eom - qsp->xfr.msg, - NOERROR, qsp->xfr.tsig_state, - qsp->xfr.state == s_x_done); - - if (qsp->xfr.state == s_x_done) { - memput(qsp->xfr.tsig_state, sizeof(ns_tcp_tsig_state)); - qsp->xfr.tsig_state = NULL; - } - qsp->xfr.cp = qsp->xfr.msg + msglen; - - } - if (qsp->xfr.cp - qsp->xfr.msg > 0) - ret = sq_write(qsp, qsp->xfr.msg, qsp->xfr.cp - qsp->xfr.msg); - else { - ns_debug(ns_log_default, 3, " Flush negative number *********"); - ret = -1; - } - if (ret >= 0) { - qsp->xfr.cp = NULL; - qsp->xfr.tsig_skip = 0; - } - else - qsp->xfr.tsig_skip = 1; - return (ret); -} -/* - * int sx_addrr(qsp, name, dp) add name/dp's RR to the current assembly - * message. if it won't fit, write current message out, renew the message, - * and then RR should fit. return: -1 = the sq_write() failed so we could not - * queue the full message. 0 = one way or another, everything is fine. side - * effects: on success, the ANCOUNT is incremented and the pointers are - * advanced. - */ -static int -sx_addrr(struct qstream *qsp, const char *dname, struct databuf *dp) { - HEADER *hp = (HEADER *) qsp->xfr.msg; - u_char **edp = qsp->xfr.ptrs + sizeof qsp->xfr.ptrs / sizeof(u_char *); - int n; - - if (qsp->xfr.cp != NULL) { - if (qsp->xfr.transfer_format == axfr_one_answer && - sx_flush(qsp) < 0) - return (-1); - } - if (qsp->xfr.cp == NULL) - sx_new_ixfrmsg(qsp); - n = make_rr(dname, dp, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, - 0, qsp->xfr.ptrs, edp, 0); - if (n < 0) { - if (sx_flush(qsp) < 0) - return (-1); - if (qsp->xfr.cp == NULL) - sx_new_ixfrmsg(qsp); - n = make_rr(dname, dp, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, - 0, qsp->xfr.ptrs, edp, 0); - INSIST(n >= 0); - } - hp->ancount = htons(ntohs(hp->ancount) + 1); - qsp->xfr.cp += n; - return (0); -} - -void -sx_send_ixfr(struct qstream *qsp) { - char * cp; - u_int32_t serial = 0; - struct zoneinfo *zp = NULL; - struct databuf *soa_dp; - struct databuf *old_soadp; - ns_delta *dp; - ns_updrec *rp; - ns_updrec *trp; - int foundsoa; - - zp = &zones[qsp->xfr.zone]; - soa_dp = (struct databuf *) findzonesoa(zp); - if (soa_dp == NULL) { - /* XXX should be more graceful */ - ns_panic(ns_log_update, 1, - "sx_send_ixfr: unable to locate soa"); - } - old_soadp = memget(DATASIZE(soa_dp->d_size)); - memcpy(old_soadp, soa_dp, DATASIZE(soa_dp->d_size)); - - again: - switch (qsp->xfr.state) { - case s_x_firstsoa: - ns_debug(ns_log_default, 3, - "IXFR: s_x_firstsoa (%s)", zp->z_origin); - /* - * The current SOA has been emited already. - * It would be cleaner if the first one was emited here... - * - * if (sx_addrr(qsp, zp->z_origin, soa_dp) < 0) - * goto cleanup; - */ - qsp->xfr.state = s_x_deletesoa; - /* FALLTHROUGH */ - case s_x_deletesoa: - ns_debug(ns_log_default, 3, - "IXFR: s_x_deletesoa (%s)", zp->z_origin); - dp = NULL; - if (qsp->xfr.top.ixfr != NULL && !EMPTY(*qsp->xfr.top.ixfr)) - dp = HEAD(*qsp->xfr.top.ixfr); - if (dp != NULL) { - foundsoa = 0; - - rp = HEAD(dp->d_changes); - while (rp != NULL) { - if (rp->r_opcode == DELETE && - rp->r_dp != NULL && - rp->r_dp->d_type == T_SOA) { - if (sx_addrr(qsp, rp->r_dname, - rp->r_dp) < 0) - goto cleanup; - db_freedata(rp->r_dp); - rp->r_dp = NULL; - foundsoa = 1; - break; - } - rp = NEXT(rp, r_link); - } - - if (!foundsoa) { - cp = (char *)findsoaserial(old_soadp->d_data); - PUTLONG(HEAD(dp->d_changes)->r_zone, cp); - - if (sx_addrr(qsp, zp->z_origin, old_soadp) < 0) - goto cleanup; - } - } - qsp->xfr.state = s_x_deleting; - /* FALLTHROUGH */ - case s_x_deleting: - ns_debug(ns_log_default, 3, - "IXFR: s_x_deleting (%s)", zp->z_origin); - dp = NULL; - if (qsp->xfr.top.ixfr != NULL && !EMPTY(*qsp->xfr.top.ixfr)) - dp = HEAD(*qsp->xfr.top.ixfr); - if (dp != NULL) { - rp = HEAD(dp->d_changes); - while (rp != NULL) { - if (rp->r_opcode == DELETE && - rp->r_dp != NULL) { - /* - * Drop any SOA deletes - */ - if (rp->r_dp->d_type != T_SOA && - sx_addrr(qsp, rp->r_dname, - rp->r_dp) < 0) - goto cleanup; - db_freedata(rp->r_dp); - rp->r_dp = NULL; - } - rp = NEXT(rp, r_link); - } - } - qsp->xfr.state = s_x_addsoa; - /* FALLTHROUGH */ - case s_x_addsoa: - ns_debug(ns_log_default, 3, - "IXFR: s_x_addsoa (%s)", zp->z_origin); - dp = NULL; - if (qsp->xfr.top.ixfr != NULL && !EMPTY(*qsp->xfr.top.ixfr)) - dp = HEAD(*qsp->xfr.top.ixfr); - if (dp != NULL) { - foundsoa = 0; - rp = HEAD(dp->d_changes); - while (rp != NULL) { - if (rp->r_opcode == ADD && - rp->r_dp != NULL && - rp->r_dp->d_type == T_SOA) { - if (sx_addrr(qsp, rp->r_dname, - rp->r_dp) < 0) - goto cleanup; - db_freedata(rp->r_dp); - rp->r_dp = NULL; - foundsoa = 1; - break; - } - rp = NEXT(rp, r_link); - } - - if (!foundsoa) { - cp = (char *)findsoaserial(old_soadp->d_data); - if (NEXT(dp, d_link) != NULL) { - PUTLONG(HEAD(dp->d_changes)->r_zone, cp); - if (sx_addrr(qsp, zp->z_origin, - old_soadp) < 0) - goto cleanup; - } else { - if (sx_addrr(qsp, zp->z_origin, - soa_dp) < 0) - goto cleanup; - } - } - } - qsp->xfr.state = s_x_adding; - /* FALLTHROUGH */ - case s_x_adding: - ns_debug(ns_log_default, 3, - "IXFR: s_x_adding (%s)", zp->z_origin); - dp = NULL; - if (qsp->xfr.top.ixfr != NULL && !EMPTY(*qsp->xfr.top.ixfr)) { - dp = HEAD(*qsp->xfr.top.ixfr); - if (dp != NULL) { - /* see s_x_deleting */ - rp = HEAD(dp->d_changes); - while (rp != NULL) { - if (rp->r_opcode == ADD && - rp->r_dp != NULL && - rp->r_dp->d_type != T_SOA) { - if (sx_addrr(qsp, rp->r_dname, - rp->r_dp) < 0) - goto cleanup; - db_freedata(rp->r_dp); - rp->r_dp = NULL; - } - rp = NEXT(rp, r_link); - } - - /* move to next update */ - UNLINK(*qsp->xfr.top.ixfr, dp, d_link); - - /* clean up old update */ - while ((rp = HEAD(dp->d_changes)) != NULL) { - UNLINK(dp->d_changes, rp, r_link); - if (rp->r_dp != NULL) { - db_freedata(rp->r_dp); - rp->r_dp = NULL; - } - res_freeupdrec(rp); - } - memput(dp, sizeof (*dp)); - if (HEAD(*qsp->xfr.top.ixfr) != NULL) { - qsp->xfr.state = s_x_deletesoa; - goto again; - } - } - } - qsp->xfr.state = s_x_lastsoa; - /* FALLTHROUGH */ - case s_x_lastsoa: - ns_debug(ns_log_default, 3, - "IXFR: s_x_lastsoa (%s)", zp->z_origin); - if (qsp->xfr.ixfr_zone != 0) - sx_addrr(qsp, zp->z_origin, soa_dp); - break; - } - ns_debug(ns_log_default, 3, "IXFR: flushing %s", zp->z_origin); - qsp->xfr.state = s_x_done; - sx_flush(qsp); - sq_writeh(qsp, sq_flushw); - cleanup: - if (qsp->xfr.top.ixfr != NULL) { - if(!EMPTY(*qsp->xfr.top.ixfr)) { - while ((dp = HEAD(*qsp->xfr.top.ixfr)) != NULL) { - UNLINK(*qsp->xfr.top.ixfr, dp, d_link); - while ((rp = HEAD(dp->d_changes)) != NULL) { - UNLINK(dp->d_changes, rp, r_link); - if (rp->r_dp != NULL) - db_freedata(rp->r_dp); - rp->r_dp = NULL; - res_freeupdrec(rp); - } - memput(dp, sizeof *dp); - } - } - memput(qsp->xfr.top.ixfr, sizeof *qsp->xfr.top.ixfr); - qsp->xfr.top.ixfr = NULL; - } - memput(old_soadp, DATASIZE(old_soadp->d_size)); -} - - -#ifndef MAXBSIZE -#define MAXBSIZE 8192 -#endif - - -/* - * int ixfr_log_maint(struct zoneinfo *zp, int fast_trim) - * - * zp - pointer to the zone information - * fast_trim - is used to denote that this is not called on the regular - * maintaince cycle. - * - */ -int ixfr_log_maint(struct zoneinfo *zp, int fast_trim) { - int fd, rcount, wcount; - int found = 0; - int error = 0; - long seek = 0; - FILE *to_fp, *from_fp, *db_fp; - static char *tmpname; - struct stat db_sb; - struct stat sb; - static char buf[MAXBSIZE]; - - ns_debug(ns_log_default, 3, "ixfr_log_maint(%s)", zp->z_origin); - - /* find out how big the zone db file is */ - if ((db_fp = fopen(zp->z_source, "r")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - zp->z_source, strerror(errno)); - return (-1); - } - if (fstat(fileno(db_fp), &db_sb) < 0) { - ns_warning(ns_log_db, "%s: %s", - zp->z_source, strerror(errno)); - (void) my_fclose(db_fp); - return (-1); - } - (void) my_fclose(db_fp); - ns_debug(ns_log_default, 3, "%s, size %d blk %d", - zp->z_source, db_sb.st_size, - db_sb.st_size); - - /* open up the zone ixfr log */ - if ((from_fp = fopen(zp->z_ixfr_base, "r")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - return (-1); - } - - if (fstat(fileno(from_fp), &sb) < 0) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - (void) my_fclose(from_fp); - return (-1); - } - ns_debug(ns_log_default, 3, "%s, size %d max %d\n", - zp->z_ixfr_base, - sb.st_size, - zp->z_max_log_size_ixfr); - if (zp->z_max_log_size_ixfr) { - if (sb.st_size > zp->z_max_log_size_ixfr) - seek = (signed)sb.st_size - - (signed)(zp->z_max_log_size_ixfr + - (zp->z_max_log_size_ixfr * .10) ); - else - seek = 0; - } else { - if (sb.st_size > (db_sb.st_size * .50)) - seek = (signed)sb.st_size - (signed)((db_sb.st_size * .50) - + ((db_sb.st_size * zp->z_max_log_size_ixfr) *.10)); - else - seek = 0; - } - ns_debug(ns_log_default, 3, "seek: %d", seek); - if (seek < 1) - { - ns_debug(ns_log_default, 3, "%s does not need to be reduced", - zp->z_ixfr_base); - (void) my_fclose(from_fp); - return (-1); - } - - if ((fast_trim) && seek < (zp->z_max_log_size_ixfr + 100000)) { - (void) my_fclose(from_fp); - return (0); - } - - tmpname = memget(strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1); - if (!tmpname) { - ns_warning(ns_log_default, "memget failed"); - return (-1); - } -#ifdef SHORT_FNAMES - filenamecpy(tmpname, zp->z_ixfr_base); -#else - (void) strcpy(tmpname, zp->z_ixfr_base); -#endif /* SHORT_FNAMES */ - - (void) strcat(tmpname, ".XXXXXX"); - if ((fd = mkstemp(tmpname)) == -1) { - ns_warning(ns_log_db, "can't make tmpfile (%s): %s", - strerror(errno)); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - return (-1); - } - if ((to_fp = fdopen(fd, "r+")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - tmpname, strerror(errno)); - (void) unlink(tmpname); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - (void) close(fd); - return (-1); - } - - if (fgets(buf, sizeof(buf), from_fp) == NULL) { - ns_error(ns_log_update, "fgets() from %s failed: %s", - zp->z_ixfr_base, strerror(errno)); - error++; - goto clean_up; - } - if (strcmp(buf, LogSignature) != 0) { - ns_error(ns_log_update, "invalid log file %s", - zp->z_ixfr_base); - error++; - goto clean_up; - } - - if (fseek( from_fp, seek, 0) < 0) { - error++; - goto clean_up; - } - - found = 0; - for (;;) { - if (getword(buf, sizeof buf, from_fp, 0)) { - if (strcasecmp(buf, "[END_DELTA]") == 0) { - if (!(fgets(buf, 2, from_fp) == NULL)) /* eat <cr><lf> */ - found = 1; - break; - } - } - if (feof(from_fp)) - break; - } - if (found) { - ns_debug(ns_log_default, 1, "ixfr_log_maint(): found [END_DELTA]"); - - fprintf(to_fp, "%s", LogSignature); - - while ((rcount = fread(buf, sizeof(char), MAXBSIZE, from_fp)) > 0) { - wcount = fwrite(buf, sizeof(char), rcount, to_fp); - if (rcount != wcount || wcount == -1) { - ns_warning(ns_log_default, "ixfr_log_maint: error in writting copy"); - break; - } - } - if (rcount < 0) - ns_warning(ns_log_default, - "ixfr_log_maint: error in reading copy"); - } - clean_up: - (void) my_fclose(to_fp); - (void) close(fd); - (void) my_fclose(from_fp); - if (error == 0) { - if (rename(tmpname, zp->z_ixfr_base) == -1) { - ns_warning(ns_log_default, "can not rename %s to %s :%s", - tmpname, zp->z_ixfr_base, strerror(errno)); - } - if ((from_fp = fopen(zp->z_ixfr_base, "r")) == NULL) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - return (-1); - } - if (fstat(fileno(from_fp), &sb) < 0) { - ns_warning(ns_log_db, "%s: %s", - zp->z_ixfr_base, strerror(errno)); - (void) my_fclose(from_fp); - return (-1); - } - if (sb.st_size <= 0) - (void) unlink(zp->z_ixfr_base); - else if (chmod(zp->z_ixfr_base, 0644) < 0) - ns_error(ns_log_update, - "chmod(%s,%o) failed, pressing on: %s", - zp->z_source, sb.st_mode, - strerror(errno)); - } - (void) unlink(tmpname); - memput(tmpname, (strlen(zp->z_ixfr_base) + sizeof(".XXXXXX") + 1)); - (void) my_fclose(from_fp); - - zp->z_serial_ixfr_start = 0; /* signal to read for lowest serial number */ - - ns_debug(ns_log_default, 3, "%s, size %d max %d\n", - zp->z_ixfr_base, - sb.st_size, - zp->z_max_log_size_ixfr); - - if (error) - return(-1); - else - return (0); -} - diff --git a/contrib/bind/bin/named/ns_lexer.c b/contrib/bind/bin/named/ns_lexer.c deleted file mode 100644 index 7110fe4989080..0000000000000 --- a/contrib/bind/bin/named/ns_lexer.c +++ /dev/null @@ -1,809 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_lexer.c,v 8.20 2000/04/21 06:54:07 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <time.h> -#include <stdarg.h> -#include <syslog.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" -#include "ns_parser.h" -#include "ns_parseutil.h" -#include "ns_lexer.h" - -typedef enum lexer_state { - scan, number, identifier, ipv4, quoted_string -} LexerState; - -#define LEX_EOF 0x01 -#define LEXER_MAX_PUSHBACK 2 - -typedef struct lexer_file_context { - const char * name; - FILE * stream; - int line_number; - LexerState state; - u_int flags; - int warnings; - int errors; - u_int pushback_count; - char pushback[LEXER_MAX_PUSHBACK]; - struct lexer_file_context * - next; -} *LexerFileContext; - -LexerFileContext current_file = NULL; - -#define LEX_LAST_WAS_DOT 0x01 -#define LEX_CONSECUTIVE_DOTS 0x02 - -typedef struct lexer_identifier { - char buffer[LEX_MAX_IDENT_SIZE+1]; - int index; - int num_dots; - unsigned int flags; -} *LexerIdentifier; - -static LexerIdentifier id; - -static char special_chars[256]; - -#define whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') -#define domain_char(c) (isalnum((c)) || (c) == '.' || (c) == '-') -#define special_char(c) (special_chars[(c)] == 1) -#define identifier_char(c) (!whitespace(c) && !special_char(c)) - -static int last_token; -static YYSTYPE last_yylval; - -static int lexer_initialized = 0; - -/* - * Problem Reporting - */ - -static char * -token_to_text(int token, YYSTYPE lval) { - static char buffer[LEX_MAX_IDENT_SIZE+50]; - - if (token < 128) { - if (token == 0) - strcpy(buffer, "<end of file>"); - else - sprintf(buffer, "'%c'", token); - } else { - switch (token) { - case L_EOS: - strcpy(buffer, ";"); - break; - case L_STRING: - sprintf(buffer, "'%s'", lval.cp); - break; - case L_QSTRING: - sprintf(buffer, "\"%s\"", lval.cp); - break; - case L_IPADDR: - sprintf(buffer, "%s", inet_ntoa(lval.ip_addr)); - break; - case L_NUMBER: - sprintf(buffer, "%ld", lval.num); - break; - case L_END_INCLUDE: - sprintf(buffer, "<end of include>"); - break; - default: - sprintf(buffer, "%s", lval.cp); - } - } - - return (buffer); -} - -static char where[MAXPATHLEN + 100]; -static char message[20480]; - -static void -parser_complain(int is_warning, int print_last_token, const char *format, - va_list args) -{ - LexerFileContext lf; - int severity; - - if (is_warning) { - severity = log_warning; - } else { - severity = log_error; - } - - INSIST(current_file != NULL); - if (current_file->next != NULL) { - for (lf = current_file; lf != NULL; lf = lf->next) { - log_write(log_ctx, ns_log_parser, severity, - "%s '%s' line %d", - (lf == current_file) ? - "In" : "included from", - lf->name, lf->line_number); - } - } - sprintf(where, "%s:%d: ", current_file->name, - current_file->line_number); - vsprintf(message, format, args); - if (print_last_token) - log_write(log_ctx, ns_log_parser, severity, "%s%s near %s", - where, message, - token_to_text(last_token, last_yylval)); - else - log_write(log_ctx, ns_log_parser, severity, - "%s%s", where, message); -} - -int -parser_warning(int print_last_token, const char *format, ...) { - va_list args; - - va_start(args, format); - parser_complain(1, print_last_token, format, args); - va_end(args); - current_file->warnings++; - return (1); -} - -int -parser_error(int print_last_token, const char *format, ...) { - va_list args; - - va_start(args, format); - parser_complain(0, print_last_token, format, args); - va_end(args); - current_file->errors++; - return (1); -} - -void -yyerror(const char *message) { - parser_error(1, message); -} - -/* - * Keywords - */ - -struct keyword { - char *name; - int token; -}; - -/* - * "keywords" is an array of the keywords which are the fixed syntactic - * elements of the configuration file. Each keyword has a string version - * of the keyword and a token id, which should be an identifier which - * matches that in a %token statement inside the parser.y file. - */ -static struct keyword keywords[] = { - {"acl", T_ACL}, - {"address", T_ADDRESS}, - {"algorithm", T_ALGID}, - {"allow", T_ALLOW}, - {"allow-query", T_ALLOW_QUERY}, - {"allow-recursion", T_ALLOW_RECURSION}, - {"allow-transfer", T_ALLOW_TRANSFER}, - {"allow-update", T_ALLOW_UPDATE}, -#ifdef BIND_NOTIFY - {"also-notify", T_ALSO_NOTIFY}, -#endif - {"auth-nxdomain", T_AUTH_NXDOMAIN}, - {"blackhole", T_BLACKHOLE}, - {"bogus", T_BOGUS}, - {"category", T_CATEGORY}, - {"class", T_CLASS}, - {"channel", T_CHANNEL}, - {"check-names", T_CHECK_NAMES}, - {"cleaning-interval", T_CLEAN_INTERVAL}, - {"controls", T_CONTROLS}, - {"coresize", T_CORESIZE}, - {"datasize", T_DATASIZE}, - {"deallocate-on-exit", T_DEALLOC_ON_EXIT}, - {"debug", T_DEBUG}, - {"default", T_DEFAULT}, - {"dialup", T_DIALUP}, - {"directory", T_DIRECTORY}, - {"dump-file", T_DUMP_FILE}, - {"dynamic", T_DYNAMIC}, - {"fail", T_FAIL}, - {"fake-iquery", T_FAKE_IQUERY}, - {"false", T_FALSE}, - {"fetch-glue", T_FETCH_GLUE}, - {"file", T_FILE}, - {"files", T_FILES}, - {"first", T_FIRST}, - {"forward", T_FORWARD}, - {"forwarders", T_FORWARDERS}, - {"group", T_GROUP}, - {"has-old-clients", T_HAS_OLD_CLIENTS}, - {"heartbeat-interval", T_HEARTBEAT}, - {"hint", T_HINT}, - {"host-statistics", T_HOSTSTATS}, - {"if-no-answer", T_IF_NO_ANSWER}, - {"if-no-domain", T_IF_NO_DOMAIN}, - {"ignore", T_IGNORE}, - {"include", T_INCLUDE}, - {"inet", T_INET}, - {"interface-interval", T_INTERFACE_INTERVAL}, - {"ixfr-base", T_FILE_IXFR}, - {"ixfr-tmp-file", T_IXFR_TMP}, - {"key", T_SEC_KEY}, - {"keys", T_KEYS}, - {"lame-ttl", T_LAME_TTL}, - {"listen-on", T_LISTEN_ON}, - {"logging", T_LOGGING}, - {"maintain-ixfr-base", T_MAINTAIN_IXFR_BASE}, - {"many-answers", T_MANY_ANSWERS}, - {"master", T_MASTER}, - {"masters", T_MASTERS}, - {"max-ixfr-log-size", T_MAX_LOG_SIZE_IXFR}, - {"max-ncache-ttl", T_MAX_NCACHE_TTL}, - {"max-transfer-time-in", T_MAX_TRANSFER_TIME_IN}, - {"memstatistics-file", T_MEMSTATS_FILE}, - {"min-roots", T_MIN_ROOTS}, - {"multiple-cnames", T_MULTIPLE_CNAMES}, - {"name", T_NAME}, - {"named-xfer", T_NAMED_XFER}, - {"no", T_NO}, -#ifdef BIND_NOTIFY - {"notify", T_NOTIFY}, -#endif - {"null", T_NULL_OUTPUT}, - {"one-answer", T_ONE_ANSWER}, - {"only", T_ONLY}, - {"order", T_ORDER}, - {"options", T_OPTIONS}, - {"owner", T_OWNER}, - {"perm", T_PERM}, - {"pid-file", T_PIDFILE}, - {"port", T_PORT}, - {"print-category", T_PRINT_CATEGORY}, - {"print-severity", T_PRINT_SEVERITY}, - {"print-time", T_PRINT_TIME}, - {"pubkey", T_PUBKEY}, - {"query-source", T_QUERY_SOURCE}, - {"rfc2308-type1", T_RFC2308_TYPE1}, - {"rrset-order", T_RRSET_ORDER}, - {"recursion", T_RECURSION}, - {"response", T_RESPONSE}, - {"secret", T_SECRET}, - {"serial-queries", T_SERIAL_QUERIES}, - {"server", T_SERVER}, - {"severity", T_SEVERITY}, - {"size", T_SIZE}, - {"slave", T_SLAVE}, - {"sortlist", T_SORTLIST}, - {"stacksize", T_STACKSIZE}, - {"statistics-file", T_STATS_FILE}, - {"statistics-interval", T_STATS_INTERVAL}, - {"stub", T_STUB}, - {"support-ixfr", T_SUPPORT_IXFR}, - {"syslog", T_SYSLOG}, - {"topology", T_TOPOLOGY}, - {"transfer-format", T_TRANSFER_FORMAT}, - {"transfer-source", T_TRANSFER_SOURCE}, - {"transfers", T_TRANSFERS}, - {"transfers-in", T_TRANSFERS_IN}, - {"transfers-out", T_TRANSFERS_OUT}, - {"transfers-per-ns", T_TRANSFERS_PER_NS}, - {"treat-cr-as-space", T_TREAT_CR_AS_SPACE}, - {"true", T_TRUE}, - {"trusted-keys", T_TRUSTED_KEYS}, - {"type", T_TYPE}, - {"unix", T_UNIX}, - {"unlimited", T_UNLIMITED}, - {"use-id-pool", T_USE_ID_POOL}, - {"use-ixfr", T_USE_IXFR}, - {"version", T_VERSION}, - {"versions", T_VERSIONS}, - {"warn", T_WARN}, - {"yes", T_YES}, - {"zone", T_ZONE}, - {(char *) NULL, 0}, -}; - -/* - * The table size should be a prime chosen to minimize collisions. - */ -#define KEYWORD_TABLE_SIZE 461 - -static symbol_table keyword_table = NULL; - -static void -init_keywords() { - struct keyword *k; - symbol_value value; - - if (keyword_table != NULL) - free_symbol_table(keyword_table); - keyword_table = new_symbol_table(KEYWORD_TABLE_SIZE, NULL); - for (k = keywords; k->name != NULL; k++) { - value.integer = k->token; - define_symbol(keyword_table, k->name, 0, value, 0); - } - dprint_symbol_table(99, keyword_table); -} - -/* - * File Contexts - */ - -void -lexer_begin_file(const char *filename, FILE *stream) { - LexerFileContext lf; - - if (stream == NULL) { - stream = fopen(filename, "r"); - if (stream == NULL) { - parser_error(0, "couldn't open include file '%s'", - filename); - return; - } - } - lf = (LexerFileContext)memget(sizeof (struct lexer_file_context)); - if (lf == NULL) - panic("memget failed in lexer_begin_file", NULL); - INSIST(stream != NULL); - lf->stream = stream; - lf->name = filename; /* note copy by reference */ - lf->line_number = 1; - lf->state = scan; - lf->flags = 0; - lf->warnings = 0; - lf->errors = 0; - lf->pushback_count = 0; - lf->next = current_file; - current_file = lf; -} - -void -lexer_end_file(void) { - LexerFileContext lf; - - INSIST(current_file != NULL); - lf = current_file; - current_file = lf->next; - fclose(lf->stream); - memput(lf, sizeof *lf); -} - -/* - * Character Input - */ - -#define LEXER_GETC(c, cf) \ - do { \ - if ((cf)->pushback_count > 0) { \ - (cf)->pushback_count--; \ - (c) = (cf)->pushback[(cf)->pushback_count]; \ - } else \ - (c) = getc((cf)->stream); \ - } while (0); - -#define LEXER_UNGETC(c, cf) \ - do { \ - INSIST((cf)->pushback_count < LEXER_MAX_PUSHBACK); \ - (cf)->pushback[(cf)->pushback_count++] = (c); \ - } while (0); - -static void -scan_to_comment_end(int c_plus_plus_style) { - int c; - int done = 0; - int prev_was_star = 0; - - while (!done) { - LEXER_GETC(c, current_file); - switch (c) { - case EOF: - if (!c_plus_plus_style) - parser_error(0, "EOF in comment"); - current_file->flags |= LEX_EOF; - done = 1; - break; - case '*': - prev_was_star = 1; - break; - case '/': - if (prev_was_star && !c_plus_plus_style) - done = 1; - prev_was_star = 0; - break; - case '\n': - if (c_plus_plus_style) { - /* don't consume the newline because - we want it to be a delimiter for - anything before the comment - started */ - LEXER_UNGETC(c, current_file); - done = 1; - } else { - current_file->line_number++; - } - prev_was_star = 0; - break; - default: - prev_was_star = 0; - } - } -} - -int -get_next_char(int comment_ok) { - int c, nc; - - if (current_file->flags & LEX_EOF) - return (EOF); - - LEXER_GETC(c, current_file); - - if (comment_ok) { - while (c == '/' || c == '#') { - if (c == '#') { - scan_to_comment_end(1); - if (current_file->flags & LEX_EOF) - return (EOF); - LEXER_GETC(c, current_file); - } else { - LEXER_GETC(nc, current_file); - switch (nc) { - case EOF: - current_file->flags |= LEX_EOF; - return ('/'); - case '*': - case '/': - scan_to_comment_end((nc == '/')); - if (current_file->flags & LEX_EOF) - return (EOF); - LEXER_GETC(c, current_file); - break; - default: - LEXER_UNGETC(nc, current_file); - return ('/'); - } - } - } - } - - if (c == EOF) - current_file->flags |= LEX_EOF; - else if (c == '\n') - current_file->line_number++; - return (c); -} - -void -put_back_char(int c) { - if (c == EOF) - current_file->flags |= LEX_EOF; - else { - LEXER_UNGETC(c, current_file); - if (c == '\n') - current_file->line_number--; - } -} - - -/* - * Identifiers - */ - -static void -clear_identifier(LexerIdentifier id) { - INSIST(id != NULL); - id->index = 0; - id->num_dots = 0; - id->flags = 0; -} - -static char * -dup_identifier(LexerIdentifier id) { - char *duplicate; - - INSIST(id != NULL); - duplicate = savestr(id->buffer, 1); - return (duplicate); -} - -static void -finish_identifier(LexerIdentifier id) { - INSIST(id != NULL && id->index < LEX_MAX_IDENT_SIZE); - id->buffer[id->index] = '\0'; -} - -static void -add_to_identifier(LexerIdentifier id, int c) { - INSIST(id != NULL); - id->buffer[id->index] = c; - id->index++; - if (id->index >= LEX_MAX_IDENT_SIZE) { - parser_error(0, "identifier too long"); - current_file->state = scan; - /* discard chars until we hit a non-identifier char */ - while (c != EOF && identifier_char(c)) { - c = get_next_char(1); - } - put_back_char(c); - clear_identifier(id); - } else { - if (c == '.') { - if (id->flags & LEX_LAST_WAS_DOT) - id->flags |= LEX_CONSECUTIVE_DOTS; - id->flags |= LEX_LAST_WAS_DOT; - id->num_dots++; - } else { - id->flags &= ~LEX_LAST_WAS_DOT; - } - } -} - -/* - * yylex() -- return the next token from the current input stream - */ -int -yylex() { - int c; - int comment_ok = 1; - int token = -1; - symbol_value value; - - while (token < 0) { - c = get_next_char(comment_ok); - switch(current_file->state) { - case scan: - if (c == EOF) { - if (current_file->next == NULL) - /* - * We don't want to call - * lexer_end_file() here because we - * want to keep the toplevel file - * context to log errors against. - */ - token = 0; - else { - lexer_end_file(); - token = L_END_INCLUDE; - } - break; - } - if (whitespace(c)) - break; - if (identifier_char(c)) { - if (isdigit(c)) - current_file->state = number; - else - current_file->state = identifier; - clear_identifier(id); - add_to_identifier(id, c); - } else - if (special_char(c)) { - if (c == ';') { - token = L_EOS; - break; - } - if (c == '"') { - clear_identifier(id); - current_file->state = - quoted_string; - comment_ok = 0; - break; - } - token = c; - } else { - parser_error(0, - "invalid character '%c'", - c); - } - break; - - case number: - if (c != EOF && identifier_char(c)) { - if (!isdigit(c)) - current_file->state = - (c == '.') ? ipv4 : identifier; - add_to_identifier(id, c); - } else { - put_back_char(c); - current_file->state = scan; - finish_identifier(id); - yylval.num = strtol(id->buffer, (char**)0, 0); - token = L_NUMBER; - } - break; - - case identifier: - if (c != EOF && identifier_char(c)) { - add_to_identifier(id, c); - } else { - put_back_char(c); - current_file->state = scan; - finish_identifier(id); - /* is it a keyword? */ - if (lookup_symbol(keyword_table, id->buffer, - 0, &value)) { - yylval.cp = id->buffer; - token = value.integer; - } else { - yylval.cp = dup_identifier(id); - token = L_STRING; - } - } - break; - - case ipv4: - if (c != EOF && identifier_char(c)) { - if (!isdigit(c)) { - if (c != '.' || - (id->flags & LEX_CONSECUTIVE_DOTS)) - current_file->state = - identifier; - } - add_to_identifier(id, c); - } else { - put_back_char(c); - if (id->num_dots > 3 || - (id->flags & LEX_LAST_WAS_DOT)) - current_file->state = identifier; - else { - if (id->num_dots == 1) { - add_to_identifier(id, '.'); - add_to_identifier(id, '0'); - add_to_identifier(id, '.'); - add_to_identifier(id, '0'); - } else if (id->num_dots == 2) { - add_to_identifier(id, '.'); - add_to_identifier(id, '0'); - } - current_file->state = scan; - finish_identifier(id); - token = L_IPADDR; - if (inet_aton(id->buffer, - &(yylval.ip_addr))==0) { - yylval.cp = dup_identifier(id); - token = L_STRING; - } - } - } - break; - - case quoted_string: - if (c == EOF) { - parser_error(0, "EOF in quoted string"); - return 0; - } else { - if (c == '"') { - comment_ok = 1; - current_file->state = scan; - finish_identifier(id); - yylval.cp = dup_identifier(id); - token = L_QSTRING; - } else { - /* XXX add backslash escapes here */ - add_to_identifier(id, c); - } - } - break; - - default: - panic("unhandled state in yylex", NULL); - } - } - - last_token = token; - last_yylval = yylval; - return (token); -} - -/* - * Initialization - */ - -symbol_table constants; - -static void -import_constants(const struct ns_sym *s, int type) { - symbol_value value; - for ((void)NULL; s != NULL && s->name != NULL; s++) { - value.integer = s->number; - define_symbol(constants, s->name, type, value, 0); - } -} - -static void -import_res_constants(const struct res_sym *r, int type) { - symbol_value value; - for ((void)NULL; r != NULL && r->name != NULL; r++) { - value.integer = r->number; - define_symbol(constants, r->name, type, value, 0); - } -} - -#define CONSTANTS_TABLE_SIZE 397 /* should be prime */ - -static void -import_all_constants() { - constants = new_symbol_table(CONSTANTS_TABLE_SIZE, NULL); - import_res_constants(__p_class_syms, SYM_CLASS); - import_constants(category_constants, SYM_CATEGORY); - import_constants(logging_constants, SYM_LOGGING); - import_constants(syslog_constants, SYM_SYSLOG); -} - -void -lexer_initialize() { - memset(special_chars, 0, sizeof special_chars); - special_chars[';'] = 1; - special_chars['{'] = 1; - special_chars['}'] = 1; - special_chars['!'] = 1; - special_chars['/'] = 1; - special_chars['"'] = 1; - special_chars['*'] = 1; - id = (LexerIdentifier)memget(sizeof (struct lexer_identifier)); - if (id == NULL) - panic("memget failed in lexer_initialize", NULL); - init_keywords(); - import_all_constants(); - lexer_initialized = 1; -} - -void -lexer_setup(void) { - REQUIRE(lexer_initialized); - - current_file = NULL; /* XXX should we INSIST(current_file==NULL)? */ - INSIST(id != NULL); -} - -void -lexer_shutdown(void) { - REQUIRE(lexer_initialized); - - free_symbol_table(keyword_table); - free_symbol_table(constants); - memput(id, sizeof (struct lexer_identifier)); - id = NULL; - lexer_initialized = 0; -} diff --git a/contrib/bind/bin/named/ns_lexer.h b/contrib/bind/bin/named/ns_lexer.h deleted file mode 100644 index 7a22b8e3ff73b..0000000000000 --- a/contrib/bind/bin/named/ns_lexer.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef _NS_LEXER_H -#define _NS_LEXER_H - -/* - * Note: <stdio.h> and "ns_parseutil.h" must be included - * before this file is included. - */ - -#define LEX_MAX_IDENT_SIZE 1024 - -#define SYM_CLASS 0x01 -#define SYM_CATEGORY 0x02 -#define SYM_LOGGING 0x04 -#define SYM_SYSLOG 0x08 - -int parser_warning(int, const char *, ...); -int parser_error(int, const char *, ...); -void yyerror(const char *); -void lexer_begin_file(const char *, FILE *); -void lexer_end_file(void); -int yylex(void); -void lexer_initialize(void); -void lexer_setup(void); -void lexer_shutdown(void); - -extern symbol_table constants; - -#endif /* !_NS_LEXER_H */ diff --git a/contrib/bind/bin/named/ns_main.c b/contrib/bind/bin/named/ns_main.c deleted file mode 100644 index 14618072ddbc4..0000000000000 --- a/contrib/bind/bin/named/ns_main.c +++ /dev/null @@ -1,2764 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)ns_main.c 4.55 (Berkeley) 7/1/91"; -static const char rcsid[] = "$Id: ns_main.c,v 8.126 2000/07/20 22:50:39 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1989, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#if !defined(lint) && !defined(SABER) -char copyright[] = -"@(#) Copyright (c) 1986, 1989, 1990 The Regents of the University of California.\n" -"portions Copyright (c) 1993 Digital Equipment Corporation\n" -"portions Copyright (c) 1995-1999 Internet Software Consortium\n" -"portions Copyright (c) 1999 Check Point Software Technologies\n" -"All rights reserved.\n"; -#endif /* not lint */ - -/* - * Internet Name server (see RCF1035 & others). - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/un.h> -#ifdef SVR4 /* XXX */ -# include <sys/sockio.h> -#else -# include <sys/mbuf.h> -#endif - -#include <netinet/in.h> -#include <net/route.h> -#include <net/if.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <grp.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <netdb.h> -#include <pwd.h> -#include <resolv.h> -#include <string.h> -#include <syslog.h> -#include <time.h> -#include <unistd.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> -#include <isc/list.h> - -#include "port_after.h" - -#ifdef HAVE_GETRUSAGE /* XXX */ -#include <sys/resource.h> -#endif - -#define MAIN_PROGRAM -#include "named.h" -#undef MAIN_PROGRAM - - /* list of interfaces */ -static LIST(struct _interface) iflist; -static int iflist_initialized = 0; -static int iflist_dont_rescan = 0; - -static const int drbufsize = 32 * 1024, /* UDP rcv buf size */ - dsbufsize = 48 * 1024, /* UDP snd buf size */ - sbufsize = 16 * 1024, /* TCP snd buf size */ -#ifdef BROKEN_RECVFROM - nudptrans = 1, -#else - nudptrans = 20, /* #/udps per select */ -#endif - listenmax = 50; - -static u_int16_t nsid_state; -static u_int16_t *nsid_pool; /* optional query id pool */ -static u_int16_t *nsid_vtable; /* optional shuffle table */ -static u_int32_t nsid_hash_state; -static u_int16_t nsid_a1, nsid_a2, nsid_a3; -static u_int16_t nsid_c1, nsid_c2, nsid_c3; -static u_int16_t nsid_state2; -static int nsid_algorithm; - -typedef void (*handler)(void); -static int needs = 0, needs_exit = 0; -static handler handlers[main_need_num]; -static void need_waitfunc(evContext, void *, const void *); - -static struct qstream *sq_add(void); -static int opensocket_d(interface *), - opensocket_s(interface *); -static void sq_query(struct qstream *), - dq_remove(interface *); -static int sq_dowrite(struct qstream *); -static void use_desired_debug(void); -static void stream_write(evContext, void *, int, int); - -static interface * if_find(struct in_addr, u_int16_t port); - -static int sq_here(struct qstream *); - -static void deallocate_everything(void), - stream_accept(evContext, void *, int, - const void *, int, - const void *, int), - stream_getlen(evContext, void *, int, int), - stream_getmsg(evContext, void *, int, int), - datagram_read(evContext, void *, int, int), - dispatch_message(u_char *, int, int, - struct qstream *, - struct sockaddr_in, int, - interface *); -static void stream_send(evContext, void *, int, - const void *, int, - const void *, int); -static int only_digits(const char *); - -static void init_needs(void), - handle_needs(void); - -#ifndef HAVE_CUSTOM -static void custom_init(void), - custom_shutdown(void); -#endif - -static void -usage() { - fprintf(stderr, -"Usage: named [-d #] [-q] [-r] [-v] [-f] [-p port] [[-b|-c] configfile]\n"); -#ifdef CAN_CHANGE_ID - fprintf(stderr, -" [-u (username|uid)] [-g (groupname|gid)]\n"); -#endif -#ifdef HAVE_CHROOT - fprintf(stderr, -" [-t directory]\n"); -#endif - exit(1); -} - -static char bad_p_option[] = -"-p remote/local obsolete; use 'listen-on' in config file to specify local"; - -static char bad_directory[] = "chdir failed for directory '%s': %s"; - -/*ARGSUSED*/ -int -main(int argc, char *argv[], char *envp[]) { - int n; - char *p; - int ch; - struct passwd *pw; - struct group *gr; - -#ifdef _AUX_SOURCE - set42sig(); -#endif - debugfile = savestr(_PATH_DEBUG, 1); - - user_id = getuid(); - group_id = getgid(); - - ns_port = htons(NAMESERVER_PORT); - desired_debug = debug; - - /* BSD has a better random number generator but it's not clear - * that we need it here. - */ - gettime(&tt); - srand(((unsigned)getpid()) + (unsigned)tt.tv_usec); - - (void) umask(022); - - /* Save argv[] before getopt() destroys it -- needed for execvp(). */ - saved_argv = malloc(sizeof(char *) * (argc + 1)); - INSIST(saved_argv != NULL); - for (n = 0; n < argc; n++) { - saved_argv[n] = strdup(argv[n]); - INSIST(saved_argv[n] != NULL); - } - saved_argv[argc] = NULL; - /* XXX we need to free() this for clean shutdowns. */ - - while ((ch = getopt(argc, argv, "b:c:d:g:p:t:u:vw:qrf")) != -1) { - switch (ch) { - case 'b': - case 'c': - if (conffile != NULL) - freestr(conffile); - conffile = savestr(optarg, 1); - break; - - case 'd': - desired_debug = atoi(optarg); - if (desired_debug <= 0) - desired_debug = 1; - break; - - case 'p': - /* use nonstandard port number. - * usage: -p remote/local - * remote is the port number to which - * we send queries. local is the port - * on which we listen for queries. - * local defaults to same as remote. - */ - ns_port = htons((u_int16_t) atoi(optarg)); - p = strchr(optarg, '/'); - if (p) { - syslog(LOG_WARNING, bad_p_option); - fprintf(stderr, bad_p_option); - fputc('\n', stderr); - } - break; - - case 'w': - if (chdir(optarg) < 0) { - syslog(LOG_CRIT, bad_directory, optarg, - strerror(errno)); - fprintf(stderr, bad_directory, optarg, - strerror(errno)); - fputc('\n', stderr); - exit(1); - } - break; -#ifdef QRYLOG - case 'q': - qrylog = 1; - break; -#endif - - case 'r': - ns_setoption(OPTION_NORECURSE); - break; - - case 'f': - foreground = 1; - break; - - case 't': - chroot_dir = savestr(optarg, 1); - break; - - case 'v': - fprintf(stdout, "%s\n", Version); - exit(0); - -#ifdef CAN_CHANGE_ID - case 'u': - user_name = savestr(optarg, 1); - if (only_digits(user_name)) - user_id = atoi(user_name); - else { - pw = getpwnam(user_name); - if (pw == NULL) { - fprintf(stderr, - "user \"%s\" unknown\n", - user_name); - exit(1); - } - user_id = pw->pw_uid; - if (group_name == NULL) { - char name[256]; - - sprintf(name, "%lu", - (u_long)pw->pw_gid); - group_name = savestr(name, 1); - group_id = pw->pw_gid; - } - } - break; - - case 'g': - if (group_name != NULL) - freestr(group_name); - group_name = savestr(optarg, 1); - if (only_digits(group_name)) - group_id = atoi(group_name); - else { - gr = getgrnam(group_name); - if (gr == NULL) { - fprintf(stderr, - "group \"%s\" unknown\n", - group_name); - exit(1); - } - group_id = gr->gr_gid; - } - break; -#endif /* CAN_CHANGE_ID */ - - case '?': - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (argc) { - if (conffile != NULL) - freestr(conffile); - conffile = savestr(*argv, 1); - argc--, argv++; - } - if (argc) - usage(); - - if (conffile == NULL) - conffile = savestr(_PATH_CONF, 1); - - /* - * Make sure we don't inherit any open descriptors - * other than those that daemon() can deal with. - */ - for (n = sysconf(_SC_OPEN_MAX) - 1; n >= 0; n--) - if (n != STDIN_FILENO && - n != STDOUT_FILENO && - n != STDERR_FILENO) - (void) close(n); - - /* - * Chroot if desired. - */ - if (chroot_dir != NULL) { -#ifdef HAVE_CHROOT - if (chroot(chroot_dir) < 0) { - fprintf(stderr, "chroot %s failed: %s\n", chroot_dir, - strerror(errno)); - exit(1); - } - if (chdir("/") < 0) { - fprintf(stderr, "chdir(\"/\") failed: %s\n", - strerror(errno)); - exit(1); - } -#else - fprintf(stderr, "warning: chroot() not available\n"); - freestr(chroot_dir); - chroot_dir = NULL; -#endif - } - - /* Establish global event context. */ - evCreate(&ev); - - /* Establish global resolver context. */ - res_ninit(&res); - res.options &= ~(RES_DEFNAMES | RES_DNSRCH | RES_RECURSE); - - /* - * Set up logging. - */ - n = LOG_PID; -#ifdef LOG_NOWAIT - n |= LOG_NOWAIT; -#endif -#ifdef LOG_NDELAY - n |= LOG_NDELAY; -#endif -#if defined(LOG_CONS) && defined(USE_LOG_CONS) - n |= LOG_CONS; -#endif -#ifdef SYSLOG_42BSD - openlog("named", n); -#else - openlog("named", n, LOG_DAEMON); -#endif - - init_logging(); - set_assertion_failure_callback(ns_assertion_failed); - -#ifdef DEBUG - use_desired_debug(); -#endif - - /* Perform system-dependent initialization */ - custom_init(); - - init_needs(); - init_signals(); - - ns_notice(ns_log_default, "starting. %s", Version); - - /* - * Initialize and load database. - */ - gettime(&tt); - buildservicelist(); - buildprotolist(); - ns_init(conffile); - time(&boottime); - resettime = boottime; - - nsid_init(); - - /* - * Fork and go into background now that - * we've done any slow initialization - * and are ready to answer queries. - */ - - if (foreground == 0) { - if (daemon(1, 0)) - ns_panic(ns_log_default, 1, "daemon: %s", - strerror(errno)); - update_pid_file(); - } - - /* Check that udp checksums are on. */ - ns_udp(); - - /* - * We waited until now to log this because we wanted logging to - * be set up the way the user prefers. - */ - if (chroot_dir != NULL) - ns_info(ns_log_security, "chrooted to %s", chroot_dir); - -#ifdef CAN_CHANGE_ID - /* - * Set user and group if desired. - */ - if (group_name != NULL) { - if (setgid(group_id) < 0) - ns_panic(ns_log_security, 1, "setgid(%s): %s", - group_name, strerror(errno)); - ns_info(ns_log_security, "group = %s", group_name); - } - if (user_name != NULL) { - if (getuid() == 0 && initgroups(user_name, group_id) < 0) - ns_panic(ns_log_security, 1, "initgroups(%s, %d): %s", - user_name, (int)group_id, strerror(errno)); - endgrent(); - endpwent(); - if (setuid(user_id) < 0) - ns_panic(ns_log_security, 1, "setuid(%s): %s", - user_name, strerror(errno)); - ns_info(ns_log_security, "user = %s", user_name); - if (user_id != 0) - iflist_dont_rescan++; - } -#endif /* CAN_CHANGE_ID */ - - ns_notice(ns_log_default, "Ready to answer queries."); - gettime(&tt); - prime_cache(); - while (!needs_exit) { - evEvent event; - - ns_debug(ns_log_default, 15, "main loop"); - if (needs != 0) - handle_needs(); - else if (evGetNext(ev, &event, EV_WAIT) != -1) - INSIST_ERR(evDispatch(ev, event) != -1); - else - INSIST_ERR(errno == EINTR); - } - ns_info(ns_log_default, "named shutting down"); -#ifdef BIND_UPDATE - dynamic_about_to_exit(); -#endif - if (server_options && server_options->pid_filename) - (void)unlink(server_options->pid_filename); - ns_logstats(ev, NULL, evNowTime(), evConsTime(0, 0)); - - if (NS_OPTION_P(OPTION_DEALLOC_ON_EXIT)) - deallocate_everything(); - else - shutdown_configuration(); - - /* Cleanup for system-dependent stuff */ - custom_shutdown(); - - return (0); -} - -#ifndef IP_OPT_BUF_SIZE -/* arbitrary size */ -#define IP_OPT_BUF_SIZE 50 -#endif - -static void -stream_accept(evContext lev, void *uap, int rfd, - const void *lav, int lalen, - const void *rav, int ralen) -{ - interface *ifp = uap; - struct qstream *sp; - struct iovec iov; - int len, n; - const int on = 1; -#ifdef IP_OPTIONS /* XXX */ - u_char ip_opts[IP_OPT_BUF_SIZE]; -#endif - const struct sockaddr_in *la, *ra; - - la = (const struct sockaddr_in *)lav; - ra = (const struct sockaddr_in *)rav; - - INSIST(ifp != NULL); - - if (rfd < 0) { - switch (errno) { - case EINTR: - case EAGAIN: -#if (EWOULDBLOCK != EAGAIN) - case EWOULDBLOCK: -#endif - case ECONNABORTED: -#ifdef EPROTO - case EPROTO: -#endif - case EHOSTUNREACH: - case EHOSTDOWN: - case ENETUNREACH: - case ENETDOWN: - case ECONNREFUSED: -#ifdef ENONET - case ENONET: -#endif - /* - * These errors are expected and harmless, so - * we ignore them. - */ - return; - case EBADF: - case ENOTSOCK: - case EFAULT: - /* - * If one these happens, we're broken. - */ - ns_panic(ns_log_default, 1, "accept: %s", - strerror(errno)); - case EMFILE: - /* - * If we're out of file descriptors, find the least - * busy fd and close it. Then we'll return to the - * eventlib which will call us right back. - */ - if (streamq) { - struct qstream *nextsp; - struct qstream *candidate = NULL; - time_t lasttime, maxctime = 0; - - for (sp = streamq; sp; sp = nextsp) { - nextsp = sp->s_next; - if (sp->s_refcnt) - continue; - gettime(&tt); - lasttime = tt.tv_sec - sp->s_time; - if (lasttime >= VQEXPIRY) - sq_remove(sp); - else if (lasttime > maxctime) { - candidate = sp; - maxctime = lasttime; - } - } - if (candidate) - sq_remove(candidate); - return; - } - /* fall through */ - default: - /* - * Either we got an error we didn't expect, or we - * got EMFILE and didn't have anything left to close. - * Log it and press on. - */ - ns_info(ns_log_default, "accept: %s", strerror(errno)); - return; - } - } - - /* Condition the socket. */ - -#ifndef CANNOT_SET_SNDBUF - if (setsockopt(rfd, SOL_SOCKET, SO_SNDBUF, - (char*)&sbufsize, sizeof sbufsize) < 0) { - ns_info(ns_log_default, "setsockopt(rfd, SO_SNDBUF, %d): %s", - sbufsize, strerror(errno)); - (void) close(rfd); - return; - } -#endif - if (setsockopt(rfd, SOL_SOCKET, SO_KEEPALIVE, - (char *)&on, sizeof on) < 0) { - ns_info(ns_log_default, "setsockopt(rfd, KEEPALIVE): %s", - strerror(errno)); - (void) close(rfd); - return; - } - - if ((n = fcntl(rfd, F_GETFL, 0)) == -1) { - ns_info(ns_log_default, "fcntl(rfd, F_GETFL): %s", - strerror(errno)); - (void) close(rfd); - return; - } - if (fcntl(rfd, F_SETFL, n|PORT_NONBLOCK) == -1) { - ns_info(ns_log_default, "fcntl(rfd, NONBLOCK): %s", - strerror(errno)); - (void) close(rfd); - return; - } - - /* - * We don't like IP options. Turn them off if the connection came in - * with any. log this event since it usually indicates a security - * problem. - */ -#if defined(IP_OPTIONS) /* XXX */ - len = sizeof ip_opts; - if (getsockopt(rfd, IPPROTO_IP, IP_OPTIONS, - (char *)ip_opts, &len) < 0) { - ns_info(ns_log_default, "getsockopt(rfd, IP_OPTIONS): %s", - strerror(errno)); - (void) close(rfd); - return; - } - if (len != 0) { - nameserIncr(ra->sin_addr, nssRcvdOpts); - if (!haveComplained(ina_ulong(ra->sin_addr), - (u_long)"rcvd ip options")) { - ns_info(ns_log_default, - "rcvd IP_OPTIONS from %s (ignored)", - sin_ntoa(*ra)); - } - if (setsockopt(rfd, IPPROTO_IP, IP_OPTIONS, NULL, 0) < 0) { - ns_info(ns_log_default, "setsockopt(!IP_OPTIONS): %s", - strerror(errno)); - (void) close(rfd); - } - } -#endif - - /* Create and populate a qsp for this socket. */ - if ((sp = sq_add()) == NULL) { - (void) close(rfd); - return; - } - sp->s_rfd = rfd; /* stream file descriptor */ - gettime(&tt); - sp->s_time = tt.tv_sec; /* last transaction time */ - sp->s_from = *ra; /* address to respond to */ - sp->s_ifp = ifp; - INSIST(sizeof sp->s_temp >= INT16SZ); - iov = evConsIovec(sp->s_temp, INT16SZ); - INSIST_ERR(evRead(lev, rfd, &iov, 1, stream_getlen, sp, &sp->evID_r) - != -1); - sp->flags |= STREAM_READ_EV; -#ifdef DEBUG - if (debug) - ns_info(ns_log_default, "IP/TCP connection from %s (fd %d)", - sin_ntoa(sp->s_from), rfd); -#endif -} - -int -tcp_send(struct qinfo *qp) { - struct qstream *sp; - int on = 1; - - ns_debug(ns_log_default, 1, "tcp_send"); - if ((sp = sq_add()) == NULL) { - return (SERVFAIL); - } - if ((sp->s_rfd = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1) { - sq_remove(sp); - return (SERVFAIL); - } - if (sp->s_rfd > evHighestFD(ev)) { - sq_remove(sp); - return (SERVFAIL); - } - if (fcntl(sp->s_rfd, F_SETFD, 1) < 0) { - sq_remove(sp); - return (SERVFAIL); - } - if (sq_openw(sp, qp->q_msglen + INT16SZ) == -1) { - sq_remove(sp); - return (SERVFAIL); - } - if (sq_write(sp, qp->q_msg, qp->q_msglen) == -1) { - sq_remove(sp); - return (SERVFAIL); - } - - if (setsockopt(sp->s_rfd, SOL_SOCKET, SO_KEEPALIVE, - (char*)&on, sizeof(on)) < 0) - ns_info(ns_log_default, - "tcp_send: setsockopt(rfd, SO_KEEPALIVE): %s", - strerror(errno)); - gettime(&tt); - sp->s_size = -1; - sp->s_time = tt.tv_sec; /* last transaction time */ - sp->s_refcnt = 1; - sp->flags |= STREAM_DONE_CLOSE; - sp->s_from = qp->q_addr[qp->q_curaddr].ns_addr; - if (evConnect(ev, sp->s_rfd, &sp->s_from, sizeof(sp->s_from), - stream_send, sp, &sp->evID_c) == -1) { - sq_remove(sp); - return (SERVFAIL); - } - sp->flags |= STREAM_CONNECT_EV; - return (NOERROR); -} - -static void -stream_send(evContext lev, void *uap, int fd, const void *la, int lalen, - const void *ra, int ralen) { - struct qstream *sp = uap; - - ns_debug(ns_log_default, 1, "stream_send"); - - sp->flags &= ~STREAM_CONNECT_EV; - - if (fd == -1) { - /* connect failed */ - sq_remove(sp); - return; - } - if (evSelectFD(ev, sp->s_rfd, EV_WRITE, - stream_write, sp, &sp->evID_w) < 0) { - sq_remove(sp); - return; - } - sp->flags |= STREAM_WRITE_EV; -} - -static void -stream_write(evContext ctx, void *uap, int fd, int evmask) { - struct qstream *sp = uap; - struct iovec iov; - - ns_debug(ns_log_default, 1, "stream_write"); - INSIST(evmask & EV_WRITE); - INSIST(fd == sp->s_rfd); - if (sq_dowrite(sp) < 0) { - sq_remove(sp); - return; - } - if (sp->s_wbuf_free != sp->s_wbuf_send) - return; - - if (sp->s_wbuf) { - memput(sp->s_wbuf, sp->s_wbuf_end - sp->s_wbuf); - sp->s_wbuf_send = sp->s_wbuf_free = NULL; - sp->s_wbuf_end = sp->s_wbuf = NULL; - } - (void) evDeselectFD(ev, sp->evID_w); - sp->flags &= ~STREAM_WRITE_EV; - sp->s_refcnt = 0; - iov = evConsIovec(sp->s_temp, INT16SZ); - INSIST_ERR(evRead(ctx, fd, &iov, 1, stream_getlen, sp, &sp->evID_r) != - -1); - sp->flags |= STREAM_READ_EV; -} - -static void -stream_getlen(evContext lev, void *uap, int fd, int bytes) { - struct qstream *sp = uap; - struct iovec iov; - - sp->flags &= ~STREAM_READ_EV; - if (bytes != INT16SZ) { - /* - * bytes == 0 is normal EOF; see if something unusual - * happened. - */ - if (bytes < 0) { - /* - * ECONNRESET happens frequently and is not worth - * logging. - */ - if (errno != ECONNRESET) - ns_info(ns_log_default, - "stream_getlen(%s): %s", - sin_ntoa(sp->s_from), strerror(errno)); - } else if (bytes != 0) - ns_error(ns_log_default, - "stream_getlen(%s): unexpected byte count %d", - sin_ntoa(sp->s_from), bytes); - sq_remove(sp); - return; - } - - /* - * Unpack the size, allocate memory for the query. This is - * tricky since in a low memory situation with possibly very - * large (64KB) queries, we want to make sure we can read at - * least the header since we need it to send back a SERVFAIL - * (owing to the out-of-memory condition). - */ - sp->s_size = ns_get16(sp->s_temp); - ns_debug(ns_log_default, 5, "stream message: %d bytes", sp->s_size); - if (sp->s_size < HFIXEDSZ) { - ns_error(ns_log_default, - "stream_getlen(%s): request too small", - sin_ntoa(sp->s_from)); - sq_remove(sp); - return; - } - - if (!(sp->flags & STREAM_MALLOC)) { - sp->s_bufsize = 64*1024-1; /* maximum tcp message size */ - sp->s_buf = (u_char *)memget(sp->s_bufsize); - if (sp->s_buf != NULL) - sp->flags |= STREAM_MALLOC; - else { - sp->s_buf = sp->s_temp; - sp->s_bufsize = HFIXEDSZ; - } - } - - iov = evConsIovec(sp->s_buf, (sp->s_size <= sp->s_bufsize) ? - sp->s_size : sp->s_bufsize); - if (evRead(lev, sp->s_rfd, &iov, 1, stream_getmsg, sp, &sp->evID_r) - == -1) - ns_panic(ns_log_default, 1, "evRead(fd %d): %s", - (void *)sp->s_rfd, strerror(errno)); - sp->flags |= STREAM_READ_EV; -} - -static void -stream_getmsg(evContext lev, void *uap, int fd, int bytes) { - struct qstream *sp = uap; - - sp->flags &= ~STREAM_READ_EV; - if (bytes == -1) { - ns_info(ns_log_default, "stream_getmsg(%s): %s", - sin_ntoa(sp->s_from), strerror(errno)); - sq_remove(sp); - return; - } - - gettime(&tt); - sp->s_time = tt.tv_sec; - - if (ns_wouldlog(ns_log_default,5)) { - ns_debug(ns_log_default, 5, "sp %#x rfd %d size %d time %d next %#x", - sp, sp->s_rfd, sp->s_size, sp->s_time, sp->s_next); - ns_debug(ns_log_default, 5, "\tbufsize %d bytes %d", sp->s_bufsize, - bytes); - } - - /* - * Do we have enough memory for the query? If not, and if we have a - * query id, then we will send a SERVFAIL error back to the client. - */ - if (bytes != sp->s_size) { - HEADER *hp = (HEADER *)sp->s_buf; - - hp->qr = 1; - hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0); - hp->ancount = htons(0); - hp->qdcount = htons(0); - hp->nscount = htons(0); - hp->arcount = htons(0); - hp->rcode = SERVFAIL; - writestream(sp, sp->s_buf, HFIXEDSZ); - sp->flags |= STREAM_DONE_CLOSE; - return; - } - - nameserIncr(sp->s_from.sin_addr, nssRcvdTCP); - sq_query(sp); - dispatch_message(sp->s_buf, bytes, sp->s_bufsize, sp, sp->s_from, -1, - sp->s_ifp); -} - -static void -datagram_read(evContext lev, void *uap, int fd, int evmask) { - interface *ifp = uap; - struct sockaddr_in from; - int from_len = sizeof from; - int n, nudp; - union { - HEADER h; /* Force alignment of 'buf'. */ - u_char buf[PACKETSZ+1]; - } u; - - tt = evTimeVal(evNowTime()); - nudp = 0; - - more: - n = recvfrom(fd, (char *)u.buf, sizeof u.buf, 0, - (struct sockaddr *)&from, &from_len); - - if (n < 0) { - switch (errno) { - case EINTR: - case EAGAIN: -#if (EWOULDBLOCK != EAGAIN) - case EWOULDBLOCK: -#endif - case EHOSTUNREACH: - case EHOSTDOWN: - case ENETUNREACH: - case ENETDOWN: - case ECONNREFUSED: -#ifdef ENONET - case ENONET: -#endif - /* - * These errors are expected and harmless, so we - * ignore them. - */ - return; - default: - /* - * An error we don't expect. Log it and press - * on. - */ - ns_info(ns_log_default, "recvfrom: %s", - strerror(errno)); - return; - } - } - - /* Handle bogosity on systems that need it. */ - if (n == 0) - return; - - if (ns_wouldlog(ns_log_default, 1)) { - ns_debug(ns_log_default, 1, "datagram from %s, fd %d, len %d", - sin_ntoa(from), fd, n); - } - - if (n > PACKETSZ) { - /* - * The message is too big. It's probably a response to - * one of our questions, so we truncate it and press on. - */ - n = trunc_adjust(u.buf, PACKETSZ, PACKETSZ); - ns_debug(ns_log_default, 1, "truncated oversize UDP packet"); - } - - dispatch_message(u.buf, n, PACKETSZ, NULL, from, fd, ifp); - if (++nudp < nudptrans) - goto more; -} - -static void -dispatch_message(u_char *msg, int msglen, int buflen, struct qstream *qsp, - struct sockaddr_in from, int dfd, interface *ifp) -{ - HEADER *hp = (HEADER *)msg; - - if (msglen < HFIXEDSZ) { - ns_debug(ns_log_default, 1, "dropping undersize message"); - if (qsp) { - qsp->flags |= STREAM_DONE_CLOSE; - sq_done(qsp); - } - return; - } - - if (server_options->blackhole_acl != NULL && - ip_match_address(server_options->blackhole_acl, - from.sin_addr) == 1) { - ns_debug(ns_log_default, 1, - "dropping blackholed %s from %s", - hp->qr ? "response" : "query", - sin_ntoa(from)); - if (qsp) { - qsp->flags |= STREAM_DONE_CLOSE; - sq_done(qsp); - } - return; - } - - /* Drop UDP packets from port zero. They are invariable forged. */ - if (qsp == NULL && ntohs(from.sin_port) == 0) { - ns_notice(ns_log_security, - "dropping source port zero packet from %s", - sin_ntoa(from)); - return; - } - - if (hp->qr) { - ns_resp(msg, msglen, from, qsp); - if (qsp) - sq_done(qsp); - /* Now is a safe time for housekeeping. */ - if (needs_prime_cache) - prime_cache(); - } else if (ifp != NULL) - ns_req(msg, msglen, buflen, qsp, from, dfd); - else { - ns_notice(ns_log_security, - "refused query on non-query socket from %s", - sin_ntoa(from)); - if (qsp) { - qsp->flags |= STREAM_DONE_CLOSE; - sq_done(qsp); - } - /* XXX Send refusal here. */ - } -} - -void -getnetconf(int periodic_scan) { - struct ifconf ifc; - struct ifreq ifreq; - struct in_addr ina; - interface *ifp; - char *buf, *cp, *cplim; - static int bufsiz = 4095; - time_t my_generation = time(NULL); - int s, cpsize, n; - int found; - listen_info li; - ip_match_element ime; - u_char *mask_ptr; - struct in_addr mask; - - if (iflist_initialized) { - if (iflist_dont_rescan) - return; - } else { - INIT_LIST(iflist); - iflist_initialized = 1; - } - - ns_debug(ns_log_default, 1, "getnetconf(generation %lu)", - (u_long)my_generation); - - /* Get interface list from system. */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - if (!periodic_scan) - ns_panic(ns_log_default, 1, "socket(SOCK_RAW): %s", - strerror(errno)); - ns_error(ns_log_default, "socket(SOCK_RAW): %s", - strerror(errno)); - return; - } - - if (local_addresses != NULL) - free_ip_match_list(local_addresses); - local_addresses = new_ip_match_list(); - if (local_networks != NULL) - free_ip_match_list(local_networks); - local_networks = new_ip_match_list(); - - for (;;) { - buf = memget(bufsiz); - if (!buf) - ns_panic(ns_log_default, 1, - "memget(interface)", NULL); - ifc.ifc_len = bufsiz; - ifc.ifc_buf = buf; -#ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF - /* - * This is a fix for IRIX OS in which the call to ioctl with - * the flag SIOCGIFCONF may not return an entry for all the - * interfaces like most flavors of Unix. - */ - if (emul_ioctl(&ifc) >= 0) - break; -#else - if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) { - /* - * Some OS's just return what will fit rather - * than set EINVAL if the buffer is too small - * to fit all the interfaces in. If - * ifc.ifc_len is too near to the end of the - * buffer we will grow it just in case and - * retry. - */ - if (ifc.ifc_len + 2 * sizeof(ifreq) < bufsiz) - break; - } -#endif - if ((n == -1) && errno != EINVAL) - ns_panic(ns_log_default, 1, - "get interface configuration: %s", - strerror(errno)); - - if (bufsiz > 1000000) - ns_panic(ns_log_default, 1, - "get interface configuration: maximum buffer size exceeded"); - memput(buf, bufsiz); - bufsiz += 4096; - } - - ns_debug(ns_log_default, 2, "getnetconf: SIOCGIFCONF: ifc_len = %d", - ifc.ifc_len); - - /* Parse system's interface list and open some sockets. */ - cplim = buf + ifc.ifc_len; /* skip over if's with big ifr_addr's */ - for (cp = buf; cp < cplim; cp += cpsize) { - memcpy(&ifreq, cp, sizeof ifreq); -#ifdef HAVE_SA_LEN -#ifdef FIX_ZERO_SA_LEN - if (ifreq.ifr_addr.sa_len == 0) - ifreq.ifr_addr.sa_len = 16; -#endif -#ifdef HAVE_MINIMUM_IFREQ - ns_debug(ns_log_default, 2, "%s sa_len = %d", - ifreq.ifr_name, (int)ifreq.ifr_addr.sa_len); - cpsize = sizeof ifreq; - if (ifreq.ifr_addr.sa_len > sizeof (struct sockaddr)) - cpsize += (int)ifreq.ifr_addr.sa_len - - (int)(sizeof (struct sockaddr)); -#else - cpsize = sizeof ifreq.ifr_name + ifreq.ifr_addr.sa_len; -#endif /* HAVE_MINIMUM_IFREQ */ -#elif defined SIOCGIFCONF_ADDR - cpsize = sizeof ifreq; -#else - cpsize = sizeof ifreq.ifr_name; - if (ioctl(s, SIOCGIFADDR, (char *)&ifreq) < 0) { - ns_notice(ns_log_default, - "get interface addr (%s): %s", - ifreq.ifr_name, strerror(errno)); - continue; - } -#endif - if (ifreq.ifr_addr.sa_family != AF_INET) { - ns_debug(ns_log_default, 2, - "getnetconf: %s AF %d != INET", - ifreq.ifr_name, ifreq.ifr_addr.sa_family); - continue; - } - ina = ina_get((u_char *)&((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr); - ns_debug(ns_log_default, 1, - "getnetconf: considering %s [%s]", - ifreq.ifr_name, inet_ntoa(ina)); - /* - * Don't test IFF_UP, packets may still be received at this - * address if any other interface is up. - */ - if (ina_hlong(ina) == INADDR_ANY) { - ns_debug(ns_log_default, 2, - "getnetconf: INADDR_ANY, ignoring."); - continue; - } - - INSIST(server_options != NULL); - INSIST(server_options->listen_list != NULL); - - found=0; - for (li = server_options->listen_list->first; - li != NULL; - li = li->next) { - if (ip_match_address(li->list, ina) > 0) { - found++; - /* - * Look for an already existing source - * interface address/port pair. - * This happens mostly when reinitializing. - * Also, if the machine has multiple point to - * point interfaces, then the local address - * may appear more than once. - */ - ifp = if_find(ina, li->port); - if (ifp != NULL) { - ns_debug(ns_log_default, 1, - "dup interface addr [%s].%u (%s)", - inet_ntoa(ina), - ntohs(li->port), - ifreq.ifr_name); - ifp->gen = my_generation; - continue; - } - - ifp = (interface *)memget(sizeof *ifp); - if (!ifp) - ns_panic(ns_log_default, 1, - "memget(interface)", NULL); - memset(ifp, 0, sizeof *ifp); - APPEND(iflist, ifp, link); - ifp->addr = ina; - ifp->port = li->port; - ifp->gen = my_generation; - ifp->flags = 0; - ifp->dfd = -1; - ifp->sfd = -1; - if (opensocket_d(ifp) < 0 || - opensocket_s(ifp) < 0) { - dq_remove(ifp); - found = 0; - break; - } - ns_info(ns_log_default, - "listening on [%s].%u (%s)", - inet_ntoa(ina), ntohs(li->port), - ifreq.ifr_name); - } - } - if (!found) - ns_debug(ns_log_default, 1, - "not listening on addr [%s] (%s)", - inet_ntoa(ina), ifreq.ifr_name); - - /* - * Add this interface's address to the list of local - * addresses if we haven't added it already. - */ - if (ip_match_address(local_addresses, ina) < 0) { - ime = new_ip_match_pattern(ina, 32); - add_to_ip_match_list(local_addresses, ime); - } - - /* - * Get interface flags. - */ - if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { - ns_notice(ns_log_default, "get interface flags: %s", - strerror(errno)); - continue; - } - - if ((ifreq.ifr_flags & IFF_POINTOPOINT)) { - /* - * The local network for a PPP link is just the - * two ends of the link, so for each endpoint we - * add a pattern that will only match the endpoint. - */ - if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { - ns_notice(ns_log_default, "get dst addr: %s", - strerror(errno)); - continue; - } - - mask.s_addr = htonl(INADDR_BROADCAST); - - /* - * Our end. - * - * Only add it if we haven't seen it before. - */ - if (ip_match_network(local_networks, ina, mask) < 0) { - ime = new_ip_match_pattern(ina, 32); - add_to_ip_match_list(local_networks, ime); - } - - /* - * The other end. - */ - ina = ((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr; - /* - * Only add it if we haven't seen it before. - */ - if (ip_match_network(local_networks, ina, mask) < 0) { - ime = new_ip_match_pattern(ina, 32); - add_to_ip_match_list(local_networks, ime); - } - } else { - /* - * Add this interface's network and netmask to the - * list of local networks. - */ - -#ifdef SIOCGIFNETMASK /* XXX */ - if (ioctl(s, SIOCGIFNETMASK, (char *)&ifreq) < 0) { - ns_notice(ns_log_default, "get netmask: %s", - strerror(errno)); - continue; - } - /* - * Use ina_get because the ifreq structure might not - * be aligned. - */ - mask_ptr = (u_char *) - &((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr; - mask = ina_get(mask_ptr); -#else - mask = net_mask(ina); -#endif - - ina.s_addr &= mask.s_addr; /* make network address */ - - /* - * Only add it if we haven't seen it before. - */ - if (ip_match_network(local_networks, ina, mask) < 0) { - ime = new_ip_match_mask(ina, mask); - add_to_ip_match_list(local_networks, ime); - } - } - } - close(s); - memput(buf, bufsiz); - - ns_debug(ns_log_default, 7, "local addresses:"); - dprint_ip_match_list(ns_log_default, local_addresses, 2, "", ""); - ns_debug(ns_log_default, 7, "local networks:"); - dprint_ip_match_list(ns_log_default, local_networks, 2, "", ""); - - /* - * now go through the iflist and delete anything that - * does not have the current generation number. this is - * how we catch interfaces that go away or change their - * addresses. note that 0.0.0.0 is the wildcard element - * and should never be deleted by this code. - */ - dq_remove_gen(my_generation); - - if (EMPTY(iflist)) - ns_warning(ns_log_default, "not listening on any interfaces"); -} - -/* opensocket_d(ifp) - * Open datagram socket bound to interface address. - * Returns: - * 0 on success. - * -1 on failure. - */ -static int -opensocket_d(interface *ifp) { - struct sockaddr_in nsa; - const int on = 1; - int m, n; - int fd; - - memset(&nsa, 0, sizeof nsa); - nsa.sin_family = AF_INET; - nsa.sin_addr = ifp->addr; - nsa.sin_port = ifp->port; - - if ((ifp->dfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - ns_error(ns_log_default, "socket(SOCK_DGRAM): %s", - strerror(errno)); - return (-1); - } - if (ifp->dfd > evHighestFD(ev)) { - ns_error(ns_log_default, "socket too high: %d", ifp->dfd); - close(ifp->dfd); - return (-1); - } - if ((n = fcntl(ifp->dfd, F_GETFL, 0)) == -1) { - ns_info(ns_log_default, "fcntl(ifp->dfd, F_GETFL): %s", - strerror(errno)); - (void) close(ifp->dfd); - return (-1); - } - if (fcntl(ifp->dfd, F_SETFL, n|PORT_NONBLOCK) == -1) { - ns_info(ns_log_default, "fcntl(ifp->dfd, NONBLOCK): %s", - strerror(errno)); - (void) close(ifp->dfd); - return (-1); - } -#ifdef F_DUPFD /* XXX */ - /* - * Leave a space for stdio to work in. - */ - if ((fd = fcntl(ifp->dfd, F_DUPFD, 20)) != -1) { - close(ifp->dfd); - ifp->dfd = fd; - } else - ns_notice(ns_log_default, "fcntl(dfd, F_DUPFD, 20): %s", - strerror(errno)); -#endif - if (fcntl(ifp->dfd, F_SETFD, 1) < 0) { - ns_error(ns_log_default, "F_SETFD: %s", strerror(errno)); - close(ifp->dfd); - return (-1); - } - ns_debug(ns_log_default, 1, "ifp->addr %s d_dfd %d", - sin_ntoa(nsa), ifp->dfd); - if (setsockopt(ifp->dfd, SOL_SOCKET, SO_REUSEADDR, - (char *)&on, sizeof(on)) != 0) { - ns_notice(ns_log_default, "setsockopt(REUSEADDR): %s", - strerror(errno)); - /* XXX press on regardless, this is not too serious. */ - } -#ifdef SO_RCVBUF /* XXX */ - m = sizeof n; - if ((getsockopt(ifp->dfd, SOL_SOCKET, SO_RCVBUF, (char*)&n, &m) >= 0) - && (m == sizeof n) - && (n < drbufsize)) { - (void) setsockopt(ifp->dfd, SOL_SOCKET, SO_RCVBUF, - (char *)&drbufsize, sizeof drbufsize); - } -#endif /* SO_RCVBUF */ -#ifndef CANNOT_SET_SNDBUF - if (setsockopt(ifp->dfd, SOL_SOCKET, SO_SNDBUF, - (char*)&dsbufsize, sizeof dsbufsize) < 0) { - ns_info(ns_log_default, - "setsockopt(dfd=%d, SO_SNDBUF, %d): %s", - ifp->dfd, dsbufsize, strerror(errno)); - /* XXX press on regardless, this is not too serious. */ - } -#endif - if (bind(ifp->dfd, (struct sockaddr *)&nsa, sizeof nsa)) { - ns_error(ns_log_default, "bind(dfd=%d, %s): %s", - ifp->dfd, sin_ntoa(nsa), strerror(errno)); - return (-1); - } - if (evSelectFD(ev, ifp->dfd, EV_READ, datagram_read, ifp, - &ifp->evID_d) == -1) { - ns_error(ns_log_default, "evSelectFD(dfd=%d): %s", - ifp->dfd, strerror(errno)); - return (-1); - } - ifp->flags |= INTERFACE_FILE_VALID; - return (0); -} - -/* opensocket_s(ifp) - * Open stream (listener) socket bound to interface address. - * Returns: - * 0 on success. - * -1 on failure. - */ -static int -opensocket_s(interface *ifp) { - struct sockaddr_in nsa; - const int on = 1; - int n; - int fd; - - memset(&nsa, 0, sizeof nsa); - nsa.sin_family = AF_INET; - nsa.sin_addr = ifp->addr; - nsa.sin_port = ifp->port; - - /* - * Open stream (listener) port. - */ - n = 0; - again: - if ((ifp->sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - ns_error(ns_log_default, "socket(SOCK_STREAM): %s", - strerror(errno)); - return (-1); - } - if (ifp->sfd > evHighestFD(ev)) { - ns_error(ns_log_default, "socket too high: %d", ifp->sfd); - close(ifp->sfd); - return (-1); - } -#ifdef F_DUPFD /* XXX */ - /* - * Leave a space for stdio to work in. - */ - if ((fd = fcntl(ifp->sfd, F_DUPFD, 20)) != -1) { - close(ifp->sfd); - ifp->sfd = fd; - } else - ns_notice(ns_log_default, "fcntl(sfd, F_DUPFD, 20): %s", - strerror(errno)); -#endif - if (fcntl(ifp->sfd, F_SETFD, 1) < 0) { - ns_error(ns_log_default, "F_SETFD: %s", strerror(errno)); - close(ifp->sfd); - return (-1); - } - if (setsockopt(ifp->sfd, SOL_SOCKET, SO_REUSEADDR, - (char *)&on, sizeof on) != 0) { - ns_notice(ns_log_default, "setsockopt(REUSEADDR): %s", - strerror(errno)); - /* Consider that your first warning of trouble to come. */ - } - if (bind(ifp->sfd, (struct sockaddr *)&nsa, sizeof nsa) < 0) { - if (errno != EADDRINUSE || ++n > 4) { - if (errno == EADDRINUSE) - ns_error(ns_log_default, - "There may be a name server already running on %s", - sin_ntoa(nsa)); - else - ns_error(ns_log_default, - "bind(sfd=%d, %s): %s", ifp->sfd, - sin_ntoa(nsa), strerror(errno)); - return (-1); - } - - /* Retry opening the socket a few times */ - close(ifp->sfd); - ifp->sfd = -1; - sleep(30); - goto again; - } - if (evListen(ev, ifp->sfd, listenmax, stream_accept, ifp, &ifp->evID_s) - == -1) { - ns_error(ns_log_default, "evListen(sfd=%d): %s", - ifp->sfd, strerror(errno)); - return (-1); - } - ifp->flags |= INTERFACE_CONN_VALID; - return (0); -} - -/* opensocket_f() - * Open datagram socket bound to no particular interface; use for ns_forw - * and sysquery. - */ -void -opensocket_f() { - static struct sockaddr_in prev_qsrc; - static int been_here; - static interface *prev_ifp; - struct sockaddr_in nsa; - const int on = 1; - int n, need_close; - interface *ifp; - - need_close = 0; - if (been_here) { - if (prev_ifp != NULL) - prev_ifp->flags &= ~INTERFACE_FORWARDING; - else if (server_options->query_source.sin_port == htons(0) || - prev_qsrc.sin_addr.s_addr != - server_options->query_source.sin_addr.s_addr || - prev_qsrc.sin_port != - server_options->query_source.sin_port) - need_close = 1; - } else - ds = -1; - - been_here = 1; - INSIST(server_options != NULL); - - if (need_close) { - evDeselectFD(ev, ds_evID); - close(ds); - ds = -1; - } - - /* - * If we're already listening on the query_source address and port, - * we don't need to open another socket. We mark the interface, so - * we'll notice we're in trouble if it goes away. - */ - ifp = if_find(server_options->query_source.sin_addr, - server_options->query_source.sin_port); - if (ifp != NULL) { - ifp->flags |= INTERFACE_FORWARDING; - prev_ifp = ifp; - ds = ifp->dfd; - ns_info(ns_log_default, "forwarding source address is %s", - sin_ntoa(server_options->query_source)); - return; - } - - /* - * If we're already using the correct query source, we're done. - */ - if (ds >= 0) - return; - - prev_qsrc = server_options->query_source; - prev_ifp = NULL; - - if ((ds = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - ns_panic(ns_log_default, 1, "socket(SOCK_DGRAM): %s", - strerror(errno)); - if (ds > evHighestFD(ev)) - ns_panic(ns_log_default, 1, "socket too high: %d", ds); - if (fcntl(ds, F_SETFD, 1) < 0) - ns_panic(ns_log_default, 1, "F_SETFD: %s", strerror(errno)); - if (setsockopt(ds, SOL_SOCKET, SO_REUSEADDR, - (char *)&on, sizeof on) != 0) { - ns_notice(ns_log_default, "setsockopt(REUSEADDR): %s", - strerror(errno)); - /* XXX press on regardless, this is not too serious. */ - } - if (bind(ds, (struct sockaddr *)&server_options->query_source, - sizeof server_options->query_source) < 0) - ns_panic(ns_log_default, 0, "opensocket_f: bind(%s): %s", - sin_ntoa(server_options->query_source), - strerror(errno)); - - n = sizeof nsa; - if (getsockname(ds, (struct sockaddr *)&nsa, &n) < 0) - ns_panic(ns_log_default, 1, "opensocket_f: getsockaddr: %s", - strerror(errno)); - - ns_debug(ns_log_default, 1, "fwd ds %d addr %s", ds, sin_ntoa(nsa)); - ns_info(ns_log_default, "Forwarding source address is %s", - sin_ntoa(nsa)); - - if (evSelectFD(ev, ds, EV_READ, datagram_read, NULL, &ds_evID) == -1) - ns_panic(ns_log_default, 1, "evSelectFD(fd %d): %s", - (void *)ds, strerror(errno)); - /* XXX: should probably use a different FileFunc that only accepts - * responses, since requests on this socket make no sense. - */ -} - -static void -setdebug(int new_debug) { -#ifdef DEBUG - int old_debug; - - if (!new_debug) - ns_debug(ns_log_default, 1, "Debug off"); - old_debug = debug; - debug = new_debug; - log_option(log_ctx, LOG_OPTION_DEBUG, debug); - log_option(log_ctx, LOG_OPTION_LEVEL, debug); - evSetDebug(ev, debug, log_get_stream(eventlib_channel)); - if (debug) { - if (!old_debug) - open_special_channels(); - ns_debug(ns_log_default, 1, "Debug level %d", debug); - if (!old_debug) { - ns_debug(ns_log_default, 1, "Version = %s", Version); - ns_debug(ns_log_default, 1, "conffile = %s", conffile); - } - } -#endif -} - -/* -** Routines for managing stream queue -*/ - -static struct qstream * -sq_add() { - struct qstream *sqp; - - if (!(sqp = (struct qstream *)memget(sizeof *sqp))) { - ns_error(ns_log_default, "sq_add: memget: %s", - strerror(errno)); - return (NULL); - } - memset(sqp, 0, sizeof *sqp); - ns_debug(ns_log_default, 3, "sq_add(%#lx)", (u_long)sqp); - - sqp->flags = 0; - /* XXX should init other fields too? */ - sqp->s_next = streamq; - streamq = sqp; - return (sqp); -} - -/* sq_remove(qp) - * remove stream queue structure `qp'. - * no current queries may refer to this stream when it is removed. - * side effects: - * memory is deallocated. sockets are closed. lists are relinked. - */ -void -sq_remove(struct qstream *qp) { - struct qstream *qsp; - - ns_debug(ns_log_default, 2, "sq_remove(%#lx, %d) rfcnt=%d", - (u_long)qp, qp->s_rfd, qp->s_refcnt); - - if (qp->s_wbuf != NULL) { - memput(qp->s_wbuf, qp->s_wbuf_end - qp->s_wbuf); - qp->s_wbuf_send = qp->s_wbuf_free = NULL; - qp->s_wbuf_end = qp->s_wbuf = NULL; - } - if (qp->flags & STREAM_MALLOC) - memput(qp->s_buf, qp->s_bufsize); - if (qp->flags & STREAM_READ_EV) - INSIST_ERR(evCancelRW(ev, qp->evID_r) != -1); - if (qp->flags & STREAM_WRITE_EV) - INSIST_ERR(evDeselectFD(ev, qp->evID_w) != -1); - if (qp->flags & STREAM_CONNECT_EV) - INSIST_ERR(evCancelConn(ev, qp->evID_c) != -1); - if (qp->flags & STREAM_AXFR || qp->flags & STREAM_AXFRIXFR) - ns_freexfr(qp); - (void) close(qp->s_rfd); - if (qp == streamq) - streamq = qp->s_next; - else { - for (qsp = streamq; - qsp && (qsp->s_next != qp); - qsp = qsp->s_next) - (void)NULL; - if (qsp) - qsp->s_next = qp->s_next; - } - memput(qp, sizeof *qp); -} - -/* void - * sq_flush(allbut) - * call sq_remove() on all open streams except `allbut' - * side effects: - * global list `streamq' modified - * idiocy: - * is N^2 due to the scan inside of sq_remove() - */ -void -sq_flush(struct qstream *allbut) { - struct qstream *sp, *spnext; - - for (sp = streamq; sp != NULL; sp = spnext) { - spnext = sp->s_next; - if (sp != allbut) - sq_remove(sp); - } -} - -/* int - * sq_openw(qs, buflen) - * add a write buffer to a stream - * return: - * 0 = success - * -1 = failure (check errno) - */ -int -sq_openw(struct qstream *qs, int buflen) { -#ifdef DO_SO_LINGER /* XXX */ - static const struct linger ll = { 1, 120 }; -#endif - - INSIST(qs->s_wbuf == NULL); - qs->s_wbuf = (u_char *)memget(buflen); - if (qs->s_wbuf == NULL) - return (-1); - qs->s_wbuf_send = qs->s_wbuf; - qs->s_wbuf_free = qs->s_wbuf; - qs->s_wbuf_end = qs->s_wbuf + buflen; -#ifdef DO_SO_LINGER /* XXX */ - /* kernels that map pages for IO end up failing if the pipe is full - * at exit and we take away the final buffer. this is really a kernel - * bug but it's harmless on systems that are not broken, so... - */ - setsockopt(qs->s_rfd, SOL_SOCKET, SO_LINGER, (char *)&ll, sizeof ll); -#endif - return (0); -} - -/* static void - * sq_dowrite(qs) - * try to submit data to the system, remove it from our queue. - */ -static int -sq_dowrite(struct qstream *qs) { - if (qs->s_wbuf_free > qs->s_wbuf_send) { - int n = write(qs->s_rfd, qs->s_wbuf_send, - qs->s_wbuf_free - qs->s_wbuf_send); - INSIST(qs->s_wbuf != NULL); - if (n < 0) { - if (errno != EINTR && errno != EAGAIN -#if (EWOULDBLOCK != EAGAIN) - && errno != EWOULDBLOCK -#endif - ) - return (-1); - return (0); - } - qs->s_wbuf_send += n; - if (qs->s_wbuf_free > qs->s_wbuf_send) { - /* XXX: need some kind of delay here during which the - * socket will be deselected so we don't spin. - */ - n = qs->s_wbuf_free - qs->s_wbuf_send; - memmove(qs->s_wbuf, qs->s_wbuf_send, n); - qs->s_wbuf_send = qs->s_wbuf; - qs->s_wbuf_free = qs->s_wbuf + n; - } - } - if (qs->s_wbuf_free == qs->s_wbuf_send) - qs->s_wbuf_free = qs->s_wbuf_send = qs->s_wbuf; - return (0); -} - -/* void - * sq_flushw(qs) - * called when the socket becomes writable and we want to flush our - * buffers and the system's socket buffers. use as a closure with - * sq_writeh(). - */ -void -sq_flushw(struct qstream *qs) { - if (qs->s_wbuf_free == qs->s_wbuf_send) { - sq_writeh(qs, NULL); - sq_done(qs); - } -} - -/* static void - * sq_writable(ctx, uap, fd, evmask) - * glue between eventlib closures and qstream closures - */ -static void -sq_writable(evContext ctx, void *uap, int fd, int evmask) { - struct qstream *qs = uap; - - INSIST(evmask & EV_WRITE); - INSIST(fd == qs->s_rfd); - if (sq_dowrite(qs) < 0) { - sq_remove(qs); - return; - } - if (qs->s_wbuf_closure - && qs->s_wbuf_end - qs->s_wbuf_free >= HFIXEDSZ+2) /* XXX guess */ - (*qs->s_wbuf_closure)(qs); - if (sq_dowrite(qs) < 0) { - sq_remove(qs); - return; - } -} - -/* int - * sq_writeh(qs, closure) - * register a closure to be called when a stream becomes writable - * return: - * 0 = success - * -1 = failure (check errno) - */ -int -sq_writeh(struct qstream *qs, sq_closure c) { - if (c) { - if (!qs->s_wbuf_closure) { - if (evSelectFD(ev, qs->s_rfd, EV_WRITE, - sq_writable, qs, &qs->evID_w) < 0) { - return (-1); - } - qs->flags |= STREAM_WRITE_EV; - } - } else { - (void) evDeselectFD(ev, qs->evID_w); - qs->flags &= ~STREAM_WRITE_EV; - } - qs->s_wbuf_closure = c; - return (0); -} - -/* int - * sq_write(qs, buf, len) - * queue a message onto the stream, prepended by a two byte length field - * return: - * 0 = success - * -1 = failure (check errno; E2BIG means we can't handle this right now) - */ -int -sq_write(struct qstream *qs, const u_char *buf, int len) { - INSIST(qs->s_wbuf != NULL); - if (NS_INT16SZ + len > qs->s_wbuf_end - qs->s_wbuf_free) { - if (sq_dowrite(qs) < 0) - return (-1); - if (NS_INT16SZ + len > qs->s_wbuf_end - qs->s_wbuf_free) { - errno = E2BIG; - return (-1); - } - } - __putshort(len, qs->s_wbuf_free); - qs->s_wbuf_free += NS_INT16SZ; - memcpy(qs->s_wbuf_free, buf, len); - qs->s_wbuf_free += len; - return (0); -} - -/* int - * sq_here(sp) - * determine whether stream 'sp' is still on the streamq - * return: - * boolean: is it here? - */ -static int -sq_here(struct qstream *sp) { - struct qstream *t; - - for (t = streamq; t != NULL; t = t->s_next) - if (t == sp) - return (1); - return (0); -} - -/* - * Initiate query on stream; - * mark as referenced and stop selecting for input. - */ -static void -sq_query(struct qstream *sp) { - sp->s_refcnt++; -} - -/* - * Note that the current request on a stream has completed, - * and that we should continue looking for requests on the stream. - */ -void -sq_done(struct qstream *sp) { - struct iovec iov; - - if (sp->s_wbuf != NULL) { - INSIST(sp->s_wbuf_send == sp->s_wbuf_free); - memput(sp->s_wbuf, sp->s_wbuf_end - sp->s_wbuf); - sp->s_wbuf_send = sp->s_wbuf_free = NULL; - sp->s_wbuf_end = sp->s_wbuf = NULL; - } - if (sp->flags & STREAM_AXFR || sp->flags & STREAM_AXFRIXFR) - ns_freexfr(sp); - sp->s_refcnt = 0; - sp->s_time = tt.tv_sec; - if (sp->flags & STREAM_DONE_CLOSE) { - /* XXX */ - sq_remove(sp); - return; - } - iov = evConsIovec(sp->s_temp, INT16SZ); - if (evRead(ev, sp->s_rfd, &iov, 1, stream_getlen, sp, &sp->evID_r) == - -1) - ns_panic(ns_log_default, 1, "evRead(fd %d): %s", - (void *)sp->s_rfd, strerror(errno)); - sp->flags |= STREAM_READ_EV; -} - -/* void - * dq_remove_gen(gen) - * close/deallocate all the udp sockets (except 0.0.0.0) which are - * not from the current generation. - * side effects: - * global list `iflist' is modified. - */ -void -dq_remove_gen(time_t gen) { - interface *this, *next; - - for (this = HEAD(iflist); this != NULL; this = next) { - next = NEXT(this, link); - if (this->gen != gen && ina_hlong(this->addr) != INADDR_ANY) - dq_remove(this); - } -} - -/* void - * dq_remove_all() - * close/deallocate all interfaces. - * side effects: - * global list `iflist' is modified. - */ -void -dq_remove_all() { - interface *this, *next; - - for (this = HEAD(iflist); this != NULL; this = next) { - next = NEXT(this, link); - /* - * Clear the forwarding flag so we don't panic the server. - */ - this->flags &= ~INTERFACE_FORWARDING; - dq_remove(this); - } -} - -/* void - * dq_remove(interface *this) - * close/deallocate an interface's sockets. called on errors - * or if the interface disappears. - * side effects: - * global list `iflist' is modified. - */ -static void -dq_remove(interface *this) { - ns_notice(ns_log_default, "deleting interface [%s].%u", - inet_ntoa(this->addr), ntohs(this->port)); - - if ((this->flags & INTERFACE_FORWARDING) != 0) - ns_panic(ns_log_default, 0, - "forwarding interface [%s].%u gone", - inet_ntoa(this->addr), - ntohs(this->port)); - - /* Deallocate fields. */ - if ((this->flags & INTERFACE_FILE_VALID) != 0) - (void) evDeselectFD(ev, this->evID_d); - if (this->dfd >= 0) - (void) close(this->dfd); - if ((this->flags & INTERFACE_CONN_VALID) != 0) - (void) evCancelConn(ev, this->evID_s); - if (this->sfd >= 0) - (void) close(this->sfd); - - UNLINK(iflist, this, link); - memput(this, sizeof *this); -} - -/* struct in_addr - * net_mask(ina) - * makes a classful assumption in a classless world, and returns it. - */ -struct in_addr -net_mask(struct in_addr ina) { - u_long hl = ina_hlong(ina); - struct in_addr ret; - - if (IN_CLASSA(hl)) - hl = IN_CLASSA_NET; - else if (IN_CLASSB(hl)) - hl = IN_CLASSB_NET; - else if (IN_CLASSC(hl)) - hl = IN_CLASSC_NET; - else - hl = INADDR_BROADCAST; - ina_ulong(ret) = htonl(hl); - return (ret); -} - -/* aIsUs(addr) - * scan our list of interface addresses for "addr". - * returns: - * 0: address isn't one of our interfaces - * >0: address is one of our interfaces, or INADDR_ANY - */ -int -aIsUs(struct in_addr addr) { - - if (ina_hlong(addr) == INADDR_ANY || if_find(addr, 0) != NULL) - return (1); - return (0); -} - -/* interface * - * if_find(addr, port) - * scan our list of interface addresses for "addr" and port. - * port == 0 means match any port - * returns: - * pointer to interface with this address/port, or NULL if there isn't - * one. - */ -static interface * -if_find(struct in_addr addr, u_int16_t port) { - interface *ifp; - - for (ifp = HEAD(iflist); ifp != NULL; ifp = NEXT(ifp, link)) - if (ina_equal(addr, ifp->addr)) - if (port == 0 || ifp->port == port) - break; - return (ifp); -} - -/* - * These are here in case we ever want to get more clever, like perhaps - * using a bitmap to keep track of outstanding queries and a random - * allocation scheme to make it a little harder to predict them. Note - * that the resolver will need the same protection so the cleverness - * should be put there rather than here; this is just an interface layer. - * - * This is true but ... most clients only send out a few queries, they - * use varying port numbers, and the queries aren't sent to the outside - * world which we know is full of spoofers. Doing a good job of randomizing - * ids may also be to expensive for each client. Queries forwarded by the - * server always come from the same port (unless you let 8.x pick a port - * and restart it periodically - maybe it should open several and use - * them randomly). The server sends out lots more queries, and if it's - * cache is corrupted, it has the potential to affect more clients. - * NOTE: - randomizing the ID or source port doesn't help a bit if the - * queries can be sniffed. - * -- DL - */ - -/* - * Allow the user to pick one of two ID randomization algorithms. - * - * The first algorithm is an adaptation of the sequence shuffling - * algorithm discovered by Carter Bays and S. D. Durham [ACM Trans. Math. - * Software 2 (1976), 59-64], as documented as Algorithm B in Chapter - * 3.2.2 in Volume 2 of Knuth's "The Art of Computer Programming". We use - * a randomly selected linear congruential random number generator with a - * modulus of 2^16, whose increment is a randomly picked odd number, and - * whose multiplier is picked from a set which meets the following - * criteria: - * Is of the form 8*n+5, which ensures "high potency" according to - * principle iii in the summary chapter 3.6. This form also has a - * gcd(a-1,m) of 4 which is good according to principle iv. - * - * Is between 0.01 and 0.99 times the modulus as specified by - * principle iv. - * - * Passes the spectral test "with flying colors" (ut >= 1) in - * dimensions 2 through 6 as calculated by Algorithm S in Chapter - * 3.3.4 and the ratings calculated by formula 35 in section E. - * - * Of the multipliers that pass this test, pick the set that is - * best according to the theoretical bounds of the serial - * correlation test. This was calculated using a simplified - * version of Knuth's Theorem K in Chapter 3.3.3. - * - * These criteria may not be important for this use, but we might as well - * pick from the best generators since there are so many possible ones and - * we don't have that many random bits to do the picking. - * - * We use a modulus of 2^16 instead of something bigger so that we will - * tend to cycle through all the possible IDs before repeating any, - * however the shuffling will perturb this somewhat. Theoretically there - * is no minimimum interval between two uses of the same ID, but in - * practice it seems to be >64000. - * - * Our adaptatation of Algorithm B mixes the hash state which has - * captured various random events into the shuffler to perturb the - * sequence. - * - * One disadvantage of this algorithm is that if the generator parameters - * were to be guessed, it would be possible to mount a limited brute force - * attack on the ID space since the IDs are only shuffled within a limited - * range. - * - * The second algorithm uses the same random number generator to populate - * a pool of 65536 IDs. The hash state is used to pick an ID from a window - * of 4096 IDs in this pool, then the chosen ID is swapped with the ID - * at the beginning of the window and the window position is advanced. - * This means that the interval between uses of the ID will be no less - * than 65536-4096. The ID sequence in the pool will become more random - * over time. - * - * For both algorithms, two more linear congruential random number generators - * are selected. The ID from the first part of algorithm is used to seed - * the first of these generators, and its output is used to seed the second. - * The strategy is use these generators as 1 to 1 hashes to obfuscate the - * properties of the generator used in the first part of either algorithm. - * - * The first algorithm may be suitable for use in a client resolver since - * its memory requirements are fairly low and it's pretty random out of - * the box. It is somewhat succeptible to a limited brute force attack, - * so the second algorithm is probably preferable for a longer running - * program that issues a large number of queries and has time to randomize - * the pool. - */ - -#define NSID_SHUFFLE_TABLE_SIZE 100 /* Suggested by Knuth */ -/* - * Pick one of the next 4096 IDs in the pool. - * There is a tradeoff here between randomness and how often and ID is reused. - */ -#define NSID_LOOKAHEAD 4096 /* Must be a power of 2 */ -#define NSID_SHUFFLE_ONLY 1 /* algorithm 1 */ -#define NSID_USE_POOL 2 /* algorithm 2 */ - -/* - * Keep a running hash of various bits of data that we'll use to - * stir the ID pool or perturb the ID generator - */ -void -nsid_hash(u_char *data, size_t len) { - /* - * Hash function similar to the one we use for hashing names. - * We don't fold case or toss the upper bit here, though. - * This hash doesn't do much interesting when fed binary zeros, - * so there may be a better hash function. - * This function doesn't need to be very strong since we're - * only using it to stir the pool, but it should be reasonably - * fast. - */ - while (len-- > 0) { - HASHROTATE(nsid_hash_state); - nsid_hash_state += *data++; - } -} - -/* - * Table of good linear congruential multipliers for modulus 2^16 - * in order of increasing serial correlation bounds (so trim from - * the end). - */ -static const u_int16_t nsid_multiplier_table[] = { - 17565, 25013, 11733, 19877, 23989, 23997, 24997, 25421, - 26781, 27413, 35901, 35917, 35973, 36229, 38317, 38437, - 39941, 40493, 41853, 46317, 50581, 51429, 53453, 53805, - 11317, 11789, 12045, 12413, 14277, 14821, 14917, 18989, - 19821, 23005, 23533, 23573, 23693, 27549, 27709, 28461, - 29365, 35605, 37693, 37757, 38309, 41285, 45261, 47061, - 47269, 48133, 48597, 50277, 50717, 50757, 50805, 51341, - 51413, 51581, 51597, 53445, 11493, 14229, 20365, 20653, - 23485, 25541, 27429, 29421, 30173, 35445, 35653, 36789, - 36797, 37109, 37157, 37669, 38661, 39773, 40397, 41837, - 41877, 45293, 47277, 47845, 49853, 51085, 51349, 54085, - 56933, 8877, 8973, 9885, 11365, 11813, 13581, 13589, - 13613, 14109, 14317, 15765, 15789, 16925, 17069, 17205, - 17621, 17941, 19077, 19381, 20245, 22845, 23733, 24869, - 25453, 27213, 28381, 28965, 29245, 29997, 30733, 30901, - 34877, 35485, 35613, 36133, 36661, 36917, 38597, 40285, - 40693, 41413, 41541, 41637, 42053, 42349, 45245, 45469, - 46493, 48205, 48613, 50861, 51861, 52877, 53933, 54397, - 55669, 56453, 56965, 58021, 7757, 7781, 8333, 9661, - 12229, 14373, 14453, 17549, 18141, 19085, 20773, 23701, - 24205, 24333, 25261, 25317, 27181, 30117, 30477, 34757, - 34885, 35565, 35885, 36541, 37957, 39733, 39813, 41157, - 41893, 42317, 46621, 48117, 48181, 49525, 55261, 55389, - 56845, 7045, 7749, 7965, 8469, 9133, 9549, 9789, - 10173, 11181, 11285, 12253, 13453, 13533, 13757, 14477, - 15053, 16901, 17213, 17269, 17525, 17629, 18605, 19013, - 19829, 19933, 20069, 20093, 23261, 23333, 24949, 25309, - 27613, 28453, 28709, 29301, 29541, 34165, 34413, 37301, - 37773, 38045, 38405, 41077, 41781, 41925, 42717, 44437, - 44525, 44613, 45933, 45941, 47077, 50077, 50893, 52117, - 5293, 55069, 55989, 58125, 59205, 6869, 14685, 15453, - 16821, 17045, 17613, 18437, 21029, 22773, 22909, 25445, - 25757, 26541, 30709, 30909, 31093, 31149, 37069, 37725, - 37925, 38949, 39637, 39701, 40765, 40861, 42965, 44813, - 45077, 45733, 47045, 50093, 52861, 52957, 54181, 56325, - 56365, 56381, 56877, 57013, 5741, 58101, 58669, 8613, - 10045, 10261, 10653, 10733, 11461, 12261, 14069, 15877, - 17757, 21165, 23885, 24701, 26429, 26645, 27925, 28765, - 29197, 30189, 31293, 39781, 39909, 40365, 41229, 41453, - 41653, 42165, 42365, 47421, 48029, 48085, 52773, 5573, - 57037, 57637, 58341, 58357, 58901, 6357, 7789, 9093, - 10125, 10709, 10765, 11957, 12469, 13437, 13509, 14773, - 15437, 15773, 17813, 18829, 19565, 20237, 23461, 23685, - 23725, 23941, 24877, 25461, 26405, 29509, 30285, 35181, - 37229, 37893, 38565, 40293, 44189, 44581, 45701, 47381, - 47589, 48557, 4941, 51069, 5165, 52797, 53149, 5341, - 56301, 56765, 58581, 59493, 59677, 6085, 6349, 8293, - 8501, 8517, 11597, 11709, 12589, 12693, 13517, 14909, - 17397, 18085, 21101, 21269, 22717, 25237, 25661, 29189, - 30101, 31397, 33933, 34213, 34661, 35533, 36493, 37309, - 40037, 4189, 42909, 44309, 44357, 44389, 4541, 45461, - 46445, 48237, 54149, 55301, 55853, 56621, 56717, 56901, - 5813, 58437, 12493, 15365, 15989, 17829, 18229, 19341, - 21013, 21357, 22925, 24885, 26053, 27581, 28221, 28485, - 30605, 30613, 30789, 35437, 36285, 37189, 3941, 41797, - 4269, 42901, 43293, 44645, 45221, 46893, 4893, 50301, - 50325, 5189, 52109, 53517, 54053, 54485, 5525, 55949, - 56973, 59069, 59421, 60733, 61253, 6421, 6701, 6709, - 7101, 8669, 15797, 19221, 19837, 20133, 20957, 21293, - 21461, 22461, 29085, 29861, 30869, 34973, 36469, 37565, - 38125, 38829, 39469, 40061, 40117, 44093, 47429, 48341, - 50597, 51757, 5541, 57629, 58405, 59621, 59693, 59701, - 61837, 7061, 10421, 11949, 15405, 20861, 25397, 25509, - 25893, 26037, 28629, 28869, 29605, 30213, 34205, 35637, - 36365, 37285, 3773, 39117, 4021, 41061, 42653, 44509, - 4461, 44829, 4725, 5125, 52269, 56469, 59085, 5917, - 60973, 8349, 17725, 18637, 19773, 20293, 21453, 22533, - 24285, 26333, 26997, 31501, 34541, 34805, 37509, 38477, - 41333, 44125, 46285, 46997, 47637, 48173, 4925, 50253, - 50381, 50917, 51205, 51325, 52165, 52229, 5253, 5269, - 53509, 56253, 56341, 5821, 58373, 60301, 61653, 61973, - 62373, 8397, 11981, 14341, 14509, 15077, 22261, 22429, - 24261, 28165, 28685, 30661, 34021, 34445, 39149, 3917, - 43013, 43317, 44053, 44101, 4533, 49541, 49981, 5277, - 54477, 56357, 57261, 57765, 58573, 59061, 60197, 61197, - 62189, 7725, 8477, 9565, 10229, 11437, 14613, 14709, - 16813, 20029, 20677, 31445, 3165, 31957, 3229, 33541, - 36645, 3805, 38973, 3965, 4029, 44293, 44557, 46245, - 48917, 4909, 51749, 53709, 55733, 56445, 5925, 6093, - 61053, 62637, 8661, 9109, 10821, 11389, 13813, 14325, - 15501, 16149, 18845, 22669, 26437, 29869, 31837, 33709, - 33973, 34173, 3677, 3877, 3981, 39885, 42117, 4421, - 44221, 44245, 44693, 46157, 47309, 5005, 51461, 52037, - 55333, 55693, 56277, 58949, 6205, 62141, 62469, 6293, - 10101, 12509, 14029, 17997, 20469, 21149, 25221, 27109, - 2773, 2877, 29405, 31493, 31645, 4077, 42005, 42077, - 42469, 42501, 44013, 48653, 49349, 4997, 50101, 55405, - 56957, 58037, 59429, 60749, 61797, 62381, 62837, 6605, - 10541, 23981, 24533, 2701, 27333, 27341, 31197, 33805, - 3621, 37381, 3749, 3829, 38533, 42613, 44381, 45901, - 48517, 51269, 57725, 59461, 60045, 62029, 13805, 14013, - 15461, 16069, 16157, 18573, 2309, 23501, 28645, 3077, - 31541, 36357, 36877, 3789, 39429, 39805, 47685, 47949, - 49413, 5485, 56757, 57549, 57805, 58317, 59549, 62213, - 62613, 62853, 62933, 8909, 12941, 16677, 20333, 21541, - 24429, 26077, 26421, 2885, 31269, 33381, 3661, 40925, - 42925, 45173, 4525, 4709, 53133, 55941, 57413, 57797, - 62125, 62237, 62733, 6773, 12317, 13197, 16533, 16933, - 18245, 2213, 2477, 29757, 33293, 35517, 40133, 40749, - 4661, 49941, 62757, 7853, 8149, 8573, 11029, 13421, - 21549, 22709, 22725, 24629, 2469, 26125, 2669, 34253, - 36709, 41013, 45597, 46637, 52285, 52333, 54685, 59013, - 60997, 61189, 61981, 62605, 62821, 7077, 7525, 8781, - 10861, 15277, 2205, 22077, 28517, 28949, 32109, 33493, - 3685, 39197, 39869, 42621, 44997, 48565, 5221, 57381, - 61749, 62317, 63245, 63381, 23149, 2549, 28661, 31653, - 33885, 36341, 37053, 39517, 42805, 45853, 48997, 59349, - 60053, 62509, 63069, 6525, 1893, 20181, 2365, 24893, - 27397, 31357, 32277, 33357, 34437, 36677, 37661, 43469, - 43917, 50997, 53869, 5653, 13221, 16741, 17893, 2157, - 28653, 31789, 35301, 35821, 61613, 62245, 12405, 14517, - 17453, 18421, 3149, 3205, 40341, 4109, 43941, 46869, - 48837, 50621, 57405, 60509, 62877, 8157, 12933, 12957, - 16501, 19533, 3461, 36829, 52357, 58189, 58293, 63053, - 17109, 1933, 32157, 37701, 59005, 61621, 13029, 15085, - 16493, 32317, 35093, 5061, 51557, 62221, 20765, 24613, - 2629, 30861, 33197, 33749, 35365, 37933, 40317, 48045, - 56229, 61157, 63797, 7917, 17965, 1917, 1973, 20301, - 2253, 33157, 58629, 59861, 61085, 63909, 8141, 9221, - 14757, 1581, 21637, 26557, 33869, 34285, 35733, 40933, - 42517, 43501, 53653, 61885, 63805, 7141, 21653, 54973, - 31189, 60061, 60341, 63357, 16045, 2053, 26069, 33997, - 43901, 54565, 63837, 8949, 17909, 18693, 32349, 33125, - 37293, 48821, 49053, 51309, 64037, 7117, 1445, 20405, - 23085, 26269, 26293, 27349, 32381, 33141, 34525, 36461, - 37581, 43525, 4357, 43877, 5069, 55197, 63965, 9845, - 12093, 2197, 2229, 32165, 33469, 40981, 42397, 8749, - 10853, 1453, 18069, 21693, 30573, 36261, 37421, 42533 -}; -#define NSID_MULT_TABLE_SIZE \ - ((sizeof nsid_multiplier_table)/(sizeof nsid_multiplier_table[0])) - -void -nsid_init(void) { - struct timeval now; - pid_t mypid; - u_int16_t a1ndx, a2ndx, a3ndx, c1ndx, c2ndx, c3ndx; - int i; - - if (nsid_algorithm != 0) - return; - - gettimeofday(&now, NULL); - mypid = getpid(); - - /* Initialize the state */ - nsid_hash_state = 0; - nsid_hash((u_char *)&now, sizeof now); - nsid_hash((u_char *)&mypid, sizeof mypid); - - /* - * Select our random number generators and initial seed. - * We could really use more random bits at this point, - * but we'll try to make a silk purse out of a sows ear ... - */ - /* generator 1 */ - a1ndx = ((u_long) NSID_MULT_TABLE_SIZE * - (nsid_hash_state & 0xFFFF)) >> 16; - nsid_a1 = nsid_multiplier_table[a1ndx]; - c1ndx = (nsid_hash_state >> 9) & 0x7FFF; - nsid_c1 = 2*c1ndx + 1; - /* generator 2, distinct from 1 */ - a2ndx = ((u_long) (NSID_MULT_TABLE_SIZE - 1) * - ((nsid_hash_state >> 10) & 0xFFFF)) >> 16; - if (a2ndx >= a1ndx) - a2ndx++; - nsid_a2 = nsid_multiplier_table[a2ndx]; - c2ndx = nsid_hash_state % 32767; - if (c2ndx >= c1ndx) - c2ndx++; - nsid_c2 = 2*c2ndx + 1; - /* generator 3, distinct from 1 and 2 */ - a3ndx = ((u_long) (NSID_MULT_TABLE_SIZE - 2) * - ((nsid_hash_state >> 20) & 0xFFFF)) >> 16; - if (a3ndx >= a1ndx || a3ndx >= a2ndx) - a3ndx++; - if (a3ndx >= a1ndx && a3ndx >= a2ndx) - a3ndx++; - nsid_a3 = nsid_multiplier_table[a3ndx]; - c3ndx = nsid_hash_state % 32766; - if (c3ndx >= c1ndx || c3ndx >= c2ndx) - c3ndx++; - if (c3ndx >= c1ndx && c3ndx >= c2ndx) - c3ndx++; - nsid_c3 = 2*c3ndx + 1; - - nsid_state = ((nsid_hash_state >> 16) ^ (nsid_hash_state)) & 0xFFFF; - - /* Do the algorithm specific initialization */ - INSIST(server_options != NULL); - if (NS_OPTION_P(OPTION_USE_ID_POOL) == 0) { - /* Algorithm 1 */ - nsid_algorithm = NSID_SHUFFLE_ONLY; - nsid_vtable = memget(NSID_SHUFFLE_TABLE_SIZE * - (sizeof(u_int16_t)) ); - if (!nsid_vtable) - ns_panic(ns_log_default, 1, "memget(nsid_vtable)", - NULL); - for (i = 0; i < NSID_SHUFFLE_TABLE_SIZE; i++) { - nsid_vtable[i] = nsid_state; - nsid_state = (((u_long) nsid_a1 * nsid_state) + nsid_c1) - & 0xFFFF; - } - nsid_state2 = nsid_state; - } else { - /* Algorithm 2 */ - nsid_algorithm = NSID_USE_POOL; - nsid_pool = memget(0x10000 * (sizeof(u_int16_t))); - if (!nsid_pool) - ns_panic(ns_log_default, 1, "memget(nsid_pool)", NULL); - for (i = 0; ; i++) { - nsid_pool[i] = nsid_state; - nsid_state = (((u_long) nsid_a1 * nsid_state) + nsid_c1) & 0xFFFF; - if (i == 0xFFFF) - break; - } - } -} - -#define NSID_RANGE_MASK (NSID_LOOKAHEAD - 1) - -#define NSID_POOL_MASK 0xFFFF /* used to wrap the pool index */ - -u_int16_t -nsid_next() { - u_int16_t id, compressed_hash; - - compressed_hash = ((nsid_hash_state >> 16) ^ (nsid_hash_state)) & - 0xFFFF; - if (nsid_algorithm == NSID_SHUFFLE_ONLY) { - u_int16_t j; - - /* - * This is the original Algorithm B - * j = ((u_long) NSID_SHUFFLE_TABLE_SIZE * nsid_state2) - * >> 16; - * - * We'll perturb it with some random stuff ... - */ - j = ((u_long) NSID_SHUFFLE_TABLE_SIZE * - (nsid_state2 ^ compressed_hash)) >> 16; - nsid_state2 = id = nsid_vtable[j]; - nsid_state = (((u_long) nsid_a1 * nsid_state) + nsid_c1) & - 0xFFFF; - nsid_vtable[j] = nsid_state; - } else if (nsid_algorithm == NSID_USE_POOL) { - u_int16_t pick; - - pick = compressed_hash & NSID_RANGE_MASK; - id = nsid_pool[(nsid_state + pick) & NSID_POOL_MASK]; - if (pick != 0) { - /* Swap two IDs to stir the pool */ - nsid_pool[(nsid_state + pick) & NSID_POOL_MASK] = - nsid_pool[nsid_state]; - nsid_pool[nsid_state] = id; - } - - /* increment the base pointer into the pool */ - if (nsid_state == 65535) - nsid_state = 0; - else - nsid_state++; - } else - ns_panic(ns_log_default, 1, "Unknown ID algorithm", NULL); - - /* Now lets obfuscate ... */ - id = (((u_long) nsid_a2 * id) + nsid_c2) & 0xFFFF; - id = (((u_long) nsid_a3 * id) + nsid_c3) & 0xFFFF; - - return (id); -} - -/* Note: this function CAN'T deallocate the saved_argv[]. */ -static void -deallocate_everything(void) { - FILE *f; - - f = write_open(server_options->memstats_filename); - - ns_freestats(); - qflush(); - sq_flush(NULL); - free_addinfo(); - ns_shutdown(); - dq_remove_all(); - db_lame_destroy(); - if (local_addresses != NULL) - free_ip_match_list(local_addresses); - if (local_networks != NULL) - free_ip_match_list(local_networks); - destroyservicelist(); - destroyprotolist(); - shutdown_logging(); - evDestroy(ev); - if (conffile != NULL) - freestr(conffile); - conffile = NULL; - if (debugfile != NULL) - freestr(debugfile); - debugfile = NULL; - if (user_name != NULL) - freestr(user_name); - user_name = NULL; - if (group_name != NULL) - freestr(group_name); - group_name = NULL; - if (chroot_dir != NULL) - freestr(chroot_dir); - chroot_dir = NULL; - if (nsid_pool != NULL) - memput(nsid_pool, 0x10000 * (sizeof(u_int16_t))); - nsid_pool = NULL; - irs_destroy(); - if (f != NULL) { - memstats(f); - (void)fclose(f); - } -} - -static void -ns_restart(void) { - ns_info(ns_log_default, "named restarting"); -#ifdef BIND_UPDATE - dynamic_about_to_exit(); -#endif - if (server_options && server_options->pid_filename) - (void)unlink(server_options->pid_filename); - ns_logstats(ev, NULL, evNowTime(), evConsTime(0, 0)); - if (NS_OPTION_P(OPTION_DEALLOC_ON_EXIT)) - deallocate_everything(); - else - shutdown_configuration(); - execvp(saved_argv[0], saved_argv); - abort(); -} - -static void -use_desired_debug(void) { -#ifdef DEBUG - sigset_t set; - - /* Protect against race conditions by blocking debugging signals. */ - - if (sigemptyset(&set) < 0) { - ns_error(ns_log_os, - "sigemptyset failed in use_desired_debug: %s", - strerror(errno)); - return; - } - if (sigaddset(&set, SIGUSR1) < 0) { - ns_error(ns_log_os, - "sigaddset SIGUSR1 failed in use_desired_debug: %s", - strerror(errno)); - return; - } - if (sigaddset(&set, SIGUSR2) < 0) { - ns_error(ns_log_os, - "sigaddset SIGUSR2 failed in use_desired_debug: %s", - strerror(errno)); - return; - } - if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) { - ns_error(ns_log_os, - "sigprocmask to block USR1 and USR2 failed: %s", - strerror(errno)); - return; - } - setdebug(desired_debug); - if (sigprocmask(SIG_UNBLOCK, &set, NULL) < 0) - ns_error(ns_log_os, - "sigprocmask to unblock USR1 and USR2 failed: %s", - strerror(errno)); -#endif -} - -void -toggle_qrylog(void) { - qrylog = !qrylog; - ns_notice(ns_log_default, "query log %s\n", qrylog ?"on" :"off"); -} - -static void -wild(void) { - ns_panic(ns_log_default, 1, "wild need", NULL); -} - -/* - * This is a functional interface to the global needs and options. - */ - -static void -init_needs(void) { - int need; - - for (need = 0; need < main_need_num; need++) - handlers[need] = wild; - handlers[main_need_zreload] = ns_zreload; - handlers[main_need_reload] = ns_reload; - handlers[main_need_reconfig] = ns_reconfig; - handlers[main_need_endxfer] = endxfer; - handlers[main_need_zoneload] = loadxfer; - handlers[main_need_dump] = doadump; - handlers[main_need_statsdump] = ns_stats; - handlers[main_need_exit] = wild; - handlers[main_need_qrylog] = toggle_qrylog; - handlers[main_need_debug] = use_desired_debug; - handlers[main_need_restart] = ns_restart; - handlers[main_need_reap] = reapchild; - handlers[main_need_noexpired] = ns_noexpired; -} - -static void -handle_needs(void) { - int need, queued = 0; - - ns_debug(ns_log_default, 15, "handle_needs()"); - block_signals(); - for (need = 0; need < main_need_num; need++) - if ((needs & (1 << need)) != 0) { - INSIST_ERR(evWaitFor(ev, handle_needs, need_waitfunc, - handlers[need], NULL) != -1); - queued++; - } - needs = 0; - unblock_signals(); - ns_debug(ns_log_default, 15, "handle_needs(): queued %d", queued); - if (queued != 0) { - INSIST_ERR(evDo(ev, handle_needs) != -1); - return; - } - ns_panic(ns_log_default, 1, "ns_handle_needs: queued == 0", NULL); -} - -static void -need_waitfunc(evContext ctx, void *uap, const void *tag) { - handler hand = (handler) uap; - - (*hand)(); -} - -void -ns_need(enum need need) { - block_signals(); - ns_need_unsafe(need); - unblock_signals(); -} - -/* Note: this function should only be called with signals blocked. */ -void -ns_need_unsafe(enum need need) { - needs |= (1 << need); - if (need == main_need_exit) - needs_exit = 1; -} - -void -ns_setoption(int option) { - ns_warning(ns_log_default, "used obsolete ns_setoption(%d)", option); -} - -void -writestream(struct qstream *sp, const u_char *msg, int msglen) { - if (sq_openw(sp, msglen + INT16SZ) == -1) { - sq_remove(sp); - return; - } - if (sq_write(sp, msg, msglen) == -1) { - sq_remove(sp); - return; - } - sq_writeh(sp, sq_flushw); -} - -static int -only_digits(const char *s) { - if (*s == '\0') - return (0); - while (*s != '\0') { - if (!isdigit(*s)) - return (0); - s++; - } - return (1); -} -#if defined(__GNUC__) && defined(__BOUNDS_CHECKING_ON) - /* Use bounds checking malloc, etc. */ -void * -memget(size_t len) { - return (malloc(len)); -} - -void -memput(void *addr, size_t len) { - free(addr); -} - -int -meminit(size_t init_max_size, size_t target_size) { - return (0); -} - -void * -memget_debug(size_t size, const char *file, int line) { - void *ptr; - ptr = __memget(size); - fprintf(stderr, "%s:%d: memget(%lu) -> %p\n", file, line, - (u_long)size, ptr); - return (ptr); -} - -void -memput_debug(void *ptr, size_t size, const char *file, int line) { - fprintf(stderr, "%s:%d: memput(%p, %lu)\n", file, line, ptr, - (u_long)size); - __memput(ptr, size); -} - -void -memstats(FILE *out) { - fputs("No memstats\n", out); -} -#endif - -#ifndef HAVE_CUSTOM -/* Standard implementation has nothing here */ -static void -custom_init(void) { - /* Noop. */ -} - -static void -custom_shutdown(void) { - /* Noop. */ -} -#endif diff --git a/contrib/bind/bin/named/ns_maint.c b/contrib/bind/bin/named/ns_maint.c deleted file mode 100644 index 952774febe183..0000000000000 --- a/contrib/bind/bin/named/ns_maint.c +++ /dev/null @@ -1,1937 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)ns_maint.c 4.39 (Berkeley) 3/2/91"; -static const char rcsid[] = "$Id: ns_maint.c,v 8.105 2000/07/17 07:25:00 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1988 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Check Point Software Technologies Incorporated not be used - * in advertising or publicity pertaining to distribution of the document - * or software without specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND CHECK POINT SOFTWARE TECHNOLOGIES - * INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL CHECK POINT SOFTWARE TECHNOLOGIES INCORPRATED - * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <assert.h> -#include <errno.h> -#include <signal.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> -#include <unistd.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" - -static int nxfers(struct zoneinfo *, int), - bottom_of_zone(struct databuf *, int); - -static void startxfer(struct zoneinfo *), - abortxfer(struct zoneinfo *), - tryxfer(void), - purge_z_2(struct hashbuf *, int); -static int purge_nonglue_2(const char *, struct hashbuf *, - int, int); - -#ifndef HAVE_SPAWNXFER -static pid_t spawnxfer(char **, struct zoneinfo *); -#endif - -static time_t stats_time; /* Redundant ??? XXX ogud */ - - /* State of all running zone transfers */ -static struct { - pid_t xfer_pid; - int xfer_state; /* see below */ - WAIT_T xfer_status; -} xferstatus[MAX_XFERS_RUNNING]; - -#define XFER_IDLE 0 -#define XFER_RUNNING 1 -#define XFER_DONE 2 - - -/* - * Perform routine zone maintenance. - */ -void -zone_maint(struct zoneinfo *zp) { - gettime(&tt); - - ns_debug(ns_log_maint, 1, "zone_maint('%s'); now %lu", - zp->z_origin[0] == '\0' ? "." : zp->z_origin, - (u_long)tt.tv_sec); - -#ifdef DEBUG - if (debug >= 2) - printzoneinfo((zp - zones), ns_log_maint, 2); -#endif - - switch (zp->z_type) { - - case Z_SECONDARY: - /*FALLTHROUGH*/ -#ifdef STUBS - case Z_STUB: -#endif - if (zp->z_serial != 0 && - ((zp->z_lastupdate+zp->z_expire) < (u_int32_t)tt.tv_sec)) { - if ((zp->z_flags & Z_NOTIFY) != 0) - ns_stopnotify(zp->z_origin, zp->z_class); - /* calls purge_zone */ - do_reload(zp->z_origin, zp->z_type, zp->z_class, 0); - /* reset zone state */ - if (!haveComplained((u_long)zp, (u_long)stale)) { - ns_notice(ns_log_default, - "%s zone \"%s\" expired", - zoneTypeString(zp->z_type), - zp->z_origin); - } - zp->z_flags &= ~Z_AUTH; - zp->z_flags |= Z_EXPIRED; - zp->z_refresh = INIT_REFRESH; - zp->z_retry = INIT_REFRESH; - zp->z_serial = 0; - } - if ((zp->z_flags & (Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL)) != 0) - { - ns_retrytime(zp, tt.tv_sec); - break; - } - if (zp->z_flags & Z_XFER_RUNNING) { - abortxfer(zp); - /* - * Check again in 30 seconds in case the first - * abort doesn't work. - */ - if (zp->z_time != 0 && zp->z_time <= tt.tv_sec) - zp->z_time = tt.tv_sec + 30; - break; - } - /* - * If we don't have the zone loaded or dialup is off - * or we attempted a qserial_query before and the queue was - * full attempt to verify / load the zone. - */ - if ((zp->z_serial == 0) || (zp->z_flags & Z_NEED_QSERIAL) || - (zp->z_dialup == zdialup_no) || - (zp->z_dialup == zdialup_use_default && - NS_OPTION_P(OPTION_NODIALUP))) - qserial_query(zp); - else { - ns_info(ns_log_default, "Suppressed qserial_query(%s)", - *(zp->z_origin) ? zp->z_origin : "."); - ns_refreshtime(zp, tt.tv_sec); - } - break; - -#ifdef BIND_UPDATE - case Z_PRIMARY: - if ((zp->z_flags & Z_DYNAMIC) == 0) - break; - if (tt.tv_sec >= zp->z_soaincrtime && - zp->z_soaincrintvl > 0 && - zp->z_flags & Z_NEED_SOAUPDATE) { - if (incr_serial(zp) < 0) { - /* Try again later. */ - ns_error(ns_log_maint, - "error updating serial number for %s from %d", - zp->z_origin, - zp->z_serial); - zp->z_soaincrtime = 0; - (void)schedule_soa_update(zp, 0); - } - - } - if (tt.tv_sec >= zp->z_dumptime && - zp->z_dumpintvl > 0 && - zp->z_flags & Z_NEED_DUMP) { - if (zonedump(zp, ISNOTIXFR) < 0) { - /* Try again later. */ - ns_error(ns_log_maint, - "zone dump for '%s' failed, rescheduling", - zp->z_origin); - zp->z_dumptime = 0; - (void)schedule_dump(zp); - } - } - if (zp->z_maintain_ixfr_base) - ixfr_log_maint(zp); - break; -#endif /* BIND_UPDATE */ - - default: - break; - } - - /* - * It is essential that we never try to set a timer in the past - * or for now because doing so could cause an infinite loop. - */ - INSIST(zp->z_time == 0 || zp->z_time > tt.tv_sec); - - sched_zone_maint(zp); -} - -static void -do_zone_maint(evContext ctx, void *uap, struct timespec due, - struct timespec inter) { - ztimer_info zti = uap; - struct zoneinfo *zp; - - INSIST(zti != NULL); - - ns_debug(ns_log_maint, 1, "do_zone_maint for zone %s (class %s)", - zti->name, p_class(zti->class)); - zp = find_zone(zti->name, zti->class); - if (zp == NULL) { - ns_error(ns_log_maint, - "do_zone_maint: %s zone '%s' (class %s) is not authoritative", - zoneTypeString(zti->type), zti->name, - p_class(zti->class)); - return; - } - if (zp->z_type != zti->type) { - ns_error(ns_log_maint, - "do_zone_maint: %s zone '%s' (class %s) has changed its type", - zoneTypeString(zti->type), zti->name, - p_class(zti->class)); - return; - } - - free_zone_timerinfo(zp); - - zp->z_flags &= ~Z_TIMER_SET; - zone_maint(zp); -} - -/* - * Figure out the next maintenance time for the zone and set a timer. - */ -void -sched_zone_maint(struct zoneinfo *zp) { - time_t next_maint = (time_t)0; - ztimer_info zti; - - if (zp->z_time != 0) - next_maint = zp->z_time; -#ifdef BIND_UPDATE - if (zp->z_type == z_master && (zp->z_flags & Z_DYNAMIC) != 0) { - if (zp->z_soaincrintvl > 0 && - (next_maint == 0 || next_maint > zp->z_soaincrtime)) - next_maint = zp->z_soaincrtime; - if (zp->z_dumpintvl > 0 && - (next_maint == 0 || next_maint > zp->z_dumptime)) - next_maint = zp->z_dumptime; - } -#endif - - if (next_maint != 0) { - if (next_maint < tt.tv_sec) - next_maint = tt.tv_sec; - - if (zp->z_flags & Z_TIMER_SET) { - if (next_maint == zp->z_nextmaint) { - ns_debug(ns_log_maint, 1, - "no schedule change for zone '%s'", - zp->z_origin[0] == '\0' ? "." : - zp->z_origin); - return; - } - - if (evResetTimer(ev, zp->z_timer, - do_zone_maint, zp->z_timerinfo, - evConsTime(next_maint, 0), - evConsTime(0, 0)) < 0) { - ns_error(ns_log_maint, - "evChangeTimer failed in sched_zone_maint for zone '%s': %s", - zp->z_origin[0] == '\0' ? "." : - zp->z_origin, - strerror(errno)); - return; - } - } else { - zti = (ztimer_info)memget(sizeof *zti); - if (zti == NULL) - ns_panic(ns_log_maint, 1, - "memget failed in sched_zone_maint"); - zti->name = savestr(zp->z_origin, 1); - zti->class = zp->z_class; - zti->type = zp->z_type; - if (evSetTimer(ev, do_zone_maint, zti, - evConsTime(next_maint, 0), - evConsTime(0, 0), &zp->z_timer) < 0) { - ns_error(ns_log_maint, - "evSetTimer failed in sched_zone_maint for zone '%s': %s", - zp->z_origin[0] == '\0' ? "." : - zp->z_origin, - strerror(errno)); - return; - } - zp->z_flags |= Z_TIMER_SET; - zp->z_timerinfo = zti; - } - ns_debug(ns_log_maint, 1, - "next maintenance for zone '%s' in %lu sec", - zp->z_origin[0] == '\0' ? "." : zp->z_origin, - (u_long)(next_maint - tt.tv_sec)); - } else { - if (zp->z_flags & Z_TIMER_SET) { - free_zone_timerinfo(zp); - if (evClearTimer(ev, zp->z_timer) < 0) - ns_error(ns_log_maint, - "evClearTimer failed in sched_zone_maint for zone '%s': %s", - zp->z_origin[0] == '\0' ? "." : - zp->z_origin, - strerror(errno)); - zp->z_flags &= ~Z_TIMER_SET; - } - ns_debug(ns_log_maint, 1, - "no scheduled maintenance for zone '%s'", - zp->z_origin[0] == '\0' ? "." : zp->z_origin); - } - zp->z_nextmaint = next_maint; -} - -void -ns_cleancache(evContext ctx, void *uap, - struct timespec due, - struct timespec inter) -{ - int deleted; - - gettime(&tt); - INSIST(uap == NULL); - deleted = clean_cache(hashtab, 0); - ns_info(ns_log_maint, "Cleaned cache of %d RRset%s", - deleted, (deleted==1) ? "" : "s"); -} - -void -ns_heartbeat(evContext ctx, void *uap, struct timespec due, - struct timespec inter) -{ - struct zoneinfo *zp; - - gettime(&tt); - INSIST(uap == NULL); - - for (zp = zones; zp < &zones[nzones]; zp++) { - enum zonetype zt = zp->z_type; - - if ((zt == z_nil) || - (zp->z_dialup == zdialup_no) || - (zp->z_dialup == zdialup_use_default && - NS_OPTION_P(OPTION_NODIALUP))) - continue; - /* - * Perform the refresh query that was suppressed. - */ - if ((zt == z_slave || zt == z_stub) && - (zp->z_flags & - (Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL|Z_XFER_RUNNING) - ) == 0) { - ns_info(ns_log_default, - "Heartbeat: qserial \"%s\"", - *(zp->z_origin) ? zp->z_origin : "."); - qserial_query(zp); - } -#ifdef BIND_NOTIFY - /* - * Trigger a refresh query while the link is up by - * sending a notify. - */ - if (((zp->z_notify == znotify_yes) || - ((zp->z_notify == znotify_use_default) && - !NS_OPTION_P(OPTION_NONOTIFY))) && - (zt == z_master || zt == z_slave) && !loading && - ((zp->z_flags & Z_AUTH) != 0)) - ns_notify(zp->z_origin, zp->z_class, ns_t_soa); -#endif - } -} - - -/* - * Mark a zone "up to date" after named-xfer tells us this or we - * discover it through the qserial_*() logic. - * The caller is responsible for calling sched_zone_maint(zp). - */ -static void -markUpToDate(struct zoneinfo *zp) { - struct stat f_time; - - zp->z_flags &= ~Z_SYSLOGGED; - zp->z_lastupdate = tt.tv_sec; - ns_refreshtime(zp, tt.tv_sec); - /* - * Restore Z_AUTH in case expired, - * but only if there were no errors - * in the zone file. - */ - if ((zp->z_flags & Z_DB_BAD) == 0) { - zp->z_flags |= Z_AUTH; - zp->z_flags &= ~Z_EXPIRED; - } - if (zp->z_source) { - struct timeval t[2]; - - t[0] = tt; - t[1] = tt; - (void) utimes(zp->z_source, t); - } - /* we use "stat" to set zp->z_ftime instead of just - setting it to tt.tv_sec in order to avoid any - possible rounding problems in utimes(). */ - if (stat(zp->z_source, &f_time) != -1) - zp->z_ftime = f_time.st_mtime; - /* XXX log if stat fails? */ -} - -void -qserial_retrytime(struct zoneinfo *zp, time_t timebase) { - zp->z_time = timebase + 5 + (rand() % 25); -} - -/* - * Query for the serial number of a zone, so that we can check to see if - * we need to transfer it. If there are too many outstanding serial - * number queries, we'll try again later. - * The caller is responsible for calling sched_zone_maint(zp). - */ -void -qserial_query(struct zoneinfo *zp) { - struct qinfo *qp; - - ns_debug(ns_log_default, 1, "qserial_query(%s)", zp->z_origin); - - if (qserials_running >= server_options->serial_queries) { - qserial_retrytime(zp, tt.tv_sec); - zp->z_flags |= Z_NEED_QSERIAL; - return; - } - - qp = sysquery(zp->z_origin, zp->z_class, T_SOA, - zp->z_addr, zp->z_addrcnt, - ntohs(zp->z_port) ? zp->z_port : ns_port, - QUERY); - if (qp == NULL) { - ns_debug(ns_log_default, 1, - "qserial_query(%s): sysquery FAILED", - zp->z_origin); - /* XXX - this is bad, we should do something */ - qserial_retrytime(zp, tt.tv_sec); - zp->z_flags |= Z_NEED_QSERIAL; - return; - } - qp->q_flags |= Q_ZSERIAL; - qp->q_zquery = zp; - zp->z_flags |= Z_QSERIAL; - zp->z_flags &= ~Z_NEED_QSERIAL; - zp->z_xaddrcnt = 0; - ns_refreshtime(zp, tt.tv_sec); - qserials_running++; - ns_debug(ns_log_default, 1, "qserial_query(%s) QUEUED", zp->z_origin); -} - -static int -qserv_compare(const void *a, const void *b) { - const struct qserv *qs1 = a, *qs2 = b; - u_int32_t s1 = qs1->serial, s2 = qs2->serial; - - /* Note that we sort the "best" serial numbers to the front. */ - if (s1 == s2) - return (0); - if (s1 == 0) - return (-1); - if (s2 == 0) - return (1); - if (!SEQ_GT(s1, s2)) - return (1); - assert(SEQ_GT(s1, s2)); - return (-1); -} - -void -qserial_answer(struct qinfo *qp) { - struct zoneinfo *zp = qp->q_zquery; - struct qserv *qs = NULL; - u_int32_t serial = 0; - int n, cnt = 0; - - /* Take this query out of the global quotas. */ - zp->z_flags &= ~Z_QSERIAL; - qp->q_flags &= ~Q_ZSERIAL; /* keeps us from being called twice */ - qserials_running--; - - /* Find best serial among those returned. */ - for (n = 0; n < qp->q_naddr; n++) { - qs = &qp->q_addr[n]; - ns_debug(ns_log_default, 1, "qserial_answer(%s): [%s] -> %lu", - zp->z_origin, inet_ntoa(qs->ns_addr.sin_addr), - qs->serial); - /* Don't consider serials which weren't set by a response. */ - if (qs->serial == 0) - continue; - /* Count valid answers. */ - cnt++; - /* Remove from consideration serials which aren't "better." */ - if (zp->z_serial != 0 && !SEQ_GT(qs->serial, zp->z_serial)) { - if (serial == 0 && qs->serial == zp->z_serial) - serial = qs->serial; - - if (qs->serial != zp->z_serial) - ns_notice(ns_log_xfer_in, - "Zone \"%s\" (%s) SOA serial# (%lu) rcvd from [%s] is < ours (%lu)%s", - zp->z_origin, p_class(zp->z_class), - (u_long) qs->serial, - inet_ntoa(qs->ns_addr.sin_addr), - (u_long) zp->z_serial, - qp->q_naddr!=1 ? ": skipping" : ""); - qs->serial = 0; - continue; - } - if (serial == 0 || SEQ_GT(qs->serial, serial)) - serial = qs->serial; - } - - /* If we have an existing serial number, then sort by "better." */ - if (zp->z_serial != 0) { - qsort(qp->q_addr, qp->q_naddr, sizeof(struct qserv), - qserv_compare); - for (n = 0; n < qp->q_naddr; n++) { - qs = &qp->q_addr[n]; - ns_debug(ns_log_default, 1, - "qserial_answer after sort: [%s] -> %lu", - inet_ntoa(qs->ns_addr.sin_addr), - qs->serial); - } - } - - /* Now see about kicking off an inbound transfer. */ - if (serial == 0) { - /* An error occurred, or the all queries timed out. */ - if (qp->q_naddr != cnt) - ns_info(ns_log_xfer_in, - "Err/TO getting serial# for \"%s\"", - zp->z_origin); - addxfer(zp); - } else if (zp->z_serial == 0 || SEQ_GT(serial, zp->z_serial)) { - ns_debug(ns_log_xfer_in, 1, - "qserial_answer: zone is out of date"); - /* Use all servers whose serials are better than ours. */ - zp->z_xaddrcnt = 0; - for (n = 0; n < qp->q_naddr; n++) { - qs = &qp->q_addr[n]; - if (qs->serial != 0) - zp->z_xaddr[zp->z_xaddrcnt++] = - qs->ns_addr.sin_addr; - } - addxfer(zp); - } else if (zp->z_serial == serial) { - ns_debug(ns_log_xfer_in, 1, - "qserial_answer: zone serial is still OK"); - markUpToDate(zp); - sched_zone_maint(zp); - } -} - -/* - * Writes TSIG key info for an address to a file, optionally opening it first. - */ -static int -write_tsig_info(struct in_addr addr, char *name, int *fd, int creat_failed) { - server_info si; - DST_KEY *dst_key; - int tsig_fd = *fd; - char tsig_str[1024], secret_buf64[172]; - u_char secret_buf[128]; - int secret_len; - - si = find_server(addr); - if (si == NULL || si->key_list == NULL || si->key_list->first == NULL) - return(0); - dst_key = si->key_list->first->key; - if (tsig_fd < 0 && creat_failed == 0) { - *fd = tsig_fd = creat(name, S_IRUSR); - if (tsig_fd < 0) { - ns_warning(ns_log_default, - "write_tsig_info: creat(%s) for TSIG info failed", - name); - return(-1); - } - (void) fchown(tsig_fd, user_id, group_id); - } - if (creat_failed != 0) - return(-1); - memset(secret_buf, 0, sizeof(secret_buf)); - secret_len = dst_key_to_buffer(dst_key, secret_buf, sizeof(secret_buf)); - b64_ntop(secret_buf, secret_len, secret_buf64, sizeof(secret_buf64)); - sprintf(tsig_str, "%s\n%s\n%d\n%s\n", - inet_ntoa(addr), dst_key->dk_key_name, dst_key->dk_alg, - secret_buf64); - write(tsig_fd, tsig_str, strlen(tsig_str)); - return (0); -} - -/* - * Start an asynchronous zone transfer for a zone. Depends on current time - * being in tt. Caller must do a sched_zone_maint(zp) after we return. - */ -static void -startxfer(struct zoneinfo *zp) { - char *argv[NSMAX*2 + 20], argv_ns[NSMAX][MAXDNAME]; - int argc = 0, argc_ns = 0, i; - pid_t pid; - u_int cnt; - char debug_str[10]; - char serial_str[10]; - char port_str[10]; - char class_str[10]; - char src_str[20]; - int tsig_fd = -1; - char tsig_name[MAXPATHLEN+1], *s; - int tsig_ret = 0; - - ns_debug(ns_log_default, 1, "startxfer() %s", - zp->z_origin[0] != '\0' ? zp->z_origin : "."); - - argv[argc++] = server_options->named_xfer; - argv[argc++] = "-z"; - argv[argc++] = zp->z_origin; - argv[argc++] = "-f"; - argv[argc++] = zp->z_source; -#ifdef BIND_IXFR - if (zp->z_ixfr_tmp) { - argv[argc++] = "-i"; - argv[argc++] = zp->z_ixfr_tmp; - } -#endif - if (zp->z_serial != 0) { - argv[argc++] = "-s"; - sprintf(serial_str, "%u", zp->z_serial); - argv[argc++] = serial_str; - } - if (zp->z_axfr_src.s_addr != 0 || - server_options->axfr_src.s_addr != 0) { - argv[argc++] = "-x"; - argv[argc++] = strcpy(src_str, inet_ntoa( - (zp->z_axfr_src.s_addr != 0) ? zp->z_axfr_src : - server_options->axfr_src)); - } - argv[argc++] = "-C"; - sprintf(class_str, "%d", zp->z_class); - argv[argc++] = class_str; - if (zp->z_flags & Z_SYSLOGGED) - argv[argc++] = "-q"; - argv[argc++] = "-P"; - sprintf(port_str, "%d", ntohs(zp->z_port) != 0 ? zp->z_port : ns_port); - argv[argc++] = port_str; - argv[argc++] = "-T"; - sprintf(tsig_name, "%s.%d", zp->z_origin, getpid()); - s = tsig_name; - while ((s = strchr(s, '/')) != NULL) - *s = '_'; - argv[argc++] = tsig_name; -#ifdef STUBS - if (zp->z_type == Z_STUB) - argv[argc++] = "-S"; -#endif -#ifdef DEBUG - if (debug) { - argv[argc++] = "-d"; - sprintf(debug_str, "%d", debug); - argv[argc++] = debug_str; - argv[argc++] = "-l"; - argv[argc++] = _PATH_XFERDDT; - if (debug > 5) { - argv[argc++] = "-t"; - argv[argc++] = _PATH_XFERTRACE; - } - } -#endif - - if (zp->z_xaddrcnt == 0) { - for (zp->z_xaddrcnt = 0; - zp->z_xaddrcnt < zp->z_addrcnt; - zp->z_xaddrcnt++) - zp->z_xaddr[zp->z_xaddrcnt] = - zp->z_addr[zp->z_xaddrcnt]; - } - /* - * Copy the server ip addresses into argv, after converting - * to ascii and saving the static inet_ntoa result. - * Also, send TSIG key info into a file for the child. - */ - for (cnt = 0; cnt < zp->z_xaddrcnt; cnt++) { - struct in_addr a; - - a = zp->z_xaddr[cnt]; - if (aIsUs(a) && ns_port == zp->z_port) { - if (!haveComplained((u_long)zp, (u_long)startxfer)) - ns_notice(ns_log_default, - "attempted to fetch zone %s from self (%s)", - zp->z_origin, inet_ntoa(a)); - continue; - } - argv[argc++] = strcpy(argv_ns[argc_ns++], inet_ntoa(a)); -#ifdef BIND_IXFR - if (zp->z_ixfr_tmp != NULL) { - server_info si = find_server(a); - - if (si != NULL && - (si->flags & SERVER_INFO_SUPPORT_IXFR) != 0) - argv[argc++] = "ixfr"; - else - argv[argc++] = "axfr"; - } -#endif - tsig_ret = write_tsig_info(a, tsig_name, &tsig_fd, tsig_ret); - } - if (tsig_fd > 0) - close(tsig_fd); - - argv[argc] = NULL; - -#ifdef DEBUG - if (debug >= 1) { - char buffer[1024]; - char *curr, *last; - int len; - - curr = buffer; - last = &buffer[sizeof buffer - 1]; /* leave room for \0 */ - for (i = 0; i < argc; i++) { - len = strlen(argv[i]); - if (curr + len + 1 >= last) { - ns_debug(ns_log_xfer_in, 1, - "xfer args debug printout truncated"); - break; - } - strncpy(curr, argv[i], len); - curr += len; - *curr = ' '; - curr++; - } - *curr = '\0'; - ns_debug(ns_log_xfer_in, 1, buffer); - } -#endif /* DEBUG */ - - gettime(&tt); - for (i = 0; i < MAX_XFERS_RUNNING; i++) - if (xferstatus[i].xfer_pid == 0) - break; - if (i == MAX_XFERS_RUNNING) { - ns_warning(ns_log_default, - "startxfer: too many xfers running"); - zp->z_time = tt.tv_sec + 10; - (void)nxfers(zp, -1); - return; - } - - if ((pid = spawnxfer(argv, zp)) == -1) { - unlink(tsig_name); - return; - } - - xferstatus[i].xfer_state = XFER_RUNNING; - xferstatus[i].xfer_pid = pid; /* XXX - small race condition here if we - * can't hold signals */ - ns_debug(ns_log_default, 1, "started xfer child %d", pid); - zp->z_flags &= ~Z_NEED_XFER; - zp->z_flags |= Z_XFER_RUNNING; - zp->z_xferpid = pid; - xfers_running++; - if (zp->z_max_transfer_time_in) - zp->z_time = tt.tv_sec + zp->z_max_transfer_time_in; - else - zp->z_time = tt.tv_sec + server_options->max_transfer_time_in; -} - -const char * -zoneTypeString(u_int type) { - static char ret[sizeof "(4294967296?)"]; /* 2^32 */ - - switch (type) { - case Z_MASTER: return ("master"); - case Z_SLAVE: return ("slave"); -#ifdef STUBS - case Z_STUB: return ("stub"); -#endif - case Z_HINT: return ("hint"); - case Z_CACHE: return ("cache"); - case Z_FORWARD: return ("forward"); - default: - sprintf(ret, "(%u?)", type); - return (ret); - } -} - -#ifdef DEBUG -void -printzoneinfo(int zonenum, int category, int level) { - struct timeval tt; - struct zoneinfo *zp = &zones[zonenum]; - - if (debug == 0) - return; - - if (!zp->z_origin) - return; - - gettime(&tt); - - ns_debug(category, level, "zone %d: %s, class %s, type %s", zonenum, - zp->z_origin[0] ? zp->z_origin : ".", - p_class(zp->z_class), zoneTypeString(zp->z_type)); - if (zp->z_source) - ns_debug(category, level, "\tsource %s", zp->z_source); - ns_debug(category, level, "\tflags %lx, serial %u, minimum %u", - (u_long)zp->z_flags, zp->z_serial, zp->z_minimum); - ns_debug(category, level, "\trefresh %u, retry %u, expire %u", - zp->z_refresh, zp->z_retry, zp->z_expire); - if (zp->z_time) - ns_debug(category, level, "\tz_time %lu (now %lu, left: %lu)", - zp->z_time, (u_long)tt.tv_sec, - (u_long)(zp->z_time - tt.tv_sec)); - else - ns_debug(category, level, "\tz_time %lu", zp->z_time); -#ifdef BIND_UPDATE - if (zp->z_type == z_master && (zp->z_flags & Z_DYNAMIC) != 0) { - ns_debug(category, level, - "\tdumpintvl %lu, soaincrintvl %lu deferupdcnt %lu", - zp->z_dumpintvl, zp->z_soaincrintvl, - zp->z_deferupdcnt); - if (zp->z_soaincrtime) - ns_debug(category, level, - "\tz_soaincrtime %lu (now %lu, left: %lu)", - zp->z_soaincrtime, (u_long)tt.tv_sec, - (u_long)(zp->z_soaincrtime - tt.tv_sec)); - else - ns_debug(category, level, "\tz_soaincrtime %lu", - zp->z_soaincrtime); - if (zp->z_dumptime) - ns_debug(category, level, - "\tz_dumptime %lu (now %lu, left: %lu)", - zp->z_dumptime, (u_long)tt.tv_sec, - (u_long)(zp->z_dumptime - tt.tv_sec)); - else - ns_debug(category, level, "\tz_dumptime %lu", - zp->z_dumptime); - } -#endif -} -#endif /* DEBUG */ - -/* - * Remove all cached data below dname, class independent. - */ -void -clean_cache_from(char *dname, struct hashbuf *htp) { - const char *fname; - struct databuf *dp, *pdp; - struct namebuf *np; - struct hashbuf *phtp = htp; - int root_zone = 0; - - ns_debug(ns_log_default, 1, "clean_cache_from(%s)", dname); - if ((np = nlookup(dname, &phtp, &fname, 0)) && dname == fname && - !ns_wildcard(NAME(*np))) { - for (pdp = NULL, dp = np->n_data; dp != NULL; (void)NULL) { - if (dp->d_zone == DB_Z_CACHE) - dp = rm_datum(dp, np, pdp, NULL); - else { - pdp = dp; - dp = dp->d_next; - } - } - - if (*dname == '\0') - root_zone = 1; - - if (np->n_hash != NULL || root_zone) { - struct hashbuf *h; - - if (root_zone) - h = htp; - else - h = np->n_hash; - (void)clean_cache(h, 1); - if (h->h_cnt == 0 && !root_zone) { - rm_hash(np->n_hash); - np->n_hash = NULL; - } - } - - if (!root_zone && np->n_hash == NULL && np->n_data == NULL) - (void) purge_node(htp, np); - } -} - -/* clean_cache(htp, all) - * Scan the entire cache looking for expired TTL's on nonauthoritative - * data, and remove it. if `all' is true, ignore TTL and rm everything. - * notes: - * this should be lazy and eventlib driven. - * return: - * number of deleted RRs (all=1) or RRsets (all=0). - */ -int -clean_cache(struct hashbuf *htp, int all) { - struct databuf *dp, *pdp; - struct namebuf *np, *pnp, *npn; - struct namebuf **npp, **nppend; - int deleted = 0; - - nppend = htp->h_tab + htp->h_size; - for (npp = htp->h_tab; npp < nppend; npp++) { - for (pnp = NULL, np = *npp; np != NULL; np = npn) { - again: - for (pdp = NULL, dp = np->n_data; dp != NULL; - (void)NULL) { - if (all && dp->d_zone == DB_Z_CACHE) { - dp = rm_datum(dp, np, pdp, NULL); - deleted++; - } else if (dp->d_zone == DB_Z_CACHE && - stale(dp)) { - delete_all(np, dp->d_class, dp->d_type); - deleted++; - goto again; - } else { - pdp = dp; - dp = dp->d_next; - } - } /*for(pdp)*/ - - if (np->n_hash) { - /* Call recursively to remove subdomains. */ - deleted += clean_cache(np->n_hash, all); - - /* If now empty, free it */ - if (np->n_hash->h_cnt == 0) { - rm_hash(np->n_hash); - np->n_hash = NULL; - } - } - - if (np->n_hash == NULL && np->n_data == NULL) { - npn = rm_name(np, npp, pnp); - htp->h_cnt--; - } else { - npn = np->n_next; - pnp = np; - } - } /*for(pnp)*/ - } /*for(npp)*/ - return (deleted); -} - -/* struct namebuf * - * purge_node(htp, np) - * Remove entry from cache. - * Prerequisites: - * Node is empty and has no children. - * Paramters: - * htp - root of recursive hash table this node is part of. - * np - the node to be deleted. - * Return: - * pointer to parent. - */ -struct namebuf * -purge_node(struct hashbuf *htp, struct namebuf *np) { - struct namebuf **npp, **nppend; - struct namebuf *npn, *pnp, *nnp, *parent; - struct hashbuf *phtp; - - ns_debug(ns_log_default, 3, "purge_node: cleaning cache"); - INSIST(np->n_hash == NULL && np->n_data == NULL); - - /* Walk parent hashtable looking for ourself. */ - parent = np->n_parent; - if (parent != NULL) - phtp = parent->n_hash; - else - phtp = htp; - - if (phtp == NULL) { - /* XXX why shouldn't we panic? */ - } else { - nppend = phtp->h_tab + phtp->h_size; - for (npp = phtp->h_tab; npp < nppend; npp++) { - for (pnp = NULL, nnp = *npp; nnp != NULL; nnp = npn) { - if (nnp == np) { - ns_debug(ns_log_default, 3, - "purge_node: found ourself"); - npn = rm_name(nnp, npp, pnp); - phtp->h_cnt--; - } else { - npn = nnp->n_next; - pnp = nnp; - } - } - } - } - return (parent); -} - -void -remove_zone(struct zoneinfo *zp, const char *verb) { -#ifdef BIND_UPDATE - /* - * A dynamic zone might have changed, so we - * need to dump it before removing it. - */ - if ((zp->z_flags & Z_DYNAMIC) != 0 && - ((zp->z_flags & Z_NEED_SOAUPDATE) != 0 || - (zp->z_flags & Z_NEED_DUMP) != 0)) - (void) zonedump(zp, ISNOTIXFR); -#endif - if ((zp->z_flags & Z_NOTIFY) != 0) - ns_stopnotify(zp->z_origin, zp->z_class); - ns_stopxfrs(zp); - do_reload(zp->z_origin, zp->z_type, zp->z_class, 1); - ns_notice(ns_log_config, "%s zone \"%s\" (%s) %s", - zoneTypeString(zp->z_type), zp->z_origin, - p_class(zp->z_class), verb); - free_zone_contents(zp, 1); - memset(zp, 0, sizeof(*zp)); - zp->z_type = z_nil; /* Pedantic; memset() did it. */ - INIT_LINK(zp, z_reloadlink); - free_zone(zp); -} - -int -purge_nonglue(const char *dname, struct hashbuf *htp, int class) { - const char *fname; - struct namebuf *np; - struct hashbuf *phtp = htp; - int root_zone = 0; - int errs = 0; - - ns_debug(ns_log_default, 1, "purge_zone(%s,%d)", dname, class); - if ((np = nlookup(dname, &phtp, &fname, 0)) && dname == fname && - !ns_wildcard(NAME(*np))) { - - if (*dname == '\0') - root_zone = 1; - - if (np->n_hash != NULL || root_zone) { - struct hashbuf *h; - - if (root_zone) - h = htp; - else - h = np->n_hash; - errs += purge_nonglue_2(dname, h, class, 0); - if (h->h_cnt == 0 && !root_zone) { - rm_hash(np->n_hash); - np->n_hash = NULL; - } - } - } - return (errs); -} - -static int -valid_glue(struct databuf *dp, char *name, int belowcut) { - - /* NS records are only valid glue at the zone cut */ - if (belowcut && dp->d_type == T_NS) - return(0); - - if (ISVALIDGLUE(dp)) /* T_NS/T_A/T_AAAA/T_A6 */ - return (1); - - if (belowcut) - return (0); - - /* Parent NXT record? */ - if (dp->d_type == T_NXT && !ns_samedomain((char*)dp->d_data, name) && - ns_samedomain((char*)dp->d_data, zones[dp->d_zone].z_origin)) - return (1); - - /* NOKEY is in parent zone otherwise child zone */ - if (dp->d_type == T_KEY && dp->d_size == 4 && - (dp->d_data[0] & 0xc6) == 0xc2) - return (1); - - /* NXT & KEY records may be signed */ - if (!belowcut && dp->d_type == T_SIG && - (SIG_COVERS(dp) == T_NXT || SIG_COVERS(dp) == T_KEY)) - return (1); - return (0); -} - -static int -purge_nonglue_2(const char *dname, struct hashbuf *htp, int class, - int belowcut) -{ - struct databuf *dp, *pdp; - struct namebuf *np, *pnp, *npn; - struct namebuf **npp, **nppend; - int errs = 0; - int zonecut; - char name[MAXDNAME]; - - nppend = htp->h_tab + htp->h_size; - for (npp = htp->h_tab; npp < nppend; npp++) { - for (pnp = NULL, np = *npp; np != NULL; np = npn) { - if (!bottom_of_zone(np->n_data, class)) { - zonecut = belowcut; - for (dp = np->n_data; dp != NULL; - dp = dp->d_next) { - if (match(dp, class, ns_t_ns)) { - zonecut = 1; - break; - } - } - getname(np, name, sizeof name); - for (pdp = NULL, dp = np->n_data; - dp != NULL; - (void)NULL) { - if (dp->d_class == class && - zonecut && - !valid_glue(dp, name, belowcut)) { - ns_error(ns_log_db, - "zone: %s/%s: non-glue record %s bottom of zone: %s/%s", - *dname ? dname : ".", - p_class(dp->d_class), - belowcut ? "below" : - "at", - *name ? name : ".", - p_type(dp->d_type)); - dp = rm_datum(dp, np, pdp, - NULL); - errs++; - } else { - pdp = dp; - dp = dp->d_next; - } - } - if (np->n_hash) { - /* - * call recursively to clean - * subdomains - */ - errs += purge_nonglue_2(dname, - np->n_hash, - class, - zonecut || - belowcut); - - /* if now empty, free it */ - if (np->n_hash->h_cnt == 0) { - rm_hash(np->n_hash); - np->n_hash = NULL; - } - } - } - - if (np->n_hash == NULL && np->n_data == NULL) { - npn = rm_name(np, npp, pnp); - htp->h_cnt--; - } else { - npn = np->n_next; - pnp = np; - } - } - } - return (errs); -} - -void -purge_zone(const char *dname, struct hashbuf *htp, int class) { - const char *fname; - struct databuf *dp, *pdp; - struct namebuf *np; - struct hashbuf *phtp = htp; - int root_zone = 0; - - ns_debug(ns_log_default, 1, "purge_zone(%s,%d)", dname, class); - if ((np = nlookup(dname, &phtp, &fname, 0)) && dname == fname && - !ns_wildcard(NAME(*np))) { - for (pdp = NULL, dp = np->n_data; dp != NULL; (void)NULL) { - if (dp->d_class == class) - dp = rm_datum(dp, np, pdp, NULL); - else { - pdp = dp; - dp = dp->d_next; - } - } - - if (*dname == '\0') - root_zone = 1; - - if (np->n_hash != NULL || root_zone) { - struct hashbuf *h; - - if (root_zone) - h = htp; - else - h = np->n_hash; - purge_z_2(h, class); - if (h->h_cnt == 0 && !root_zone) { - rm_hash(np->n_hash); - np->n_hash = NULL; - } - } - - if (!root_zone && np->n_hash == NULL && np->n_data == NULL) - (void) purge_node(htp, np); - } -} - -static void -purge_z_2(htp, class) - struct hashbuf *htp; - int class; -{ - struct databuf *dp, *pdp; - struct namebuf *np, *pnp, *npn; - struct namebuf **npp, **nppend; - - nppend = htp->h_tab + htp->h_size; - for (npp = htp->h_tab; npp < nppend; npp++) { - for (pnp = NULL, np = *npp; np != NULL; np = npn) { - if (!bottom_of_zone(np->n_data, class)) { - for (pdp = NULL, dp = np->n_data; - dp != NULL; - (void)NULL) { - if (dp->d_class == class) - dp = rm_datum(dp, np, pdp, - NULL); - else { - pdp = dp; - dp = dp->d_next; - } - } - if (np->n_hash) { - /* call recursively to rm subdomains */ - purge_z_2(np->n_hash, class); - - /* if now empty, free it */ - if (np->n_hash->h_cnt == 0) { - rm_hash(np->n_hash); - np->n_hash = NULL; - } - } - } - - if (np->n_hash == NULL && np->n_data == NULL) { - npn = rm_name(np, npp, pnp); - htp->h_cnt--; - } else { - npn = np->n_next; - pnp = np; - } - } - } -} - -static int -bottom_of_zone(struct databuf *dp, int class) { - int ret = 0; - - for ((void)NULL; dp; dp = dp->d_next) { - if (dp->d_class != class) - continue; - if (dp->d_zone == DB_Z_CACHE) - continue; - if (dp->d_rcode) /* This should not occur. */ - continue; - if (dp->d_type != T_SOA) - continue; - ret = 1; - break; - } - ns_debug(ns_log_default, 3, "bottom_of_zone() == %d", ret); - return (ret); -} - -/* - * Handle XFER limit for a nameserver. - */ -static int -nxfers(struct zoneinfo *zp, int delta) { - struct in_addr nsa; - struct nameser *nsp; - int ret; - - if (zp->z_xaddrcnt != 0) - nsa = zp->z_xaddr[0]; /* first ns holds zone's xfer limit */ - else if (zp->z_addrcnt != 0) - nsa = zp->z_addr[0]; /* first ns holds zone's xfer limit */ - else - return (-1); - - if (!(nsp = nameserFind(nsa, NS_F_INSERT))) - return (-1); /* probably ENOMEM */ - - ret = nsp->xfers; - if (delta < 0 && -delta > ret) - return (-1); /* taking more than we have */ - - nsp->xfers += delta; - return (ret); -} - -/* - * Abort an xfer that has taken too long. - */ -static void -abortxfer(struct zoneinfo *zp) { - if (zp->z_flags & (Z_XFER_GONE|Z_XFER_ABORTED)) { - int i; - - for (i = 0; i < MAX_XFERS_RUNNING; i++) { - if (xferstatus[i].xfer_pid == zp->z_xferpid) { - xferstatus[i].xfer_pid = 0; - xferstatus[i].xfer_state = XFER_IDLE; - break; - } - } - - if (zp->z_flags & Z_XFER_GONE) - ns_warning(ns_log_default, - "zone transfer timeout for \"%s\"; pid %lu missing", - zp->z_origin, (u_long)zp->z_xferpid); - else if (kill(zp->z_xferpid, SIGKILL) == -1) - ns_warning(ns_log_default, - "zone transfer timeout for \"%s\"; kill pid %lu: %s", - zp->z_origin, (u_long)zp->z_xferpid, - strerror(errno)); - else - ns_warning(ns_log_default, -"zone transfer timeout for \"%s\"; second kill \ -pid %lu - forgetting, processes may accumulate", - zp->z_origin, (u_long)zp->z_xferpid); - - zp->z_xferpid = 0; - xfers_running--; - (void)nxfers(zp, -1); - zp->z_flags &= ~(Z_XFER_RUNNING|Z_XFER_ABORTED|Z_XFER_GONE); - } else if (kill(zp->z_xferpid, SIGTERM) == -1) { - if (errno == ESRCH) - /* No warning on first time, it may have just exited */ - zp->z_flags |= Z_XFER_GONE; - else { - ns_warning(ns_log_default, - "zone transfer timeout for \"%s\"; pid %lu kill failed %s", - zp->z_origin, (u_long)zp->z_xferpid, - strerror(errno)); - zp->z_flags |= Z_XFER_ABORTED; - } - } else { - ns_notice(ns_log_default, - "zone transfer timeout for \"%s\"; pid %lu killed", - zp->z_origin, (u_long)zp->z_xferpid); - zp->z_flags |= Z_XFER_ABORTED; - } -} - -/* - * Process exit of xfer's. - */ -void -reapchild(void) { - int i; - pid_t pid; - WAIT_T status; - - gettime(&tt); - while ((pid = (pid_t)waitpid(-1, &status, WNOHANG)) > 0) { - for (i = 0; i < MAX_XFERS_RUNNING; i++) { - if (xferstatus[i].xfer_pid == pid) { - xferstatus[i].xfer_status = status; - xferstatus[i].xfer_state = XFER_DONE; - ns_need(main_need_endxfer); - break; - } - } - } -} - -/* - * Finish processing of of finished xfers - */ -void -endxfer() { - struct zoneinfo *zp; - int exitstatus, i; - pid_t pid; - WAIT_T status; - - gettime(&tt); - - for (i = 0; i < MAX_XFERS_RUNNING; i++) { - if (xferstatus[i].xfer_state != XFER_DONE) - continue; - pid = xferstatus[i].xfer_pid; - status = xferstatus[i].xfer_status; - exitstatus = WIFEXITED(status) ? WEXITSTATUS(status) : 0; - - for (zp = zones; zp < &zones[nzones]; zp++) { - if (zp->z_xferpid != pid) - continue; - xfers_running--; - (void) nxfers(zp, -1); - zp->z_xferpid = 0; - zp->z_flags &= - ~(Z_XFER_RUNNING|Z_XFER_ABORTED|Z_XFER_GONE); - ns_debug(ns_log_default, 1, - "\nendxfer: child %d zone %s returned status=%d termsig=%d", - pid, zp->z_origin, exitstatus, - WIFSIGNALED(status) ? WTERMSIG(status) : -1); - if (WIFSIGNALED(status)) { - if (WTERMSIG(status) != SIGKILL) { - ns_notice(ns_log_default, - "named-xfer \"%s\" exited with signal %d", - zp->z_origin[0]?zp->z_origin:".", - WTERMSIG(status)); - } - ns_retrytime(zp, tt.tv_sec); - sched_zone_maint(zp); - } else { - switch (exitstatus) { - case XFER_UPTODATE: - markUpToDate(zp); - sched_zone_maint(zp); - break; - - case XFER_SUCCESSAXFR: - case XFER_SUCCESSAXFRIXFRFILE: - zp->z_xferpid = XFER_ISAXFR; - if (exitstatus == XFER_SUCCESSAXFRIXFRFILE) { - zp->z_xferpid = XFER_ISAXFRIXFR; - } - movefile(zp->z_ixfr_tmp, zp->z_source); - /* XXX should incorporate loadxfer() */ - zp->z_flags |= Z_NEED_RELOAD; - zp->z_flags &= ~Z_SYSLOGGED; - ns_need(main_need_zoneload); - break; - - case XFER_SUCCESSIXFR: - zp->z_flags |= Z_XFER_RUNNING; - zp->z_xferpid = XFER_ISIXFR; - ns_notice(ns_log_default, - "IXFR Success %s", - zp->z_ixfr_tmp); - if (merge_logs(zp, zp->z_ixfr_tmp) >= 0) { - ns_notice(ns_log_default, - "IXFR Merge success %s", - zp->z_ixfr_tmp); - - (void)unlink(zp->z_updatelog); - (void)unlink(zp->z_ixfr_base); - movefile(zp->z_ixfr_tmp, - zp->z_ixfr_base); - (void)unlink(zp->z_ixfr_tmp); - if (zonedump(zp, ISIXFR) < 0) - ns_warning(ns_log_db, - "error in write ixfr updates to zone file %s", - zp ->z_source); - } else - ns_notice(ns_log_default, - "IXFR Merge failed %s", - zp->z_ixfr_tmp); - zp->z_flags &= - ~(Z_XFER_RUNNING|Z_XFER_ABORTED|Z_XFER_GONE); - break; - - case XFER_TIMEOUT: - if (!(zp->z_flags & Z_SYSLOGGED)) { - zp->z_flags |= Z_SYSLOGGED; - ns_notice(ns_log_default, - "zoneref: Masters for secondary zone \"%s\" unreachable", - zp->z_origin); - } - ns_retrytime(zp, tt.tv_sec); - sched_zone_maint(zp); - break; - - default: - if (!(zp->z_flags & Z_SYSLOGGED)) { - zp->z_flags |= Z_SYSLOGGED; - ns_notice(ns_log_default, - "named-xfer for \"%s\" exited %d", - zp->z_origin, - exitstatus); - } - /* FALLTHROUGH */ - case XFER_FAIL: - zp->z_flags |= Z_SYSLOGGED; - ns_retrytime(zp, tt.tv_sec); - sched_zone_maint(zp); - break; - } - break; - } - } - xferstatus[i].xfer_state = XFER_IDLE; - xferstatus[i].xfer_pid = 0; - } - tryxfer(); -} - -/* - * Try to start some xfers - new "fair scheduler" by Bob Halley @DEC (1995) - */ -static void -tryxfer() { - static struct zoneinfo *zp = NULL; - static struct zoneinfo *lastzones = NULL; - static int lastnzones = 0; - struct zoneinfo *startzp, *stopzp; - - /* initialize, and watch out for changes in zones! */ - if (lastzones != zones) { - if (lastzones != NULL) - ns_debug(ns_log_default, 3, "zones changed: %p != %p", - lastzones, zones); - lastzones = zones; - zp = zones; - } - - /* did zones shrink? */ - if (lastnzones > nzones) { - ns_debug(ns_log_default, 3, "zones shrunk"); - zp = zones; - } - lastnzones = nzones; - - if (zp == zones) - stopzp = &zones[nzones-1]; - else - stopzp = zp - 1; - - ns_debug(ns_log_default, 3, - "tryxfer start zp=%p stopzp=%p def=%d running=%d", - zp, stopzp, xfers_deferred, xfers_running); - - startzp = zp; - for (;;) { - int xfers; - - if (!xfers_deferred || - xfers_running >= server_options->transfers_in) - break; - - if ((xfers = nxfers(zp, 0)) != -1 && - xfers < server_options->transfers_per_ns && - (zp->z_flags & Z_NEED_XFER)) { - nxfers(zp, 1); - xfers_deferred--; - startxfer(zp); - sched_zone_maint(zp); - } - - if (zp == stopzp) { - ns_debug(ns_log_default, 3, "tryxfer stop mark"); - zp = startzp; - break; - } - - zp++; - /* wrap around? */ - if (zp == &zones[nzones]) - zp = zones; - } - ns_debug(ns_log_default, 3, "tryxfer stop zp=%p", zp); -} - -/* - * Reload zones whose transfers have completed. - */ -void -loadxfer(void) { - struct zoneinfo *zp; - u_int32_t old_serial,new_serial; - char *tmpnom; - int isixfr; - - gettime(&tt); - for (zp = zones; zp < &zones[nzones]; zp++) { - if (zp->z_flags & Z_NEED_RELOAD) { - ns_debug(ns_log_default, 1, "loadxfer() \"%s\"", - zp->z_origin[0] ? zp->z_origin : "."); - zp->z_flags &= ~(Z_NEED_RELOAD|Z_AUTH); -/* XXX this is bad, should be done in ns_zreload() for primary changes. */ - ns_stopxfrs(zp); - old_serial = zp->z_serial; - if (zp->z_xferpid == XFER_ISIXFR) { - tmpnom = zp->z_ixfr_tmp; - isixfr = ISIXFR; - } else { - tmpnom = zp->z_source; - purge_zone(zp->z_origin, hashtab, zp->z_class); - isixfr = ISNOTIXFR; - } - if (zp->z_xferpid == XFER_ISAXFRIXFR) { - tmpnom= zp->z_source; - purge_zone(zp->z_origin, hashtab, zp->z_class); - isixfr = ISNOTIXFR; - } - - if (!db_load(tmpnom, zp->z_origin, zp, NULL, isixfr)) { - zp->z_flags |= Z_AUTH; - zp->z_flags &= ~Z_EXPIRED; - if (isixfr == ISIXFR) { - new_serial= zp ->z_serial; - ns_warning(ns_log_db, "ISIXFR"); - ns_warning(ns_log_db, "error in updating ixfr data base file %s from %s", zp -> z_ixfr_base, zp ->z_ixfr_tmp); - if (zonedump(zp,ISIXFR)<0) - ns_warning(ns_log_db, "error in write ixfr updates to zone file %s", zp ->z_source); - - } - } - zp->z_xferpid = 0; - if (zp->z_flags & Z_TMP_FILE) - (void) unlink(zp->z_source); - sched_zone_maint(zp); - } - } -} - -/* - * Add this zone to the set of those needing transfers. - */ -void -addxfer(struct zoneinfo *zp) { - if (!(zp->z_flags & Z_NEED_XFER)) { - zp->z_flags |= Z_NEED_XFER; - xfers_deferred++; - tryxfer(); - } -} - -/* - * Mark one zone as requiring a reload. - * Note that it should be called with signals blocked, - * and should not allocate memory (since it can be called from a sighandler). - */ -const char * -deferred_reload_unsafe(struct zoneinfo *zp) { - INSIST(zp->z_type != z_nil); - if (!zonefile_changed_p(zp)) - return ("Zone file has not changed."); - if (LINKED(zp, z_reloadlink)) - return ("Zone is already scheduled for reloading."); - APPEND(reloadingzones, zp, z_reloadlink); - ns_need_unsafe(main_need_zreload); - return ("Zone is now scheduled for reloading."); -} - -/* - * If we've loaded this file, and the file has not been modified and contains - * no $INCLUDE, then there's no need to reload. - */ -int -zonefile_changed_p(struct zoneinfo *zp) { - struct stat sb; - - INSIST(zp->z_type != z_nil); - return ((zp->z_flags & Z_INCLUDE) != 0 || - stat(zp->z_source, &sb) == -1 || - zp->z_ftime != sb.st_mtime); -} - -int -reload_master(struct zoneinfo *zp) { - INSIST(zp->z_type == z_master); - zp->z_flags &= ~Z_AUTH; - ns_stopxfrs(zp); - /* XXX what about parent zones? */ -#ifdef BIND_UPDATE - /* - * A dynamic zone might have changed, so we - * need to dump it before reloading it. - */ - if ((zp->z_flags & Z_DYNAMIC) != 0 && - ((zp->z_flags & Z_NEED_SOAUPDATE) != 0 || - (zp->z_flags & Z_NEED_DUMP) != 0)) - (void) zonedump(zp, ISNOTIXFR); -#endif - purge_zone(zp->z_origin, hashtab, zp->z_class); - ns_debug(ns_log_config, 1, "reloading zone"); -#ifdef BIND_UPDATE - if ((zp->z_flags & Z_DYNAMIC) != 0) { - struct stat sb; - - if (stat(zp->z_source, &sb) < 0) - ns_error(ns_log_config, "stat(%s) failed: %s", - zp->z_source, strerror(errno)); - else { - if ((sb.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) != 0) - ns_warning(ns_log_config, - "dynamic zone file '%s' is writable", - zp->z_source); - } - } -#endif - if (!db_load(zp->z_source, zp->z_origin, zp, NULL, ISNOTIXFR)) - zp->z_flags |= Z_AUTH; - zp->z_refresh = 0; /* no maintenance needed */ - zp->z_time = 0; -#ifdef BIND_UPDATE - zp->z_lastupdate = 0; - if ((zp->z_flags & Z_DYNAMIC) != 0) - if (merge_logs(zp, zp->z_updatelog) == 1) - return (1); -#endif - return (0); -} - -/* - * Called by main() when main_need_zreload has been set. Should pull one - * zone off of the reloadingzones list and reload it, then if the list is - * not then empty, should turn main_need_zreload on again for the next call. - * It is not an error to call this when the reloadingzones list is empty. - */ -void -ns_zreload(void) { - struct zoneinfo *zp; - - block_signals(); - if (EMPTY(reloadingzones)) { - unblock_signals(); - return; - } - zp = HEAD(reloadingzones); - UNLINK(reloadingzones, zp, z_reloadlink); - unblock_signals(); - - reload_master(zp); - - block_signals(); - if (!EMPTY(reloadingzones)) - ns_need_unsafe(main_need_zreload); - unblock_signals(); -} - -/* - * Flush and reload configuration file and data base. - */ -void -ns_reload(void) { - ns_notice(ns_log_default, "%s %snameserver", - (reconfiging != 0) ? "reconfiguring" : "reloading", - (noexpired == 1) ? "(-noexpired) " : ""); - - INSIST(reloading == 0); - qflush(); - sq_flush(NULL); - reloading++; /* To force transfer if secondary and backing up. */ - ns_init(conffile); - time(&resettime); - reloading--; - ns_notice(ns_log_default, "Ready to answer queries."); -} - -/* - * Reload configuration, look for new or deleted zones, not changed ones - * also ignore expired zones. - */ -void -ns_noexpired(void) { - INSIST(noexpired == 0); - noexpired++; /* To ignore zones which are expired */ - ns_reconfig(); - noexpired--; -} - -/* - * Reload configuration, look for new or deleted zones, not changed ones. - */ -void -ns_reconfig(void) { - INSIST(reconfiging == 0); - reconfiging++; /* To ignore zones which aren't new or deleted. */ - ns_reload(); - reconfiging--; -} - -void -make_new_zones(void) { - struct zoneinfo *zp; - int n; - - ns_debug(ns_log_config, 1, "Adding %d template zones", NEWZONES); - zp = (struct zoneinfo *) - memget((nzones + NEWZONES) * sizeof(struct zoneinfo)); - if (zp == NULL) - panic("no memory for more zones", NULL); - memset(zp, 0, (nzones + NEWZONES) * sizeof(struct zoneinfo)); - if (zones != NULL) { - memcpy(zp, zones, nzones * sizeof(struct zoneinfo)); - memput(zones, nzones * sizeof(struct zoneinfo)); - } - zones = zp; - block_signals(); - for (n = 0; n < NEWZONES; n++) { - INIT_LINK(&zones[nzones], z_reloadlink); - if (nzones != 0) - free_zone(&zones[nzones]); - nzones++; - } - unblock_signals(); -} - -void -free_zone(struct zoneinfo *zp) { - if (LINKED(zp, z_reloadlink)) - panic("freeing reloading zone", NULL); - if (zp->z_type != z_nil) - panic("freeing unfree zone", NULL); - APPEND(freezones, zp, z_freelink); -} - -#ifndef HAVE_SPAWNXFER -static pid_t -spawnxfer(char **argv, struct zoneinfo *zp) { - pid_t pid = (pid_t)vfork(); - - if (pid == -1) { - ns_error(ns_log_default, "xfer vfork: %s", strerror(errno)); - zp->z_time = tt.tv_sec + 10; - return (pid); - } - if (pid == 0) { - /* Child. */ - execv(server_options->named_xfer, argv); - ns_error(ns_log_default, "can't exec %s: %s", - server_options->named_xfer, strerror(errno)); - (void)nxfers(zp, -1); - _exit(XFER_FAIL); /* Avoid duplicate buffer flushes. */ - } - return (pid); -} -#endif - -struct zoneinfo * -find_auth_zone(const char *zname, ns_class zclass) { - struct zoneinfo *zp; - struct hashbuf *htp; - struct namebuf *np; - const char *fname; - int zn; - - zp = find_zone(zname, zclass); - if (zp != NULL && - (zp->z_type == z_slave || - zp->z_type == z_master || - zp->z_type == z_stub)) - return (zp); - - htp = hashtab; - np = nlookup(zname, &htp, &fname, 0); - if (np != NULL && (zn = findMyZone(np, zclass)) != DB_Z_CACHE) - return (&zones[zn]); - - return (NULL); -} diff --git a/contrib/bind/bin/named/ns_ncache.c b/contrib/bind/bin/named/ns_ncache.c deleted file mode 100644 index 2b8bb6bd7788c..0000000000000 --- a/contrib/bind/bin/named/ns_ncache.c +++ /dev/null @@ -1,270 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_ncache.c,v 8.27 2000/04/21 06:54:09 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> - -#include <errno.h> -#include <resolv.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include "port_after.h" - -#include "named.h" - -#define BOUNDS_CHECK(ptr, count) \ - do { \ - if ((ptr) + (count) > eom) { \ - return; \ - } \ - } while (0) - -void -cache_n_resp(u_char *msg, int msglen, struct sockaddr_in from, - const char *qname, int qclass, int qtype) -{ - struct databuf *dp; - HEADER *hp; - u_char *cp, *eom, *rdatap; - char dname[MAXDNAME]; - int n, type, class, flags; - u_int ancount, nscount, dlen; -#ifdef RETURNSOA - u_int32_t ttl; - u_int16_t atype; - u_char *sp, *cp1; - u_char data[MAXDATA]; - size_t len = sizeof data; -#endif - - nameserIncr(from.sin_addr, nssRcvdNXD); - - hp = (HEADER *)msg; - cp = msg + HFIXEDSZ; - eom = msg + msglen; - - switch (ntohs(hp->qdcount)) { - case 0: - dname[sizeof dname - 1] = '\0'; - strncpy(dname, qname, sizeof dname); - if (dname[sizeof dname - 1] != '\0') { - ns_debug(ns_log_ncache, 1, - "qp->qname too long (%d)", strlen(qname)); - hp->rcode = FORMERR; - return; - } - class = qclass; - type = qtype; - break; - case 1: - n = dn_expand(msg, eom, cp, dname, sizeof dname); - if (n < 0) { - ns_debug(ns_log_ncache, 1, - "Query expand name failed: cache_n_resp"); - hp->rcode = FORMERR; - return; - } - cp += n; - BOUNDS_CHECK(cp, 2 * INT16SZ); - GETSHORT(type, cp); - GETSHORT(class, cp); - if (class > CLASS_MAX) { - ns_debug(ns_log_ncache, 1, - "bad class in cache_n_resp"); - hp->rcode = FORMERR; - return; - } - break; - default: - ns_debug(ns_log_ncache, 1, - "QDCOUNT>1 (%d) in cache_n_resp", ntohs(hp->qdcount)); - hp->rcode = FORMERR; - return; - } - ns_debug(ns_log_ncache, 1, "ncache: dname %s, type %d, class %d", - dname, type, class); - - ancount = ntohs(hp->ancount); - nscount = ntohs(hp->nscount); - - while (ancount--) { - u_int32_t ttl; - u_int atype, aclass; - - n = dn_skipname(cp, eom); - if (n < 0) { - ns_debug(ns_log_ncache, 3, "ncache: form error"); - return; - } - cp += n; - BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ); - GETSHORT(atype, cp); - GETSHORT(aclass, cp); - if (atype != T_CNAME || aclass != class) { - ns_debug(ns_log_ncache, 3, - "ncache: not CNAME (%s) or wrong class (%s)", - p_type(atype), p_class(aclass)); - return; - } - GETLONG(ttl, cp); - GETSHORT(dlen, cp); - BOUNDS_CHECK(cp, dlen); - rdatap = cp; - n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname); - if (n < 0) { - ns_debug(ns_log_ncache, 3, "ncache: bad cname target"); - return; - } - cp += n; - if (cp != rdatap + dlen) { - ns_debug(ns_log_ncache, 3, "ncache: bad cname rdata"); - return; - } - } - - dp = NULL; -#ifdef RETURNSOA - while (nscount--) { - sp = cp; - - /* we store NXDOMAIN as T_SOA regardless of the query type */ - if (hp->rcode == NXDOMAIN) - type = T_SOA; - - /* store ther SOA record */ - n = dn_skipname(cp, msg + msglen); - if (n < 0) { - ns_debug(ns_log_ncache, 3, "ncache: form error"); - return; - } - cp += n; - - BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ); - GETSHORT(atype, cp); /* type */ - cp += INT16SZ; /* class */ - GETLONG(ttl, cp); /* ttl */ - GETSHORT(dlen, cp); /* dlen */ - BOUNDS_CHECK(cp, dlen); - if (atype != T_SOA) { - ns_debug(ns_log_ncache, 3, - "ncache: type (%d) != T_SOA", atype); - cp += dlen; - continue; - } - rdatap = cp; - - /* origin */ - n = dn_expand(msg, msg + msglen, cp, (char*)data, len); - if (n < 0) { - ns_debug(ns_log_ncache, 3, - "ncache: origin form error"); - return; - } - cp += n; - n = strlen((char*)data) + 1; - cp1 = data + n; - len -= n; - /* mail */ - n = dn_expand(msg, msg + msglen, cp, (char*)cp1, len); - if (n < 0) { - ns_debug(ns_log_ncache, 3, "ncache: mail form error"); - return; - } - cp += n; - n = strlen((char*)cp1) + 1; - cp1 += n; - len -= n; - n = 5 * INT32SZ; - BOUNDS_CHECK(cp, n); - memcpy(cp1, cp, n); - /* serial, refresh, retry, expire, min */ - cp1 += n; - len -= n; - cp += n; - if (cp != rdatap + dlen) { - ns_debug(ns_log_ncache, 3, "ncache: form error"); - return; - } - /* store the zone of the soa record */ - n = dn_expand(msg, msg + msglen, sp, (char*)cp1, len); - if (n < 0) { - ns_debug(ns_log_ncache, 3, "ncache: form error 2"); - return; - } - n = strlen((char*)cp1) + 1; - cp1 += n; - - /* - * we only want to store these long enough so that - * ns_resp can find it. - */ - if (qtype == T_SOA && hp->rcode == NXDOMAIN) - ttl = 0; - dp = savedata(class, type, - MIN(ttl, server_options->max_ncache_ttl) + - tt.tv_sec, data, - cp1 - data); - break; - } -#endif - if (dp == NULL) -#ifdef STRICT_RFC2308 - dp = savedata(class, type, tt.tv_sec, NULL, 0); -#else - dp = savedata(class, type, NTTL + tt.tv_sec, NULL, 0); -#endif - dp->d_zone = DB_Z_CACHE; - dp->d_cred = hp->aa ? DB_C_AUTH : DB_C_ANSWER; - dp->d_secure = DB_S_INSECURE; /* BEW - should be UNCHECKED */ - dp->d_clev = 0; - if(hp->rcode == NXDOMAIN) { - dp->d_rcode = NXDOMAIN; - flags = DB_NODATA|DB_NOTAUTH|DB_NOHINTS; - } else { - dp->d_rcode = NOERROR_NODATA; - flags = DB_NOTAUTH|DB_NOHINTS; - } - - if ((n = db_update(dname, dp, dp, NULL, flags, hashtab, from)) != OK) { - ns_debug(ns_log_ncache, 1, - "db_update failed (%d), cache_n_resp()", n); - db_freedata(dp); - return; - } - ns_debug(ns_log_ncache, 4, - "ncache succeeded: [%s %s %s] rcode:%d ttl:%ld", - dname, p_type(type), p_class(class), - dp->d_rcode, (long)(dp->d_ttl - tt.tv_sec)); -} diff --git a/contrib/bind/bin/named/ns_notify.c b/contrib/bind/bin/named/ns_notify.c deleted file mode 100644 index 0cf1e0a327a58..0000000000000 --- a/contrib/bind/bin/named/ns_notify.c +++ /dev/null @@ -1,424 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_notify.c,v 8.10 2000/04/21 06:54:09 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1994-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* Import. */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <limits.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" - -#ifdef BIND_NOTIFY - -/* Types. */ - -struct notify { - char * name; - ns_class class; - ns_type type; - evTimerID timer; - LINK(struct notify) link; -}; - -/* Forward. */ - -static void sysnotify(const char *, ns_class, ns_type); -static void sysnotify_slaves(const char *, const char *, - ns_class, ns_type, int, int *, int *); -static void sysnotify_ns(const char *, const char *, - ns_class, ns_type, int, int *, int *); -static void free_notify(struct notify *); -static void notify_timer(evContext, void *, - struct timespec, struct timespec); - -/* Local. */ - -static LIST(struct notify) pending_notifies; -static LIST(struct notify) loading_notifies; - -/* Public. */ - -/* - * ns_notify(dname, class, type) - * call this when a zone has changed and its slaves need to know. - */ -void -ns_notify(const char *dname, ns_class class, ns_type type) { - static const char no_room[] = "%s failed, cannot notify for zone %s"; - int delay, max_delay; - struct zoneinfo *zp; - struct notify *ni; - - zp = find_auth_zone(dname, class); - if (zp == NULL) { - ns_warning(ns_log_notify, - "no zone found for notify (\"%s\" %s %s)", - (dname && *dname) ? dname : ".", - p_class(class), p_type(type)); - return; - } - if (ns_samename(dname, zp->z_origin) != 1) { - ns_warning(ns_log_notify, - "notify not called with top of zone (\"%s\" %s %s)", - (dname && *dname) ? dname : ".", - p_class(class), p_type(type)); - return; - } - if ((zp->z_flags & Z_NOTIFY) != 0) { - ns_info(ns_log_notify, - "suppressing duplicate notify (\"%s\" %s %s)", - (dname && *dname) ? dname : ".", - p_class(class), p_type(type)); - return; - } - ni = memget(sizeof *ni); - if (ni == NULL) { - ns_info(ns_log_notify, no_room, "memget", dname); - return; - } - ni->name = savestr(dname, 0); - if (ni->name == NULL) { - memput(ni, sizeof *ni); - ni = NULL; - ns_info(ns_log_notify, no_room, "memget", dname); - return; - } - ni->class = class; - ni->type = type; - evInitID(&ni->timer); - - if (loading != 0) { - APPEND(loading_notifies, ni, link); - return; - } - - /* Delay notification for from five seconds up to fifteen minutes. */ - max_delay = MIN(nzones/5, 895); - max_delay = MAX(max_delay, 25); - delay = 5 + (rand() % max_delay); - if (evSetTimer(ev, notify_timer, ni, - evAddTime(evNowTime(), evConsTime(delay, 0)), - evConsTime(0, 0), &ni->timer) < 0) { - ns_error(ns_log_notify, "evSetTimer() failed: %s", - strerror(errno)); - freestr(ni->name); - memput(ni, sizeof *ni); - return; - } - - zp->z_flags |= Z_NOTIFY; - APPEND(pending_notifies, ni, link); - ns_debug(ns_log_notify, 3, - "ns_notify(%s, %s, %s): ni %p, zp %p, delay %d", - (dname && *dname) ? dname : ".", - p_class(class), p_type(type), - ni, zp, delay); -} - -void -notify_afterload() { - struct notify *ni; - - INSIST(loading == 0); - while ((ni = HEAD(loading_notifies)) != NULL) { - UNLINK(loading_notifies, ni, link); - ns_notify(ni->name, ni->class, ni->type); - freestr(ni->name); - memput(ni, sizeof *ni); - } -} - -/* - * ns_unnotify() - * call this when all pending notifies are now considered junque. - */ -void -ns_unnotify(void) { - while (!EMPTY(pending_notifies)) { - struct notify *ni = HEAD(pending_notifies); - - INSIST(LINKED(ni, link)); - UNLINK(pending_notifies, ni, link); - free_notify(ni); - } -} - -/* - * ns_stopnotify(const char *dname, ns_class class) - * stop notifies for this particular zone. - */ -void -ns_stopnotify(const char *dname, ns_class class) { - struct notify *ni; - - ni = HEAD(pending_notifies); - while (ni != NULL && - (ni->class != class || ns_samename(ni->name, dname) != 1)) - ni = NEXT(ni, link); - - if (ni != NULL) { - UNLINK(pending_notifies, ni, link); - free_notify(ni); - } -} - -/* Private. */ - -/* - * sysnotify(dname, class, type) - * cause a NOTIFY request to be sysquery()'d to each slave server - * of the zone that "dname" is within. - */ -static void -sysnotify(const char *dname, ns_class class, ns_type type) { - const char *zname, *fname; - u_int32_t zserial; - int nns, na, i; - struct zoneinfo *zp; - struct in_addr *also_addr; - - ns_debug(ns_log_notify, 3, "sysnotify(%s, %s, %s)", - dname, p_class(class), p_type(type)); - zp = find_auth_zone(dname, class); - if (zp == NULL) { - ns_warning(ns_log_notify, "sysnotify: can't find \"%s\" (%s)", - dname, p_class(class)); - return; - } - if (ns_samename(dname, zp->z_origin) != 1) { - ns_warning(ns_log_notify, "sysnotify: not auth for zone %s", - dname); - return; - } - if (zp->z_notify == znotify_no || - (zp->z_notify == znotify_use_default && - NS_OPTION_P(OPTION_NONOTIFY))) - return; - if (zp->z_type != z_master && zp->z_type != z_slave) { - ns_warning(ns_log_notify, "sysnotify: %s not master or slave", - dname); - return; - } - zname = zp->z_origin; - zserial = zp->z_serial; - nns = na = 0; - sysnotify_slaves(dname, zname, class, type, zp - zones, &nns, &na); - - /* - * Handle any global or zone-specific also-notify clauses - */ - if (zp->z_notify_count != 0) { - /* zone-specific also notify */ - - ns_debug(ns_log_notify, 3, "zone notify ns = %d", - zp->z_notify_count); - - also_addr = zp->z_also_notify; - for (i = 0; i < zp->z_notify_count; i++) { - ns_debug(ns_log_notify, 4, "notifying %s", - inet_ntoa(*also_addr)); - sysquery(dname, class, type, also_addr, 1, ns_port, - NS_NOTIFY_OP); - also_addr++; - } - nns += zp->z_notify_count; - na += zp->z_notify_count; - } else if (server_options->notify_count != 0) { - ns_debug(ns_log_notify, 4, "global notify ns = %d", - server_options->notify_count); - also_addr = server_options->also_notify; - for (i = 0; i < server_options->notify_count; i++) { - ns_debug(ns_log_notify, 3, "notifying %s", - inet_ntoa(*also_addr)); - sysquery(dname, class, type, also_addr, - 1, ns_port, ns_o_notify); - also_addr++; - } - nns += server_options->notify_count; - na += server_options->notify_count; - } - - if (nns != 0 || na != 0) - ns_info(ns_log_notify, - "Sent NOTIFY for \"%s %s %s %u\" (%s); %d NS, %d A", - dname, p_class(class), p_type(type), zserial, zname, nns, na); -} - -static void -sysnotify_slaves(const char *dname, const char *zname, - ns_class class, ns_type type, - int zn, int *nns, int *na) -{ - const char *mname, *fname; - struct hashbuf *htp; - struct namebuf *np; - struct databuf *dp; - - /* - * Master. - */ - htp = hashtab; - np = nlookup(zname, &htp, &fname, 0); - if (np == NULL) { - ns_warning(ns_log_notify, - "sysnotify: found name \"%s\" but not zone", - dname); - return; - } - mname = NULL; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (dp->d_zone == DB_Z_CACHE || !match(dp, class, ns_t_soa)) - continue; - if (dp->d_type == ns_t_sig) - continue; - if (mname) { - ns_notice(ns_log_notify, - "multiple SOA's for zone \"%s\"?", - zname); - return; - } - mname = (char *) dp->d_data; - } - if (mname == NULL) { - ns_notice(ns_log_notify, "no SOA found for zone \"%s\"", - zname); - return; - } - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (dp->d_zone == DB_Z_CACHE || !match(dp, class, ns_t_ns)) - continue; - if (dp->d_type == ns_t_sig) - continue; - if (ns_samename((char*)dp->d_data, mname) == 1) - continue; - sysnotify_ns(dname, (char *)dp->d_data, class, type, - zn, nns, na); - } -} - -static void -sysnotify_ns(const char *dname, const char *aname, - ns_class class, ns_type type, - int zn, int *nns, int *na) -{ - struct databuf *adp; - struct namebuf *anp; - const char *fname; - struct in_addr nss[NSMAX]; - struct hashbuf *htp; - int is_us, nsc; - - htp = hashtab; - anp = nlookup(aname, &htp, &fname, 0); - nsc = 0; - is_us = 0; - if (anp != NULL) - for (adp = anp->n_data; adp; adp = adp->d_next) { - struct in_addr ina; - - if (!match(adp, class, T_A)) - continue; - if (adp->d_type == ns_t_sig) - continue; - ina = ina_get(adp->d_data); - if (aIsUs(ina)) { - is_us = 1; - continue; - } - if (nsc < NSMAX) - nss[nsc++] = ina; - } /*next A*/ - if (nsc == 0) { - if (!is_us && !NS_OPTION_P(OPTION_NOFETCHGLUE)) { - struct qinfo *qp; - - qp = sysquery(aname, class, ns_t_a, 0, 0, ns_port, - ns_o_query); - if (qp != NULL) - qp->q_notifyzone = zn; - } - return; - } - sysquery(dname, class, type, nss, nsc, ns_port, ns_o_notify); - (*nns)++; - *na += nsc; -} - -static void -free_notify(struct notify *ni) { - struct zoneinfo *zp; - - INSIST(!LINKED(ni, link)); - zp = find_auth_zone(ni->name, ni->class); - if (zp != NULL && ns_samename(ni->name, zp->z_origin) == 1) { - INSIST((zp->z_flags & Z_NOTIFY) != 0); - zp->z_flags &= ~Z_NOTIFY; - } - if (evTestID(ni->timer)) { - evClearTimer(ev, ni->timer); - evInitID(&ni->timer); - } - freestr(ni->name); - memput(ni, sizeof *ni); -} - -static void -notify_timer(evContext ctx, void *uap, - struct timespec due, - struct timespec inter) -{ - struct notify *ni = uap; - - INSIST(evTestID(ni->timer)); - evInitID(&ni->timer); - INSIST(LINKED(ni, link)); - UNLINK(pending_notifies, ni, link); - sysnotify(ni->name, ni->class, ni->type); - free_notify(ni); -} - -#endif /*BIND_NOTIFY*/ diff --git a/contrib/bind/bin/named/ns_parser.c b/contrib/bind/bin/named/ns_parser.c deleted file mode 100644 index 03d0a84d7cbaa..0000000000000 --- a/contrib/bind/bin/named/ns_parser.c +++ /dev/null @@ -1,3150 +0,0 @@ -#ifndef lint -static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93 (BSDI)"; -#endif -#include <stdlib.h> -#define YYBYACC 1 -#define YYMAJOR 1 -#define YYMINOR 9 -#define YYEMPTY (-1) -#define YYLEX yylex() -#define yyclearin (yychar=YYEMPTY) -#define yyerrok (yyerrflag=0) -#define YYRECOVERING (yyerrflag!=0) -#define YYPREFIX "yy" -#line 2 "ns_parser.y" -#if !defined(lint) && !defined(SABER) -static char rcsid[] = "$Id: ns_parser.y,v 8.51 1999/11/12 05:29:18 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* Global C stuff goes here. */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <limits.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" -#include "ns_parseutil.h" -#include "ns_lexer.h" - -#define SYM_ZONE 0x010000 -#define SYM_SERVER 0x020000 -#define SYM_KEY 0x030000 -#define SYM_ACL 0x040000 -#define SYM_CHANNEL 0x050000 -#define SYM_PORT 0x060000 - -#define SYMBOL_TABLE_SIZE 29989 /* should always be prime */ -static symbol_table symtab; - -#define AUTH_TABLE_SIZE 397 /* should always be prime */ -static symbol_table authtab = NULL; - -static zone_config current_zone; -static int should_install; - -static options current_options; -static int seen_options; - -static controls current_controls; - -static topology_config current_topology; -static int seen_topology; - -static server_config current_server; -static int seen_server; - -static char *current_algorithm; -static char *current_secret; - -static log_config current_logging; -static int current_category; -static int chan_type; -static int chan_level; -static u_int chan_flags; -static int chan_facility; -static char *chan_name; -static int chan_versions; -static u_long chan_max_size; - -static log_channel lookup_channel(char *); -static void define_channel(char *, log_channel); -static char *canonical_name(char *); - -int yyparse(); - -#line 103 "ns_parser.y" -typedef union { - char * cp; - int s_int; - long num; - u_long ul_int; - u_int16_t us_int; - struct in_addr ip_addr; - ip_match_element ime; - ip_match_list iml; - rrset_order_list rol; - rrset_order_element roe; - struct dst_key * keyi; - enum axfr_format axfr_fmt; -} YYSTYPE; -#line 130 "y.tab.c" -#define L_EOS 257 -#define L_IPADDR 258 -#define L_NUMBER 259 -#define L_STRING 260 -#define L_QSTRING 261 -#define L_END_INCLUDE 262 -#define T_INCLUDE 263 -#define T_OPTIONS 264 -#define T_DIRECTORY 265 -#define T_PIDFILE 266 -#define T_NAMED_XFER 267 -#define T_DUMP_FILE 268 -#define T_STATS_FILE 269 -#define T_MEMSTATS_FILE 270 -#define T_FAKE_IQUERY 271 -#define T_RECURSION 272 -#define T_FETCH_GLUE 273 -#define T_QUERY_SOURCE 274 -#define T_LISTEN_ON 275 -#define T_PORT 276 -#define T_ADDRESS 277 -#define T_RRSET_ORDER 278 -#define T_ORDER 279 -#define T_NAME 280 -#define T_CLASS 281 -#define T_CONTROLS 282 -#define T_INET 283 -#define T_UNIX 284 -#define T_PERM 285 -#define T_OWNER 286 -#define T_GROUP 287 -#define T_ALLOW 288 -#define T_DATASIZE 289 -#define T_STACKSIZE 290 -#define T_CORESIZE 291 -#define T_DEFAULT 292 -#define T_UNLIMITED 293 -#define T_FILES 294 -#define T_VERSION 295 -#define T_HOSTSTATS 296 -#define T_DEALLOC_ON_EXIT 297 -#define T_TRANSFERS_IN 298 -#define T_TRANSFERS_OUT 299 -#define T_TRANSFERS_PER_NS 300 -#define T_TRANSFER_FORMAT 301 -#define T_MAX_TRANSFER_TIME_IN 302 -#define T_SERIAL_QUERIES 303 -#define T_ONE_ANSWER 304 -#define T_MANY_ANSWERS 305 -#define T_NOTIFY 306 -#define T_AUTH_NXDOMAIN 307 -#define T_MULTIPLE_CNAMES 308 -#define T_USE_IXFR 309 -#define T_MAINTAIN_IXFR_BASE 310 -#define T_CLEAN_INTERVAL 311 -#define T_INTERFACE_INTERVAL 312 -#define T_STATS_INTERVAL 313 -#define T_MAX_LOG_SIZE_IXFR 314 -#define T_HEARTBEAT 315 -#define T_USE_ID_POOL 316 -#define T_MAX_NCACHE_TTL 317 -#define T_HAS_OLD_CLIENTS 318 -#define T_RFC2308_TYPE1 319 -#define T_LAME_TTL 320 -#define T_MIN_ROOTS 321 -#define T_TREAT_CR_AS_SPACE 322 -#define T_LOGGING 323 -#define T_CATEGORY 324 -#define T_CHANNEL 325 -#define T_SEVERITY 326 -#define T_DYNAMIC 327 -#define T_FILE 328 -#define T_VERSIONS 329 -#define T_SIZE 330 -#define T_SYSLOG 331 -#define T_DEBUG 332 -#define T_NULL_OUTPUT 333 -#define T_PRINT_TIME 334 -#define T_PRINT_CATEGORY 335 -#define T_PRINT_SEVERITY 336 -#define T_SORTLIST 337 -#define T_TOPOLOGY 338 -#define T_SERVER 339 -#define T_LONG_AXFR 340 -#define T_BOGUS 341 -#define T_TRANSFERS 342 -#define T_KEYS 343 -#define T_SUPPORT_IXFR 344 -#define T_ZONE 345 -#define T_IN 346 -#define T_CHAOS 347 -#define T_HESIOD 348 -#define T_TYPE 349 -#define T_MASTER 350 -#define T_SLAVE 351 -#define T_STUB 352 -#define T_RESPONSE 353 -#define T_HINT 354 -#define T_MASTERS 355 -#define T_TRANSFER_SOURCE 356 -#define T_PUBKEY 357 -#define T_ALSO_NOTIFY 358 -#define T_DIALUP 359 -#define T_FILE_IXFR 360 -#define T_IXFR_TMP 361 -#define T_TRUSTED_KEYS 362 -#define T_ACL 363 -#define T_ALLOW_UPDATE 364 -#define T_ALLOW_QUERY 365 -#define T_ALLOW_TRANSFER 366 -#define T_ALLOW_RECURSION 367 -#define T_BLACKHOLE 368 -#define T_SEC_KEY 369 -#define T_ALGID 370 -#define T_SECRET 371 -#define T_CHECK_NAMES 372 -#define T_WARN 373 -#define T_FAIL 374 -#define T_IGNORE 375 -#define T_FORWARD 376 -#define T_FORWARDERS 377 -#define T_ONLY 378 -#define T_FIRST 379 -#define T_IF_NO_ANSWER 380 -#define T_IF_NO_DOMAIN 381 -#define T_YES 382 -#define T_TRUE 383 -#define T_NO 384 -#define T_FALSE 385 -#define YYERRCODE 256 -short yylhs[] = { -1, - 0, 31, 31, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 33, 42, 34, 43, 43, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 46, 44, 44, 44, 44, 44, - 44, 44, 49, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 35, 53, 53, 54, 54, 54, 54, - 15, 15, 12, 12, 13, 13, 14, 14, 16, 6, - 6, 5, 5, 4, 4, 55, 56, 48, 48, 48, - 48, 2, 2, 3, 3, 29, 29, 29, 29, 29, - 27, 27, 27, 28, 28, 28, 45, 45, 45, 45, - 51, 51, 51, 51, 26, 26, 26, 26, 52, 52, - 52, 47, 47, 57, 57, 58, 50, 50, 59, 59, - 60, 61, 36, 62, 62, 62, 64, 63, 66, 63, - 68, 68, 68, 68, 69, 69, 70, 71, 71, 71, - 71, 71, 72, 10, 10, 11, 11, 73, 74, 74, - 74, 74, 74, 74, 74, 67, 67, 67, 9, 9, - 75, 65, 65, 65, 8, 8, 8, 7, 76, 37, - 77, 77, 78, 78, 78, 78, 78, 78, 20, 20, - 18, 18, 18, 17, 17, 17, 17, 17, 19, 23, - 80, 79, 79, 79, 81, 41, 82, 82, 82, 24, - 25, 40, 84, 38, 83, 83, 21, 21, 22, 22, - 22, 22, 22, 85, 85, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 89, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 87, 87, 92, - 91, 91, 93, 93, 94, 88, 88, 90, 90, 95, - 95, 96, 39, 97, 97, 98, 98, 1, 30, 30, -}; -short yylen[] = { 2, - 1, 1, 2, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 1, 2, 2, 3, 0, 5, 2, 3, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, - 2, 2, 5, 2, 0, 5, 2, 2, 4, 4, - 4, 4, 0, 5, 4, 4, 1, 1, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, - 2, 2, 1, 4, 2, 3, 0, 8, 8, 1, - 2, 3, 0, 2, 0, 2, 0, 2, 5, 1, - 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, - 2, 0, 2, 0, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, - 2, 0, 1, 2, 3, 1, 0, 1, 2, 3, - 1, 0, 5, 2, 3, 1, 0, 6, 0, 6, - 1, 1, 2, 1, 2, 2, 2, 0, 1, 1, - 2, 2, 3, 1, 1, 0, 1, 2, 1, 1, - 1, 2, 2, 2, 2, 2, 3, 1, 1, 1, - 1, 2, 3, 1, 1, 1, 1, 1, 0, 6, - 2, 3, 2, 2, 2, 2, 4, 1, 2, 3, - 1, 2, 2, 1, 3, 3, 1, 3, 1, 1, - 1, 2, 3, 1, 0, 6, 2, 2, 1, 3, - 3, 5, 0, 5, 0, 3, 0, 1, 1, 1, - 1, 1, 1, 2, 3, 2, 2, 2, 2, 5, - 2, 2, 4, 4, 4, 2, 0, 5, 2, 2, - 2, 2, 5, 5, 4, 2, 1, 2, 3, 1, - 0, 1, 2, 3, 1, 1, 1, 0, 1, 2, - 3, 1, 4, 2, 3, 5, 5, 1, 1, 1, -}; -short yydefred[] = { 0, - 0, 13, 0, 17, 0, 142, 0, 0, 0, 0, - 215, 0, 0, 2, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 14, 15, 0, 0, 0, 0, 189, - 0, 0, 279, 280, 0, 0, 3, 5, 6, 7, - 8, 9, 10, 11, 12, 16, 0, 80, 0, 0, - 0, 0, 0, 0, 223, 228, 0, 0, 0, 0, - 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, - 0, 0, 0, 0, 0, 45, 0, 0, 57, 58, - 92, 93, 0, 0, 74, 0, 75, 146, 0, 0, - 0, 0, 0, 0, 0, 0, 273, 0, 274, 0, - 0, 0, 0, 0, 201, 0, 207, 0, 209, 0, - 23, 25, 24, 28, 26, 27, 110, 106, 107, 108, - 109, 29, 30, 31, 0, 0, 47, 0, 0, 0, - 0, 0, 126, 127, 128, 121, 125, 122, 123, 124, - 22, 33, 34, 129, 130, 131, 90, 91, 59, 60, - 61, 32, 38, 39, 35, 36, 62, 63, 64, 65, - 68, 41, 66, 37, 42, 67, 72, 71, 0, 0, - 48, 0, 69, 0, 0, 0, 0, 111, 112, 113, - 0, 117, 118, 119, 120, 44, 0, 18, 0, 19, - 0, 0, 76, 186, 187, 147, 188, 185, 180, 149, - 179, 143, 0, 144, 198, 0, 0, 0, 0, 0, - 0, 0, 0, 224, 0, 0, 275, 0, 0, 203, - 0, 202, 199, 222, 0, 219, 0, 0, 0, 0, - 0, 278, 95, 94, 97, 96, 100, 101, 103, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 114, 115, 116, 40, 0, 20, 0, 0, 0, - 0, 145, 196, 193, 195, 0, 194, 190, 0, 191, - 257, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, - 0, 0, 0, 0, 205, 206, 208, 200, 0, 0, - 217, 218, 216, 0, 84, 0, 0, 70, 0, 81, - 52, 56, 141, 0, 0, 0, 49, 51, 50, 55, - 136, 0, 0, 0, 0, 0, 0, 0, 214, 211, - 210, 0, 0, 192, 249, 251, 252, 250, 237, 229, - 230, 232, 231, 233, 236, 0, 0, 241, 0, 0, - 0, 256, 238, 239, 0, 0, 0, 242, 266, 267, - 246, 0, 226, 0, 234, 276, 277, 220, 221, 43, - 86, 0, 0, 82, 54, 0, 139, 46, 0, 134, - 0, 0, 184, 181, 0, 0, 178, 0, 0, 0, - 171, 0, 0, 0, 0, 169, 170, 0, 197, 0, - 212, 105, 0, 0, 0, 265, 0, 0, 0, 0, - 0, 0, 0, 235, 88, 0, 140, 135, 0, 0, - 148, 0, 182, 154, 0, 151, 172, 0, 165, 167, - 168, 164, 173, 174, 175, 150, 0, 176, 213, 260, - 0, 0, 0, 0, 255, 0, 263, 243, 244, 245, - 272, 0, 0, 0, 89, 78, 79, 183, 153, 0, - 0, 0, 0, 163, 177, 240, 0, 258, 253, 254, - 264, 248, 0, 270, 155, 156, 157, 161, 162, 259, - 271, -}; -short yydgoto[] = { 12, - 274, 171, 387, 275, 123, 189, 236, 237, 424, 470, - 471, 282, 347, 413, 283, 284, 145, 146, 147, 148, - 55, 385, 370, 269, 270, 176, 221, 295, 162, 149, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 27, 117, 118, 226, 227, 362, 167, 212, 354, - 119, 120, 51, 52, 168, 169, 363, 364, 355, 356, - 29, 131, 132, 300, 425, 301, 435, 467, 502, 503, - 504, 436, 437, 438, 426, 54, 251, 252, 372, 373, - 36, 271, 254, 134, 331, 332, 481, 401, 402, 492, - 447, 482, 448, 449, 493, 494, 58, 59, -}; -short yysindex[] = { 419, - -172, 0, -236, 0, -91, 0, -224, -211, -71, -178, - 0, 0, 419, 0, 0, -166, -160, -158, -156, -154, - -144, -139, -128, 0, 0, -126, -49, -195, 10, 0, - -178, -198, 0, 0, 12, -178, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 349, 0, -7, -123, - -112, -115, -238, 23, 0, 0, -189, -110, -105, 43, - 31, 0, -98, -96, -94, -85, -76, -73, -190, -190, - -190, -86, -106, 33, -81, -81, -81, -81, -58, -190, - -190, -59, -50, -45, -121, -34, -32, -190, -190, -190, - -190, -190, 51, 56, 63, 64, 66, -190, 68, -190, - -190, 69, 71, -190, 123, 136, -7, 0, -190, 212, - 219, 220, 222, -258, -182, 0, 168, 89, 0, 0, - 0, 0, 73, 62, 0, 93, 0, 0, -181, -216, - -69, 94, -220, 230, 95, 96, 0, 99, 0, 312, - 313, 104, 43, -100, 0, 108, 0, -29, 0, -196, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -31, -7, 0, 100, 92, 111, - 254, 98, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 43, 43, - 0, 257, 0, 43, 43, 43, 43, 0, 0, 0, - -68, 0, 0, 0, 0, 0, 258, 0, 127, 0, - 111, 126, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 129, 0, 0, -121, -190, 130, 265, -190, - -120, 133, 374, 0, 134, 135, 0, 137, 138, 0, - -25, 0, 0, 0, 141, 0, -178, -178, 21, 32, - 275, 0, 0, 0, 0, 0, 0, 0, 0, 43, - -178, 52, -108, 146, -21, -17, 147, -11, 5, 9, - 14, 0, 0, 0, 0, 148, 0, 116, 121, 286, - 287, 0, 0, 0, 0, -151, 0, 0, 154, 0, - 0, 155, -190, -190, 157, 152, -13, 143, -7, 35, - 294, -190, 160, 161, 300, 302, 304, -68, -70, 0, - 236, 171, 169, 170, 0, 0, 0, 0, 172, 175, - 0, 0, 0, 18, 0, -178, 164, 0, 188, 0, - 0, 0, 0, 322, 147, 191, 0, 0, 0, 0, - 0, 324, 148, 193, 328, 194, -207, -2, 0, 0, - 0, -92, 195, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 111, 331, 0, 196, 197, - 202, 0, 0, 0, 43, 43, 43, 0, 0, 0, - 0, 338, 0, 215, 0, 0, 0, 0, 0, 0, - 0, 232, 216, 0, 0, 237, 0, 0, 239, 0, - 43, 186, 0, 0, -41, 243, 0, -145, 240, -183, - 0, -190, -190, -190, -118, 0, 0, 245, 0, 246, - 0, 0, 249, 250, 251, 0, 379, 202, 255, 22, - 26, 30, 253, 0, 0, 248, 0, 0, 39, 256, - 0, 259, 0, 0, 260, 0, 0, -16, 0, 0, - 0, 0, 0, 0, 0, 0, 261, 0, 0, 0, - -101, 263, 252, 264, 0, 271, 0, 0, 0, 0, - 0, 389, 253, 272, 0, 0, 0, 0, 0, -218, - -81, 187, 192, 0, 0, 0, 273, 0, 0, 0, - 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, - 0, -}; -short yyrindex[] = { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 522, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 280, 0, 0, - -117, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, - 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 409, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 284, 0, 0, 0, 0, 0, 290, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 291, 292, 0, - 0, -222, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 41, -222, 0, 0, 0, 418, 0, 0, 0, - 0, 0, 0, 0, 0, 426, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 429, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, - 0, 0, 431, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 433, 0, 0, - 0, 0, 434, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 303, 0, 0, 305, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 436, 0, 0, 0, 0, 0, 0, 0, - 0, 306, 308, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -}; -short yygindex[] = { 0, - -124, 0, 0, 0, -93, 320, 0, 0, 437, 0, - 0, 0, 0, 0, 0, 285, 425, -84, 0, 102, - 0, 0, 0, 301, 307, -75, 0, 242, -61, -10, - 0, 559, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 456, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 523, 406, 410, 0, 214, 0, 224, - 0, 0, 449, 0, 0, 0, 0, 0, 78, 80, - 0, 0, 0, 149, 158, 0, 0, 335, 0, 217, - 0, 0, 0, 0, 0, 267, 0, 0, 0, 0, - 0, 106, 0, 140, 0, 97, 0, 541, -}; -#define YYTABLESIZE 788 -short yytable[] = { 35, - 178, 179, 180, 144, 308, 227, 476, 144, 163, 164, - 273, 144, 125, 211, 137, 144, 348, 128, 182, 183, - 56, 144, 143, 506, 26, 61, 192, 193, 194, 195, - 196, 28, 439, 30, 122, 245, 202, 144, 204, 205, - 515, 144, 208, 33, 34, 279, 144, 213, 423, 31, - 144, 32, 33, 34, 144, 242, 83, 83, 144, 266, - 48, 57, 144, 265, 177, 177, 177, 177, 157, 135, - 136, 144, 276, 47, 516, 144, 33, 34, 33, 34, - 246, 33, 34, 461, 24, 129, 130, 49, 50, 25, - 38, 218, 219, 143, 220, 264, 39, 143, 40, 337, - 41, 143, 42, 351, 369, 143, 298, 352, 33, 34, - 234, 143, 43, 357, 33, 34, 239, 44, 238, 241, - 247, 248, 249, 250, 235, 239, 83, 143, 45, 358, - 46, 143, 53, 359, 60, 245, 143, 124, 360, 227, - 143, 127, 410, 48, 143, 133, 488, 469, 143, 57, - 489, 139, 143, 150, 490, 172, 480, 140, 141, 33, - 34, 143, 151, 496, 152, 143, 153, 33, 34, 170, - 49, 50, 281, 267, 268, 154, 265, 173, 33, 34, - 246, 464, 187, 188, 155, 304, 465, 156, 307, 165, - 166, 158, 159, 160, 161, 222, 223, 224, 225, 184, - 265, 265, 181, 265, 265, 265, 265, 428, 185, 429, - 174, 175, 430, 186, 431, 432, 433, 434, 33, 34, - 247, 248, 249, 250, 190, 388, 191, 272, 140, 141, - 33, 34, 140, 141, 33, 34, 140, 141, 33, 34, - 140, 141, 33, 34, 261, 209, 140, 141, 33, 34, - 121, 376, 377, 427, 129, 130, 339, 340, 210, 265, - 392, 442, 140, 141, 33, 34, 140, 141, 33, 34, - 345, 140, 141, 33, 34, 140, 141, 33, 34, 140, - 141, 33, 34, 140, 141, 33, 34, 140, 141, 33, - 34, 239, 228, 389, 390, 371, 140, 141, 33, 34, - 140, 141, 33, 34, 292, 293, 294, 399, 400, 197, - 285, 286, 500, 501, 198, 288, 289, 290, 291, 85, - 85, 199, 200, 428, 201, 429, 203, 206, 430, 207, - 431, 432, 433, 434, 214, 411, 380, 381, 382, 142, - 383, 215, 216, 142, 217, 230, 232, 142, 231, 233, - 244, 142, 253, 255, 256, 257, 241, 142, 258, 259, - 403, 371, 384, 260, 263, 265, 265, 265, 166, 272, - 473, 474, 475, 142, 265, 165, 280, 142, 281, 287, - 296, 344, 142, 297, 299, 302, 142, 306, 305, 310, - 142, 268, 333, 334, 142, 335, 336, 338, 142, 343, - 346, 267, 350, 365, 353, 361, 366, 142, 367, 368, - 374, 142, 379, 375, 241, 378, 391, 466, 386, 472, - 393, 394, 395, 62, 396, 517, 397, 405, 408, 406, - 407, 409, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 412, 414, 74, 415, 417, 418, 420, - 421, 441, 422, 443, 444, 445, 75, 76, 77, 446, - 453, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 454, 460, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 177, 311, 455, 457, 456, 458, 450, 451, 452, 463, - 468, 478, 479, 485, 105, 106, 480, 495, 483, 484, - 491, 487, 509, 512, 497, 498, 501, 505, 499, 508, - 500, 1, 459, 107, 510, 108, 109, 511, 514, 520, - 521, 102, 110, 111, 112, 113, 77, 312, 21, 114, - 225, 313, 137, 115, 116, 314, 204, 98, 99, 315, - 132, 104, 138, 166, 87, 133, 261, 262, 268, 152, - 269, 158, 159, 316, 160, 303, 240, 349, 262, 398, - 342, 37, 229, 126, 278, 341, 419, 277, 416, 243, - 519, 518, 462, 477, 317, 309, 507, 486, 440, 513, - 318, 319, 320, 321, 322, 323, 324, 404, 138, 325, - 326, 327, 0, 0, 62, 0, 0, 328, 0, 0, - 0, 329, 330, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 0, 0, 74, 0, 0, 311, - 0, 0, 0, 0, 0, 0, 0, 75, 76, 77, - 0, 0, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 0, 0, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 0, 0, 0, 1, 312, 0, 0, 0, 313, - 2, 3, 4, 314, 0, 105, 106, 315, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 316, 0, 0, 107, 0, 108, 109, 0, 0, - 0, 0, 0, 110, 111, 112, 113, 0, 0, 0, - 114, 0, 317, 0, 115, 116, 0, 0, 318, 319, - 320, 321, 322, 323, 324, 0, 0, 325, 326, 327, - 0, 6, 0, 0, 0, 328, 0, 0, 0, 329, - 330, 0, 0, 0, 0, 0, 0, 7, 0, 0, - 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 10, 0, 0, 0, 0, 0, 11, -}; -short yycheck[] = { 10, - 76, 77, 78, 33, 125, 123, 125, 33, 70, 71, - 42, 33, 125, 107, 125, 33, 125, 256, 80, 81, - 31, 33, 123, 125, 261, 36, 88, 89, 90, 91, - 92, 123, 125, 258, 42, 256, 98, 33, 100, 101, - 259, 33, 104, 260, 261, 170, 33, 109, 256, 261, - 33, 123, 260, 261, 33, 125, 279, 280, 33, 256, - 256, 260, 33, 148, 75, 76, 77, 78, 259, 259, - 260, 33, 166, 123, 293, 33, 260, 261, 260, 261, - 301, 260, 261, 125, 257, 324, 325, 283, 284, 262, - 257, 350, 351, 123, 353, 125, 257, 123, 257, 125, - 257, 123, 257, 125, 256, 123, 231, 125, 260, 261, - 292, 123, 257, 125, 260, 261, 333, 257, 129, 130, - 341, 342, 343, 344, 306, 333, 349, 123, 257, 125, - 257, 123, 123, 125, 123, 256, 123, 261, 125, 257, - 123, 257, 125, 256, 123, 123, 125, 331, 123, 260, - 125, 257, 123, 123, 125, 123, 258, 258, 259, 260, - 261, 123, 261, 125, 261, 123, 261, 260, 261, 276, - 283, 284, 281, 370, 371, 261, 261, 259, 260, 261, - 301, 327, 304, 305, 261, 247, 332, 261, 250, 276, - 277, 382, 383, 384, 385, 378, 379, 380, 381, 259, - 285, 286, 261, 288, 289, 290, 291, 326, 259, 328, - 292, 293, 331, 259, 333, 334, 335, 336, 260, 261, - 341, 342, 343, 344, 259, 319, 259, 259, 258, 259, - 260, 261, 258, 259, 260, 261, 258, 259, 260, 261, - 258, 259, 260, 261, 143, 123, 258, 259, 260, 261, - 258, 313, 314, 256, 324, 325, 267, 268, 123, 344, - 322, 386, 258, 259, 260, 261, 258, 259, 260, 261, - 281, 258, 259, 260, 261, 258, 259, 260, 261, 258, - 259, 260, 261, 258, 259, 260, 261, 258, 259, 260, - 261, 333, 125, 259, 260, 306, 258, 259, 260, 261, - 258, 259, 260, 261, 373, 374, 375, 378, 379, 259, - 209, 210, 329, 330, 259, 214, 215, 216, 217, 279, - 280, 259, 259, 326, 259, 328, 259, 259, 331, 259, - 333, 334, 335, 336, 123, 346, 350, 351, 352, 369, - 354, 123, 123, 369, 123, 257, 285, 369, 276, 257, - 257, 369, 123, 259, 259, 257, 367, 369, 47, 47, - 125, 372, 376, 260, 257, 450, 451, 452, 277, 259, - 432, 433, 434, 369, 459, 276, 123, 369, 281, 123, - 123, 280, 369, 257, 259, 257, 369, 123, 259, 257, - 369, 371, 259, 259, 369, 259, 259, 257, 369, 125, - 349, 370, 257, 288, 258, 258, 286, 369, 123, 123, - 257, 369, 261, 259, 425, 259, 123, 428, 276, 430, - 261, 261, 123, 256, 123, 501, 123, 257, 257, 261, - 261, 257, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 280, 257, 278, 125, 257, 125, 257, - 123, 257, 259, 123, 259, 259, 289, 290, 291, 258, - 123, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 257, 287, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 501, 256, 261, 257, 279, 257, 395, 396, 397, 257, - 261, 257, 257, 125, 337, 338, 258, 260, 259, 259, - 258, 257, 261, 125, 259, 257, 330, 257, 259, 257, - 329, 0, 421, 356, 261, 358, 359, 257, 257, 257, - 257, 123, 365, 366, 367, 368, 257, 302, 257, 372, - 257, 306, 125, 376, 377, 310, 257, 257, 257, 314, - 125, 123, 125, 257, 279, 125, 125, 125, 125, 257, - 125, 257, 257, 328, 257, 246, 130, 283, 144, 328, - 270, 13, 117, 51, 169, 269, 363, 168, 355, 131, - 503, 502, 425, 435, 349, 251, 481, 448, 372, 493, - 355, 356, 357, 358, 359, 360, 361, 331, 58, 364, - 365, 366, -1, -1, 256, -1, -1, 372, -1, -1, - -1, 376, 377, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, -1, -1, 278, -1, -1, 256, - -1, -1, -1, -1, -1, -1, -1, 289, 290, 291, - -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, - 302, 303, -1, -1, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, -1, -1, -1, 256, 302, -1, -1, -1, 306, - 262, 263, 264, 310, -1, 337, 338, 314, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 282, 328, -1, -1, 356, -1, 358, 359, -1, -1, - -1, -1, -1, 365, 366, 367, 368, -1, -1, -1, - 372, -1, 349, -1, 376, 377, -1, -1, 355, 356, - 357, 358, 359, 360, 361, -1, -1, 364, 365, 366, - -1, 323, -1, -1, -1, 372, -1, -1, -1, 376, - 377, -1, -1, -1, -1, -1, -1, 339, -1, -1, - -1, -1, -1, 345, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 362, 363, -1, -1, -1, -1, -1, 369, -}; -#define YYFINAL 12 -#ifndef YYDEBUG -#define YYDEBUG 0 -#endif -#define YYMAXTOKEN 385 -#if YYDEBUG -char *yyname[] = { -"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -"'!'",0,0,0,0,0,0,0,0,"'*'",0,0,0,0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"L_EOS", -"L_IPADDR","L_NUMBER","L_STRING","L_QSTRING","L_END_INCLUDE","T_INCLUDE", -"T_OPTIONS","T_DIRECTORY","T_PIDFILE","T_NAMED_XFER","T_DUMP_FILE", -"T_STATS_FILE","T_MEMSTATS_FILE","T_FAKE_IQUERY","T_RECURSION","T_FETCH_GLUE", -"T_QUERY_SOURCE","T_LISTEN_ON","T_PORT","T_ADDRESS","T_RRSET_ORDER","T_ORDER", -"T_NAME","T_CLASS","T_CONTROLS","T_INET","T_UNIX","T_PERM","T_OWNER","T_GROUP", -"T_ALLOW","T_DATASIZE","T_STACKSIZE","T_CORESIZE","T_DEFAULT","T_UNLIMITED", -"T_FILES","T_VERSION","T_HOSTSTATS","T_DEALLOC_ON_EXIT","T_TRANSFERS_IN", -"T_TRANSFERS_OUT","T_TRANSFERS_PER_NS","T_TRANSFER_FORMAT", -"T_MAX_TRANSFER_TIME_IN","T_SERIAL_QUERIES","T_ONE_ANSWER","T_MANY_ANSWERS", -"T_NOTIFY","T_AUTH_NXDOMAIN","T_MULTIPLE_CNAMES","T_USE_IXFR", -"T_MAINTAIN_IXFR_BASE","T_CLEAN_INTERVAL","T_INTERFACE_INTERVAL", -"T_STATS_INTERVAL","T_MAX_LOG_SIZE_IXFR","T_HEARTBEAT","T_USE_ID_POOL", -"T_MAX_NCACHE_TTL","T_HAS_OLD_CLIENTS","T_RFC2308_TYPE1","T_LAME_TTL", -"T_MIN_ROOTS","T_TREAT_CR_AS_SPACE","T_LOGGING","T_CATEGORY","T_CHANNEL", -"T_SEVERITY","T_DYNAMIC","T_FILE","T_VERSIONS","T_SIZE","T_SYSLOG","T_DEBUG", -"T_NULL_OUTPUT","T_PRINT_TIME","T_PRINT_CATEGORY","T_PRINT_SEVERITY", -"T_SORTLIST","T_TOPOLOGY","T_SERVER","T_LONG_AXFR","T_BOGUS","T_TRANSFERS", -"T_KEYS","T_SUPPORT_IXFR","T_ZONE","T_IN","T_CHAOS","T_HESIOD","T_TYPE", -"T_MASTER","T_SLAVE","T_STUB","T_RESPONSE","T_HINT","T_MASTERS", -"T_TRANSFER_SOURCE","T_PUBKEY","T_ALSO_NOTIFY","T_DIALUP","T_FILE_IXFR", -"T_IXFR_TMP","T_TRUSTED_KEYS","T_ACL","T_ALLOW_UPDATE","T_ALLOW_QUERY", -"T_ALLOW_TRANSFER","T_ALLOW_RECURSION","T_BLACKHOLE","T_SEC_KEY","T_ALGID", -"T_SECRET","T_CHECK_NAMES","T_WARN","T_FAIL","T_IGNORE","T_FORWARD", -"T_FORWARDERS","T_ONLY","T_FIRST","T_IF_NO_ANSWER","T_IF_NO_DOMAIN","T_YES", -"T_TRUE","T_NO","T_FALSE", -}; -char *yyrule[] = { -"$accept : config_file", -"config_file : statement_list", -"statement_list : statement", -"statement_list : statement_list statement", -"statement : include_stmt", -"statement : options_stmt L_EOS", -"statement : controls_stmt L_EOS", -"statement : logging_stmt L_EOS", -"statement : server_stmt L_EOS", -"statement : zone_stmt L_EOS", -"statement : trusted_keys_stmt L_EOS", -"statement : acl_stmt L_EOS", -"statement : key_stmt L_EOS", -"statement : L_END_INCLUDE", -"statement : error L_EOS", -"statement : error L_END_INCLUDE", -"include_stmt : T_INCLUDE L_QSTRING L_EOS", -"$$1 :", -"options_stmt : T_OPTIONS $$1 '{' options '}'", -"options : option L_EOS", -"options : options option L_EOS", -"option :", -"option : T_VERSION L_QSTRING", -"option : T_DIRECTORY L_QSTRING", -"option : T_NAMED_XFER L_QSTRING", -"option : T_PIDFILE L_QSTRING", -"option : T_STATS_FILE L_QSTRING", -"option : T_MEMSTATS_FILE L_QSTRING", -"option : T_DUMP_FILE L_QSTRING", -"option : T_FAKE_IQUERY yea_or_nay", -"option : T_RECURSION yea_or_nay", -"option : T_FETCH_GLUE yea_or_nay", -"option : T_NOTIFY yea_or_nay", -"option : T_HOSTSTATS yea_or_nay", -"option : T_DEALLOC_ON_EXIT yea_or_nay", -"option : T_USE_IXFR yea_or_nay", -"option : T_MAINTAIN_IXFR_BASE yea_or_nay", -"option : T_HAS_OLD_CLIENTS yea_or_nay", -"option : T_AUTH_NXDOMAIN yea_or_nay", -"option : T_MULTIPLE_CNAMES yea_or_nay", -"option : T_CHECK_NAMES check_names_type check_names_opt", -"option : T_USE_ID_POOL yea_or_nay", -"option : T_RFC2308_TYPE1 yea_or_nay", -"option : T_LISTEN_ON maybe_port '{' address_match_list '}'", -"option : T_FORWARD forward_opt", -"$$2 :", -"option : T_FORWARDERS $$2 '{' opt_forwarders_list '}'", -"option : T_QUERY_SOURCE query_source", -"option : T_TRANSFER_SOURCE maybe_wild_addr", -"option : T_ALLOW_QUERY '{' address_match_list '}'", -"option : T_ALLOW_RECURSION '{' address_match_list '}'", -"option : T_ALLOW_TRANSFER '{' address_match_list '}'", -"option : T_SORTLIST '{' address_match_list '}'", -"$$3 :", -"option : T_ALSO_NOTIFY $$3 '{' opt_also_notify_list '}'", -"option : T_BLACKHOLE '{' address_match_list '}'", -"option : T_TOPOLOGY '{' address_match_list '}'", -"option : size_clause", -"option : transfer_clause", -"option : T_TRANSFER_FORMAT transfer_format", -"option : T_MAX_TRANSFER_TIME_IN L_NUMBER", -"option : T_SERIAL_QUERIES L_NUMBER", -"option : T_CLEAN_INTERVAL L_NUMBER", -"option : T_INTERFACE_INTERVAL L_NUMBER", -"option : T_STATS_INTERVAL L_NUMBER", -"option : T_MAX_LOG_SIZE_IXFR L_NUMBER", -"option : T_MAX_NCACHE_TTL L_NUMBER", -"option : T_LAME_TTL L_NUMBER", -"option : T_HEARTBEAT L_NUMBER", -"option : T_DIALUP yea_or_nay", -"option : T_RRSET_ORDER '{' rrset_ordering_list '}'", -"option : T_TREAT_CR_AS_SPACE yea_or_nay", -"option : T_MIN_ROOTS L_NUMBER", -"option : error", -"controls_stmt : T_CONTROLS '{' controls '}'", -"controls : control L_EOS", -"controls : controls control L_EOS", -"control :", -"control : T_INET maybe_wild_addr T_PORT in_port T_ALLOW '{' address_match_list '}'", -"control : T_UNIX L_QSTRING T_PERM L_NUMBER T_OWNER L_NUMBER T_GROUP L_NUMBER", -"control : error", -"rrset_ordering_list : rrset_ordering_element L_EOS", -"rrset_ordering_list : rrset_ordering_list rrset_ordering_element L_EOS", -"ordering_class :", -"ordering_class : T_CLASS any_string", -"ordering_type :", -"ordering_type : T_TYPE any_string", -"ordering_name :", -"ordering_name : T_NAME L_QSTRING", -"rrset_ordering_element : ordering_class ordering_type ordering_name T_ORDER L_STRING", -"transfer_format : T_ONE_ANSWER", -"transfer_format : T_MANY_ANSWERS", -"maybe_wild_addr : L_IPADDR", -"maybe_wild_addr : '*'", -"maybe_wild_port : in_port", -"maybe_wild_port : '*'", -"query_source_address : T_ADDRESS maybe_wild_addr", -"query_source_port : T_PORT maybe_wild_port", -"query_source : query_source_address", -"query_source : query_source_port", -"query_source : query_source_address query_source_port", -"query_source : query_source_port query_source_address", -"maybe_port :", -"maybe_port : T_PORT in_port", -"maybe_zero_port :", -"maybe_zero_port : T_PORT in_port", -"yea_or_nay : T_YES", -"yea_or_nay : T_TRUE", -"yea_or_nay : T_NO", -"yea_or_nay : T_FALSE", -"yea_or_nay : L_NUMBER", -"check_names_type : T_MASTER", -"check_names_type : T_SLAVE", -"check_names_type : T_RESPONSE", -"check_names_opt : T_WARN", -"check_names_opt : T_FAIL", -"check_names_opt : T_IGNORE", -"forward_opt : T_ONLY", -"forward_opt : T_FIRST", -"forward_opt : T_IF_NO_ANSWER", -"forward_opt : T_IF_NO_DOMAIN", -"size_clause : T_DATASIZE size_spec", -"size_clause : T_STACKSIZE size_spec", -"size_clause : T_CORESIZE size_spec", -"size_clause : T_FILES size_spec", -"size_spec : any_string", -"size_spec : L_NUMBER", -"size_spec : T_DEFAULT", -"size_spec : T_UNLIMITED", -"transfer_clause : T_TRANSFERS_IN L_NUMBER", -"transfer_clause : T_TRANSFERS_OUT L_NUMBER", -"transfer_clause : T_TRANSFERS_PER_NS L_NUMBER", -"opt_forwarders_list :", -"opt_forwarders_list : forwarders_in_addr_list", -"forwarders_in_addr_list : forwarders_in_addr L_EOS", -"forwarders_in_addr_list : forwarders_in_addr_list forwarders_in_addr L_EOS", -"forwarders_in_addr : L_IPADDR", -"opt_also_notify_list :", -"opt_also_notify_list : also_notify_in_addr_list", -"also_notify_in_addr_list : also_notify_in_addr L_EOS", -"also_notify_in_addr_list : also_notify_in_addr_list also_notify_in_addr L_EOS", -"also_notify_in_addr : L_IPADDR", -"$$4 :", -"logging_stmt : T_LOGGING $$4 '{' logging_opts_list '}'", -"logging_opts_list : logging_opt L_EOS", -"logging_opts_list : logging_opts_list logging_opt L_EOS", -"logging_opts_list : error", -"$$5 :", -"logging_opt : T_CATEGORY category $$5 '{' channel_list '}'", -"$$6 :", -"logging_opt : T_CHANNEL channel_name $$6 '{' channel_opt_list '}'", -"channel_severity : any_string", -"channel_severity : T_DEBUG", -"channel_severity : T_DEBUG L_NUMBER", -"channel_severity : T_DYNAMIC", -"version_modifier : T_VERSIONS L_NUMBER", -"version_modifier : T_VERSIONS T_UNLIMITED", -"size_modifier : T_SIZE size_spec", -"maybe_file_modifiers :", -"maybe_file_modifiers : version_modifier", -"maybe_file_modifiers : size_modifier", -"maybe_file_modifiers : version_modifier size_modifier", -"maybe_file_modifiers : size_modifier version_modifier", -"channel_file : T_FILE L_QSTRING maybe_file_modifiers", -"facility_name : any_string", -"facility_name : T_SYSLOG", -"maybe_syslog_facility :", -"maybe_syslog_facility : facility_name", -"channel_syslog : T_SYSLOG maybe_syslog_facility", -"channel_opt : channel_file", -"channel_opt : channel_syslog", -"channel_opt : T_NULL_OUTPUT", -"channel_opt : T_SEVERITY channel_severity", -"channel_opt : T_PRINT_TIME yea_or_nay", -"channel_opt : T_PRINT_CATEGORY yea_or_nay", -"channel_opt : T_PRINT_SEVERITY yea_or_nay", -"channel_opt_list : channel_opt L_EOS", -"channel_opt_list : channel_opt_list channel_opt L_EOS", -"channel_opt_list : error", -"channel_name : any_string", -"channel_name : T_NULL_OUTPUT", -"channel : channel_name", -"channel_list : channel L_EOS", -"channel_list : channel_list channel L_EOS", -"channel_list : error", -"category_name : any_string", -"category_name : T_DEFAULT", -"category_name : T_NOTIFY", -"category : category_name", -"$$7 :", -"server_stmt : T_SERVER L_IPADDR $$7 '{' server_info_list '}'", -"server_info_list : server_info L_EOS", -"server_info_list : server_info_list server_info L_EOS", -"server_info : T_BOGUS yea_or_nay", -"server_info : T_SUPPORT_IXFR yea_or_nay", -"server_info : T_TRANSFERS L_NUMBER", -"server_info : T_TRANSFER_FORMAT transfer_format", -"server_info : T_KEYS '{' key_list '}'", -"server_info : error", -"address_match_list : address_match_element L_EOS", -"address_match_list : address_match_list address_match_element L_EOS", -"address_match_element : address_match_simple", -"address_match_element : '!' address_match_simple", -"address_match_element : T_SEC_KEY L_STRING", -"address_match_simple : L_IPADDR", -"address_match_simple : L_IPADDR '/' L_NUMBER", -"address_match_simple : L_NUMBER '/' L_NUMBER", -"address_match_simple : address_name", -"address_match_simple : '{' address_match_list '}'", -"address_name : any_string", -"key_ref : any_string", -"key_list_element : key_ref", -"key_list : key_list_element L_EOS", -"key_list : key_list key_list_element L_EOS", -"key_list : error", -"$$8 :", -"key_stmt : T_SEC_KEY $$8 any_string '{' key_definition '}'", -"key_definition : algorithm_id secret", -"key_definition : secret algorithm_id", -"key_definition : error", -"algorithm_id : T_ALGID any_string L_EOS", -"secret : T_SECRET any_string L_EOS", -"acl_stmt : T_ACL any_string '{' address_match_list '}'", -"$$9 :", -"zone_stmt : T_ZONE L_QSTRING optional_class $$9 optional_zone_options_list", -"optional_zone_options_list :", -"optional_zone_options_list : '{' zone_option_list '}'", -"optional_class :", -"optional_class : any_string", -"zone_type : T_MASTER", -"zone_type : T_SLAVE", -"zone_type : T_HINT", -"zone_type : T_STUB", -"zone_type : T_FORWARD", -"zone_option_list : zone_option L_EOS", -"zone_option_list : zone_option_list zone_option L_EOS", -"zone_option : T_TYPE zone_type", -"zone_option : T_FILE L_QSTRING", -"zone_option : T_FILE_IXFR L_QSTRING", -"zone_option : T_IXFR_TMP L_QSTRING", -"zone_option : T_MASTERS maybe_zero_port '{' master_in_addr_list '}'", -"zone_option : T_TRANSFER_SOURCE maybe_wild_addr", -"zone_option : T_CHECK_NAMES check_names_opt", -"zone_option : T_ALLOW_UPDATE '{' address_match_list '}'", -"zone_option : T_ALLOW_QUERY '{' address_match_list '}'", -"zone_option : T_ALLOW_TRANSFER '{' address_match_list '}'", -"zone_option : T_FORWARD zone_forward_opt", -"$$10 :", -"zone_option : T_FORWARDERS $$10 '{' opt_zone_forwarders_list '}'", -"zone_option : T_MAX_TRANSFER_TIME_IN L_NUMBER", -"zone_option : T_MAX_LOG_SIZE_IXFR L_NUMBER", -"zone_option : T_NOTIFY yea_or_nay", -"zone_option : T_MAINTAIN_IXFR_BASE yea_or_nay", -"zone_option : T_PUBKEY L_NUMBER L_NUMBER L_NUMBER L_QSTRING", -"zone_option : T_PUBKEY L_STRING L_NUMBER L_NUMBER L_QSTRING", -"zone_option : T_ALSO_NOTIFY '{' opt_notify_in_addr_list '}'", -"zone_option : T_DIALUP yea_or_nay", -"zone_option : error", -"master_in_addr_list : master_in_addr L_EOS", -"master_in_addr_list : master_in_addr_list master_in_addr L_EOS", -"master_in_addr : L_IPADDR", -"opt_notify_in_addr_list :", -"opt_notify_in_addr_list : notify_in_addr_list", -"notify_in_addr_list : notify_in_addr L_EOS", -"notify_in_addr_list : notify_in_addr_list notify_in_addr L_EOS", -"notify_in_addr : L_IPADDR", -"zone_forward_opt : T_ONLY", -"zone_forward_opt : T_FIRST", -"opt_zone_forwarders_list :", -"opt_zone_forwarders_list : zone_forwarders_in_addr_list", -"zone_forwarders_in_addr_list : zone_forwarders_in_addr L_EOS", -"zone_forwarders_in_addr_list : zone_forwarders_in_addr_list zone_forwarders_in_addr L_EOS", -"zone_forwarders_in_addr : L_IPADDR", -"trusted_keys_stmt : T_TRUSTED_KEYS '{' trusted_keys_list '}'", -"trusted_keys_list : trusted_key L_EOS", -"trusted_keys_list : trusted_keys_list trusted_key L_EOS", -"trusted_key : L_STRING L_NUMBER L_NUMBER L_NUMBER L_QSTRING", -"trusted_key : L_STRING L_STRING L_NUMBER L_NUMBER L_QSTRING", -"in_port : L_NUMBER", -"any_string : L_STRING", -"any_string : L_QSTRING", -}; -#endif -#ifdef YYSTACKSIZE -#undef YYMAXDEPTH -#define YYMAXDEPTH YYSTACKSIZE -#else -#ifdef YYMAXDEPTH -#define YYSTACKSIZE YYMAXDEPTH -#else -#define YYSTACKSIZE 10000 -#define YYMAXDEPTH 10000 -#endif -#endif -#define YYINITSTACKSIZE 200 -int yydebug; -int yynerrs; -struct yystack { - short *ssp; - YYSTYPE *vsp; - short *ss; - YYSTYPE *vs; - int stacksize; - short *sslim; -}; -int yychar; /* some people use this, so we copy it in & out */ -int yyerrflag; /* must be global for yyerrok & YYRECOVERING */ -YYSTYPE yylval; -#line 1776 "ns_parser.y" - -static char * -canonical_name(char *name) { - char canonical[MAXDNAME]; - - if (strlen(name) >= MAXDNAME) - return (NULL); - strcpy(canonical, name); - if (makename(canonical, ".", sizeof canonical) < 0) - return (NULL); - return (savestr(canonical, 0)); -} - -static void -init_acls() { - ip_match_element ime; - ip_match_list iml; - struct in_addr address; - - /* Create the predefined ACLs */ - - address.s_addr = 0U; - - /* ACL "any" */ - ime = new_ip_match_pattern(address, 0); - iml = new_ip_match_list(); - add_to_ip_match_list(iml, ime); - define_acl(savestr("any", 1), iml); - - /* ACL "none" */ - ime = new_ip_match_pattern(address, 0); - ip_match_negate(ime); - iml = new_ip_match_list(); - add_to_ip_match_list(iml, ime); - define_acl(savestr("none", 1), iml); - - /* ACL "localhost" */ - ime = new_ip_match_localhost(); - iml = new_ip_match_list(); - add_to_ip_match_list(iml, ime); - define_acl(savestr("localhost", 1), iml); - - /* ACL "localnets" */ - ime = new_ip_match_localnets(); - iml = new_ip_match_list(); - add_to_ip_match_list(iml, ime); - define_acl(savestr("localnets", 1), iml); -} - -static void -free_sym_value(int type, void *value) { - ns_debug(ns_log_parser, 99, "free_sym_value: type %06x value %p", - type, value); - type &= ~0xffff; - switch (type) { - case SYM_ACL: - free_ip_match_list(value); - break; - case SYM_KEY: - free_key_info(value); - break; - default: - ns_panic(ns_log_parser, 1, - "unhandled case in free_sym_value()"); - /* NOTREACHED */ - break; - } -} - -static log_channel -lookup_channel(char *name) { - symbol_value value; - - if (lookup_symbol(symtab, name, SYM_CHANNEL, &value)) - return ((log_channel)(value.pointer)); - return (NULL); -} - -static void -define_channel(char *name, log_channel channel) { - symbol_value value; - - value.pointer = channel; - define_symbol(symtab, name, SYM_CHANNEL, value, SYMBOL_FREE_KEY); -} - -static void -define_builtin_channels() { - define_channel(savestr("default_syslog", 1), syslog_channel); - define_channel(savestr("default_debug", 1), debug_channel); - define_channel(savestr("default_stderr", 1), stderr_channel); - define_channel(savestr("null", 1), null_channel); -} - -static void -parser_setup() { - seen_options = 0; - seen_topology = 0; - symtab = new_symbol_table(SYMBOL_TABLE_SIZE, NULL); - if (authtab != NULL) - free_symbol_table(authtab); - authtab = new_symbol_table(AUTH_TABLE_SIZE, free_sym_value); - init_acls(); - define_builtin_channels(); - INIT_LIST(current_controls); -} - -static void -parser_cleanup() { - if (symtab != NULL) - free_symbol_table(symtab); - symtab = NULL; - /* - * We don't clean up authtab here because the ip_match_lists are in - * use. - */ -} - -/* - * Public Interface - */ - -ip_match_list -lookup_acl(char *name) { - symbol_value value; - - if (lookup_symbol(authtab, name, SYM_ACL, &value)) - return ((ip_match_list)(value.pointer)); - return (NULL); -} - -void -define_acl(char *name, ip_match_list iml) { - symbol_value value; - - INSIST(name != NULL); - INSIST(iml != NULL); - - value.pointer = iml; - define_symbol(authtab, name, SYM_ACL, value, - SYMBOL_FREE_KEY|SYMBOL_FREE_VALUE); - ns_debug(ns_log_parser, 7, "acl %s", name); - dprint_ip_match_list(ns_log_parser, iml, 2, "allow ", "deny "); -} - -struct dst_key * -lookup_key(char *name) { - symbol_value value; - - if (lookup_symbol(authtab, name, SYM_KEY, &value)) - return ((struct dst_key *)(value.pointer)); - return (NULL); -} - -void -define_key(char *name, struct dst_key *dst_key) { - symbol_value value; - - INSIST(name != NULL); - INSIST(dst_key != NULL); - - value.pointer = dst_key; - define_symbol(authtab, name, SYM_KEY, value, SYMBOL_FREE_VALUE); - dprint_key_info(dst_key); -} - -void -parse_configuration(const char *filename) { - FILE *config_stream; - - config_stream = fopen(filename, "r"); - if (config_stream == NULL) - ns_panic(ns_log_parser, 0, "can't open '%s'", filename); - - lexer_setup(); - parser_setup(); - lexer_begin_file(filename, config_stream); - (void)yyparse(); - lexer_end_file(); - parser_cleanup(); -} - -void -parser_initialize(void) { - lexer_initialize(); -} - -void -parser_shutdown(void) { - if (authtab != NULL) - free_symbol_table(authtab); - lexer_shutdown(); -} -#line 1216 "y.tab.c" -/* allocate initial stack */ -#if defined(__STDC__) || defined(__cplusplus) -static int yyinitstack(struct yystack *sp) -#else -static int yyinitstack(sp) - struct yystack *sp; -#endif -{ - int newsize; - short *newss; - YYSTYPE *newvs; - - newsize = YYINITSTACKSIZE; - newss = (short *)malloc(newsize * sizeof *newss); - newvs = (YYSTYPE *)malloc(newsize * sizeof *newvs); - sp->ss = sp->ssp = newss; - sp->vs = sp->vsp = newvs; - if (newss == NULL || newvs == NULL) return -1; - sp->stacksize = newsize; - sp->sslim = newss + newsize - 1; - return 0; -} - -/* double stack size, up to YYMAXDEPTH */ -#if defined(__STDC__) || defined(__cplusplus) -static int yygrowstack(struct yystack *sp) -#else -static int yygrowstack(sp) - struct yystack *sp; -#endif -{ - int newsize, i; - short *newss; - YYSTYPE *newvs; - - if ((newsize = sp->stacksize) >= YYMAXDEPTH) return -1; - if ((newsize *= 2) > YYMAXDEPTH) newsize = YYMAXDEPTH; - i = sp->ssp - sp->ss; - if ((newss = (short *)realloc(sp->ss, newsize * sizeof *newss)) == NULL) - return -1; - sp->ss = newss; - sp->ssp = newss + i; - if ((newvs = (YYSTYPE *)realloc(sp->vs, newsize * sizeof *newvs)) == NULL) - return -1; - sp->vs = newvs; - sp->vsp = newvs + i; - sp->stacksize = newsize; - sp->sslim = newss + newsize - 1; - return 0; -} - -#define YYFREESTACK(sp) { free((sp)->ss); free((sp)->vs); } - -#define YYABORT goto yyabort -#define YYREJECT goto yyabort -#define YYACCEPT goto yyaccept -#define YYERROR goto yyerrlab -int -yyparse() -{ - register int yym, yyn, yystate, yych; - register YYSTYPE *yyvsp; - YYSTYPE yyval; - struct yystack yystk; -#if YYDEBUG - register char *yys; - extern char *getenv(); - - if (yys = getenv("YYDEBUG")) - { - yyn = *yys; - if (yyn >= '0' && yyn <= '9') - yydebug = yyn - '0'; - } -#endif - - yynerrs = 0; - yyerrflag = 0; - yychar = yych = YYEMPTY; - - if (yyinitstack(&yystk)) goto yyoverflow; - *yystk.ssp = yystate = 0; - -yyloop: - if (yyn = yydefred[yystate]) goto yyreduce; - if (yych < 0) - { - if ((yych = YYLEX) < 0) yych = 0; - yychar = yych; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yych <= YYMAXTOKEN) yys = yyname[yych]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, yystate, yych, yys); - } -#endif - } - if ((yyn = yysindex[yystate]) && (yyn += yych) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yych) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, shifting to state %d\n", - YYPREFIX, yystate, yytable[yyn]); -#endif - if (yystk.ssp >= yystk.sslim && yygrowstack(&yystk)) - goto yyoverflow; - *++yystk.ssp = yystate = yytable[yyn]; - *++yystk.vsp = yylval; - yychar = yych = YYEMPTY; - if (yyerrflag > 0) --yyerrflag; - goto yyloop; - } - if ((yyn = yyrindex[yystate]) && (yyn += yych) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yych) - { - yyn = yytable[yyn]; - goto yyreduce; - } - if (yyerrflag) goto yyinrecovery; -#ifdef lint - goto yynewerror; -#endif -yynewerror: - yyerror("syntax error"); -#ifdef lint - goto yyerrlab; -#endif -yyerrlab: - ++yynerrs; -yyinrecovery: - if (yyerrflag < 3) - { - yyerrflag = 3; - for (;;) - { - if ((yyn = yysindex[*yystk.ssp]) && - (yyn += YYERRCODE) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, error recovery shifting\ - to state %d\n", YYPREFIX, *yystk.ssp, yytable[yyn]); -#endif - if (yystk.ssp >= yystk.sslim && yygrowstack(&yystk)) - goto yyoverflow; - *++yystk.ssp = yystate = yytable[yyn]; - *++yystk.vsp = yylval; - goto yyloop; - } - else - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: error recovery discarding state %d\n", - YYPREFIX, *yystk.ssp); -#endif - if (yystk.ssp <= yystk.ss) goto yyabort; - --yystk.ssp; - --yystk.vsp; - } - } - } - else - { - if (yych == 0) goto yyabort; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yych <= YYMAXTOKEN) yys = yyname[yych]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, error recovery discards token %d (%s)\n", - YYPREFIX, yystate, yych, yys); - } -#endif - yychar = yych = YYEMPTY; - goto yyloop; - } -yyreduce: -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, reducing by rule %d (%s)\n", - YYPREFIX, yystate, yyn, yyrule[yyn]); -#endif - yym = yylen[yyn]; - yyvsp = yystk.vsp; /* for speed in code under switch() */ - yyval = yyvsp[1-yym]; - switch (yyn) - { -case 1: -#line 241 "ns_parser.y" -{ - if (EMPTY(current_controls)) - ns_ctl_defaults(¤t_controls); - ns_ctl_install(¤t_controls); - } -break; -case 16: -#line 266 "ns_parser.y" -{ lexer_begin_file(yyvsp[-1].cp, NULL); } -break; -case 17: -#line 274 "ns_parser.y" -{ - if (seen_options) - parser_error(0, "cannot redefine options"); - current_options = new_options(); - } -break; -case 18: -#line 280 "ns_parser.y" -{ - if (!seen_options) - set_options(current_options, 0); - else - free_options(current_options); - current_options = NULL; - seen_options = 1; - } -break; -case 22: -#line 296 "ns_parser.y" -{ - if (current_options->version != NULL) - freestr(current_options->version); - current_options->version = yyvsp[0].cp; - } -break; -case 23: -#line 302 "ns_parser.y" -{ - if (current_options->directory != NULL) - freestr(current_options->directory); - current_options->directory = yyvsp[0].cp; - } -break; -case 24: -#line 308 "ns_parser.y" -{ - if (current_options->named_xfer != NULL) - freestr(current_options->named_xfer); - current_options->named_xfer = yyvsp[0].cp; - } -break; -case 25: -#line 314 "ns_parser.y" -{ - if (current_options->pid_filename != NULL) - freestr(current_options->pid_filename); - current_options->pid_filename = yyvsp[0].cp; - } -break; -case 26: -#line 320 "ns_parser.y" -{ - if (current_options->stats_filename != NULL) - freestr(current_options->stats_filename); - current_options->stats_filename = yyvsp[0].cp; - } -break; -case 27: -#line 326 "ns_parser.y" -{ - if (current_options->memstats_filename != NULL) - freestr(current_options->memstats_filename); - current_options->memstats_filename = yyvsp[0].cp; - } -break; -case 28: -#line 332 "ns_parser.y" -{ - if (current_options->dump_filename != NULL) - freestr(current_options->dump_filename); - current_options->dump_filename = yyvsp[0].cp; - } -break; -case 29: -#line 338 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_FAKE_IQUERY, yyvsp[0].num); - } -break; -case 30: -#line 343 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_NORECURSE, !yyvsp[0].num); - } -break; -case 31: -#line 348 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_NOFETCHGLUE, !yyvsp[0].num); - } -break; -case 32: -#line 353 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_NONOTIFY, !yyvsp[0].num); - } -break; -case 33: -#line 358 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_HOSTSTATS, yyvsp[0].num); - } -break; -case 34: -#line 363 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_DEALLOC_ON_EXIT, yyvsp[0].num); - } -break; -case 35: -#line 368 "ns_parser.y" -{ - set_global_boolean_option(current_options, OPTION_USE_IXFR, yyvsp[0].num); - } -break; -case 36: -#line 372 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_MAINTAIN_IXFR_BASE, yyvsp[0].num); - } -break; -case 37: -#line 377 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_MAINTAIN_IXFR_BASE, yyvsp[0].num); - set_global_boolean_option(current_options, - OPTION_NORFC2308_TYPE1, yyvsp[0].num); - set_global_boolean_option(current_options, - OPTION_NONAUTH_NXDOMAIN, !yyvsp[0].num); - } -break; -case 38: -#line 386 "ns_parser.y" -{ - set_global_boolean_option(current_options, OPTION_NONAUTH_NXDOMAIN, - !yyvsp[0].num); - } -break; -case 39: -#line 391 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_MULTIPLE_CNAMES, yyvsp[0].num); - } -break; -case 40: -#line 396 "ns_parser.y" -{ - current_options->check_names[yyvsp[-1].s_int] = (enum severity)yyvsp[0].s_int; - } -break; -case 41: -#line 400 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_USE_ID_POOL, yyvsp[0].num); - } -break; -case 42: -#line 405 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_NORFC2308_TYPE1, !yyvsp[0].num); - } -break; -case 43: -#line 410 "ns_parser.y" -{ - char port_string[10]; - symbol_value value; - - (void)sprintf(port_string, "%u", yyvsp[-3].us_int); - if (lookup_symbol(symtab, port_string, SYM_PORT, NULL)) - parser_error(0, - "cannot redefine listen-on for port %u", - ntohs(yyvsp[-3].us_int)); - else { - add_listen_on(current_options, yyvsp[-3].us_int, yyvsp[-1].iml); - value.pointer = NULL; - define_symbol(symtab, savestr(port_string, 1), - SYM_PORT, value, SYMBOL_FREE_KEY); - } - - } -break; -case 45: -#line 429 "ns_parser.y" -{ - if (current_options->fwdtab) { - free_forwarders(current_options->fwdtab); - current_options->fwdtab = NULL; - } - } -break; -case 48: -#line 438 "ns_parser.y" -{ - current_options->axfr_src = yyvsp[0].ip_addr; - } -break; -case 49: -#line 442 "ns_parser.y" -{ - if (current_options->query_acl) { - parser_warning(0, - "options allow-query acl already set; skipping"); - free_ip_match_list(yyvsp[-1].iml); - } else - current_options->query_acl = yyvsp[-1].iml; - } -break; -case 50: -#line 451 "ns_parser.y" -{ - if (current_options->recursion_acl) { - parser_warning(0, - "options allow-recursion acl already set; skipping"); - free_ip_match_list(yyvsp[-1].iml); - } else - current_options->recursion_acl = yyvsp[-1].iml; - } -break; -case 51: -#line 460 "ns_parser.y" -{ - if (current_options->transfer_acl) { - parser_warning(0, - "options allow-transfer acl already set; skipping"); - free_ip_match_list(yyvsp[-1].iml); - } else - current_options->transfer_acl = yyvsp[-1].iml; - } -break; -case 52: -#line 469 "ns_parser.y" -{ - if (current_options->sortlist) { - parser_warning(0, - "options sortlist already set; skipping"); - free_ip_match_list(yyvsp[-1].iml); - } else - current_options->sortlist = yyvsp[-1].iml; - } -break; -case 53: -#line 478 "ns_parser.y" -{ - if (current_options->also_notify) { - parser_warning(0, - "duplicate also-notify clause: overwriting"); - free_also_notify(current_options); - current_options->also_notify = NULL; - } - } -break; -case 55: -#line 488 "ns_parser.y" -{ - if (current_options->blackhole_acl) { - parser_warning(0, - "options blackhole already set; skipping"); - free_ip_match_list(yyvsp[-1].iml); - } else - current_options->blackhole_acl = yyvsp[-1].iml; - } -break; -case 56: -#line 497 "ns_parser.y" -{ - if (current_options->topology) { - parser_warning(0, - "options topology already set; skipping"); - free_ip_match_list(yyvsp[-1].iml); - } else - current_options->topology = yyvsp[-1].iml; - } -break; -case 57: -#line 506 "ns_parser.y" -{ - /* To get around the $$ = $1 default rule. */ - } -break; -case 59: -#line 511 "ns_parser.y" -{ - current_options->transfer_format = yyvsp[0].axfr_fmt; - } -break; -case 60: -#line 515 "ns_parser.y" -{ - current_options->max_transfer_time_in = yyvsp[0].num * 60; - } -break; -case 61: -#line 519 "ns_parser.y" -{ - current_options->serial_queries = yyvsp[0].num; - } -break; -case 62: -#line 523 "ns_parser.y" -{ - current_options->clean_interval = yyvsp[0].num * 60; - } -break; -case 63: -#line 527 "ns_parser.y" -{ - current_options->interface_interval = yyvsp[0].num * 60; - } -break; -case 64: -#line 531 "ns_parser.y" -{ - current_options->stats_interval = yyvsp[0].num * 60; - } -break; -case 65: -#line 535 "ns_parser.y" -{ - current_options->max_log_size_ixfr = yyvsp[0].num; - } -break; -case 66: -#line 539 "ns_parser.y" -{ - current_options->max_ncache_ttl = yyvsp[0].num; - } -break; -case 67: -#line 543 "ns_parser.y" -{ - current_options->lame_ttl = yyvsp[0].num; - } -break; -case 68: -#line 547 "ns_parser.y" -{ - current_options->heartbeat_interval = yyvsp[0].num * 60; - } -break; -case 69: -#line 551 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_NODIALUP, !yyvsp[0].num); - } -break; -case 70: -#line 556 "ns_parser.y" -{ - if (current_options->ordering) - free_rrset_order_list(current_options->ordering); - current_options->ordering = yyvsp[-1].rol; - } -break; -case 71: -#line 562 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_TREAT_CR_AS_SPACE, yyvsp[0].num); - } -break; -case 72: -#line 567 "ns_parser.y" -{ - if (yyvsp[0].num >= 1) - current_options->minroots = yyvsp[0].num; - } -break; -case 78: -#line 587 "ns_parser.y" -{ - ns_ctl_add(¤t_controls, ns_ctl_new_inet(yyvsp[-6].ip_addr, yyvsp[-4].us_int, yyvsp[-1].iml)); - } -break; -case 79: -#line 591 "ns_parser.y" -{ - ns_ctl_add(¤t_controls, ns_ctl_new_unix(yyvsp[-6].cp, yyvsp[-4].num, yyvsp[-2].num, yyvsp[0].num)); - } -break; -case 81: -#line 598 "ns_parser.y" -{ - rrset_order_list rol; - - rol = new_rrset_order_list(); - if (yyvsp[-1].roe != NULL) { - add_to_rrset_order_list(rol, yyvsp[-1].roe); - } - - yyval.rol = rol; - } -break; -case 82: -#line 609 "ns_parser.y" -{ - if (yyvsp[-1].roe != NULL) { - add_to_rrset_order_list(yyvsp[-2].rol, yyvsp[-1].roe); - } - yyval.rol = yyvsp[-2].rol; - } -break; -case 83: -#line 618 "ns_parser.y" -{ - yyval.s_int = C_ANY; - } -break; -case 84: -#line 622 "ns_parser.y" -{ - symbol_value value; - - if (lookup_symbol(constants, yyvsp[0].cp, SYM_CLASS, &value)) - yyval.s_int = value.integer; - else { - parser_error(0, "unknown class '%s'; using ANY", yyvsp[0].cp); - yyval.s_int = C_ANY; - } - freestr(yyvsp[0].cp); - } -break; -case 85: -#line 636 "ns_parser.y" -{ - yyval.s_int = ns_t_any; - } -break; -case 86: -#line 640 "ns_parser.y" -{ - int success; - - if (strcmp(yyvsp[0].cp, "*") == 0) { - yyval.s_int = ns_t_any; - } else { - yyval.s_int = __sym_ston(__p_type_syms, yyvsp[0].cp, &success); - if (success == 0) { - yyval.s_int = ns_t_any; - parser_error(0, - "unknown type '%s'; assuming ANY", - yyvsp[0].cp); - } - } - freestr(yyvsp[0].cp); - } -break; -case 87: -#line 658 "ns_parser.y" -{ - yyval.cp = savestr("*", 1); - } -break; -case 88: -#line 662 "ns_parser.y" -{ - if (strcmp(".",yyvsp[0].cp) == 0 || strcmp("*.",yyvsp[0].cp) == 0) { - yyval.cp = savestr("*", 1); - freestr(yyvsp[0].cp); - } else { - yyval.cp = yyvsp[0].cp ; - } - /* XXX Should do any more name validation here? */ - } -break; -case 89: -#line 674 "ns_parser.y" -{ - enum ordering o; - - if (strlen(yyvsp[0].cp) == 0) { - parser_error(0, "null order name"); - yyval.roe = NULL ; - } else { - o = lookup_ordering(yyvsp[0].cp); - if (o == unknown_order) { - o = (enum ordering)DEFAULT_ORDERING; - parser_error(0, - "invalid order name '%s'; using %s", - yyvsp[0].cp, p_order(o)); - } - - freestr(yyvsp[0].cp); - - yyval.roe = new_rrset_order_element(yyvsp[-4].s_int, yyvsp[-3].s_int, yyvsp[-2].cp, o); - } - } -break; -case 90: -#line 697 "ns_parser.y" -{ - yyval.axfr_fmt = axfr_one_answer; - } -break; -case 91: -#line 701 "ns_parser.y" -{ - yyval.axfr_fmt = axfr_many_answers; - } -break; -case 92: -#line 706 "ns_parser.y" -{ yyval.ip_addr = yyvsp[0].ip_addr; } -break; -case 93: -#line 707 "ns_parser.y" -{ yyval.ip_addr.s_addr = htonl(INADDR_ANY); } -break; -case 94: -#line 710 "ns_parser.y" -{ yyval.us_int = yyvsp[0].us_int; } -break; -case 95: -#line 711 "ns_parser.y" -{ yyval.us_int = htons(0); } -break; -case 96: -#line 715 "ns_parser.y" -{ - current_options->query_source.sin_addr = yyvsp[0].ip_addr; - } -break; -case 97: -#line 721 "ns_parser.y" -{ - current_options->query_source.sin_port = yyvsp[0].us_int; - } -break; -case 102: -#line 732 "ns_parser.y" -{ yyval.us_int = htons(NS_DEFAULTPORT); } -break; -case 103: -#line 733 "ns_parser.y" -{ yyval.us_int = yyvsp[0].us_int; } -break; -case 104: -#line 736 "ns_parser.y" -{ yyval.us_int = htons(0); } -break; -case 105: -#line 737 "ns_parser.y" -{ yyval.us_int = yyvsp[0].us_int; } -break; -case 106: -#line 742 "ns_parser.y" -{ - yyval.num = 1; - } -break; -case 107: -#line 746 "ns_parser.y" -{ - yyval.num = 1; - } -break; -case 108: -#line 750 "ns_parser.y" -{ - yyval.num = 0; - } -break; -case 109: -#line 754 "ns_parser.y" -{ - yyval.num = 0; - } -break; -case 110: -#line 758 "ns_parser.y" -{ - if (yyvsp[0].num == 1 || yyvsp[0].num == 0) { - yyval.num = yyvsp[0].num; - } else { - parser_warning(0, - "number should be 0 or 1; assuming 1"); - yyval.num = 1; - } - } -break; -case 111: -#line 770 "ns_parser.y" -{ - yyval.s_int = primary_trans; - } -break; -case 112: -#line 774 "ns_parser.y" -{ - yyval.s_int = secondary_trans; - } -break; -case 113: -#line 778 "ns_parser.y" -{ - yyval.s_int = response_trans; - } -break; -case 114: -#line 784 "ns_parser.y" -{ - yyval.s_int = warn; - } -break; -case 115: -#line 788 "ns_parser.y" -{ - yyval.s_int = fail; - } -break; -case 116: -#line 792 "ns_parser.y" -{ - yyval.s_int = ignore; - } -break; -case 117: -#line 798 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_FORWARD_ONLY, 1); - } -break; -case 118: -#line 803 "ns_parser.y" -{ - set_global_boolean_option(current_options, - OPTION_FORWARD_ONLY, 0); - } -break; -case 119: -#line 808 "ns_parser.y" -{ - parser_warning(0, "forward if-no-answer is unimplemented"); - } -break; -case 120: -#line 812 "ns_parser.y" -{ - parser_warning(0, "forward if-no-domain is unimplemented"); - } -break; -case 121: -#line 818 "ns_parser.y" -{ - current_options->data_size = yyvsp[0].ul_int; - } -break; -case 122: -#line 822 "ns_parser.y" -{ - current_options->stack_size = yyvsp[0].ul_int; - } -break; -case 123: -#line 826 "ns_parser.y" -{ - current_options->core_size = yyvsp[0].ul_int; - } -break; -case 124: -#line 830 "ns_parser.y" -{ - current_options->files = yyvsp[0].ul_int; - } -break; -case 125: -#line 836 "ns_parser.y" -{ - u_long result; - - if (unit_to_ulong(yyvsp[0].cp, &result)) - yyval.ul_int = result; - else { - parser_error(0, "invalid unit string '%s'", yyvsp[0].cp); - /* 0 means "use default" */ - yyval.ul_int = 0; - } - freestr(yyvsp[0].cp); - } -break; -case 126: -#line 849 "ns_parser.y" -{ - yyval.ul_int = (u_long)yyvsp[0].num; - } -break; -case 127: -#line 853 "ns_parser.y" -{ - yyval.ul_int = 0; - } -break; -case 128: -#line 857 "ns_parser.y" -{ - yyval.ul_int = ULONG_MAX; - } -break; -case 129: -#line 863 "ns_parser.y" -{ - current_options->transfers_in = (u_long) yyvsp[0].num; - } -break; -case 130: -#line 867 "ns_parser.y" -{ - current_options->transfers_out = (u_long) yyvsp[0].num; - } -break; -case 131: -#line 871 "ns_parser.y" -{ - current_options->transfers_per_ns = (u_long) yyvsp[0].num; - } -break; -case 134: -#line 881 "ns_parser.y" -{ - /* nothing */ - } -break; -case 135: -#line 885 "ns_parser.y" -{ - /* nothing */ - } -break; -case 136: -#line 891 "ns_parser.y" -{ - add_global_forwarder(current_options, yyvsp[0].ip_addr); - } -break; -case 139: -#line 901 "ns_parser.y" -{ - /* nothing */ - } -break; -case 140: -#line 905 "ns_parser.y" -{ - /* nothing */ - } -break; -case 141: -#line 911 "ns_parser.y" -{ - add_global_also_notify(current_options, yyvsp[0].ip_addr); - } -break; -case 142: -#line 921 "ns_parser.y" -{ - current_logging = begin_logging(); - } -break; -case 143: -#line 925 "ns_parser.y" -{ - end_logging(current_logging, 1); - current_logging = NULL; - } -break; -case 147: -#line 937 "ns_parser.y" -{ - current_category = yyvsp[0].s_int; - } -break; -case 149: -#line 942 "ns_parser.y" -{ - chan_type = log_null; - chan_flags = 0; - chan_level = log_info; - } -break; -case 150: -#line 948 "ns_parser.y" -{ - log_channel current_channel = NULL; - - if (lookup_channel(yyvsp[-4].cp) != NULL) { - parser_error(0, "can't redefine channel '%s'", yyvsp[-4].cp); - freestr(yyvsp[-4].cp); - } else { - switch (chan_type) { - case log_file: - current_channel = - log_new_file_channel(chan_flags, - chan_level, - chan_name, NULL, - chan_versions, - chan_max_size); - freestr(chan_name); - chan_name = NULL; - break; - case log_syslog: - current_channel = - log_new_syslog_channel(chan_flags, - chan_level, - chan_facility); - break; - case log_null: - current_channel = log_new_null_channel(); - break; - default: - ns_panic(ns_log_parser, 1, - "unknown channel type: %d", - chan_type); - } - if (current_channel == NULL) - ns_panic(ns_log_parser, 0, - "couldn't create channel"); - define_channel(yyvsp[-4].cp, current_channel); - } - } -break; -case 151: -#line 989 "ns_parser.y" -{ - symbol_value value; - - if (lookup_symbol(constants, yyvsp[0].cp, SYM_LOGGING, &value)) { - chan_level = value.integer; - } else { - parser_error(0, "unknown severity '%s'", yyvsp[0].cp); - chan_level = log_debug(99); - } - freestr(yyvsp[0].cp); - } -break; -case 152: -#line 1001 "ns_parser.y" -{ - chan_level = log_debug(1); - } -break; -case 153: -#line 1005 "ns_parser.y" -{ - chan_level = yyvsp[0].num; - } -break; -case 154: -#line 1009 "ns_parser.y" -{ - chan_level = 0; - chan_flags |= LOG_USE_CONTEXT_LEVEL|LOG_REQUIRE_DEBUG; - } -break; -case 155: -#line 1016 "ns_parser.y" -{ - chan_versions = yyvsp[0].num; - } -break; -case 156: -#line 1020 "ns_parser.y" -{ - chan_versions = LOG_MAX_VERSIONS; - } -break; -case 157: -#line 1026 "ns_parser.y" -{ - chan_max_size = yyvsp[0].ul_int; - } -break; -case 158: -#line 1032 "ns_parser.y" -{ - chan_versions = 0; - chan_max_size = ULONG_MAX; - } -break; -case 159: -#line 1037 "ns_parser.y" -{ - chan_max_size = ULONG_MAX; - } -break; -case 160: -#line 1041 "ns_parser.y" -{ - chan_versions = 0; - } -break; -case 163: -#line 1049 "ns_parser.y" -{ - chan_flags |= LOG_CLOSE_STREAM; - chan_type = log_file; - chan_name = yyvsp[-1].cp; - } -break; -case 164: -#line 1057 "ns_parser.y" -{ yyval.cp = yyvsp[0].cp; } -break; -case 165: -#line 1058 "ns_parser.y" -{ yyval.cp = savestr("syslog", 1); } -break; -case 166: -#line 1061 "ns_parser.y" -{ yyval.s_int = LOG_DAEMON; } -break; -case 167: -#line 1063 "ns_parser.y" -{ - symbol_value value; - - if (lookup_symbol(constants, yyvsp[0].cp, SYM_SYSLOG, &value)) { - yyval.s_int = value.integer; - } else { - parser_error(0, "unknown facility '%s'", yyvsp[0].cp); - yyval.s_int = LOG_DAEMON; - } - freestr(yyvsp[0].cp); - } -break; -case 168: -#line 1077 "ns_parser.y" -{ - chan_type = log_syslog; - chan_facility = yyvsp[0].s_int; - } -break; -case 169: -#line 1083 "ns_parser.y" -{ /* nothing to do */ } -break; -case 170: -#line 1084 "ns_parser.y" -{ /* nothing to do */ } -break; -case 171: -#line 1086 "ns_parser.y" -{ - chan_type = log_null; - } -break; -case 172: -#line 1089 "ns_parser.y" -{ /* nothing to do */ } -break; -case 173: -#line 1091 "ns_parser.y" -{ - if (yyvsp[0].num) - chan_flags |= LOG_TIMESTAMP; - else - chan_flags &= ~LOG_TIMESTAMP; - } -break; -case 174: -#line 1098 "ns_parser.y" -{ - if (yyvsp[0].num) - chan_flags |= LOG_PRINT_CATEGORY; - else - chan_flags &= ~LOG_PRINT_CATEGORY; - } -break; -case 175: -#line 1105 "ns_parser.y" -{ - if (yyvsp[0].num) - chan_flags |= LOG_PRINT_LEVEL; - else - chan_flags &= ~LOG_PRINT_LEVEL; - } -break; -case 180: -#line 1119 "ns_parser.y" -{ yyval.cp = savestr("null", 1); } -break; -case 181: -#line 1123 "ns_parser.y" -{ - log_channel channel; - symbol_value value; - - if (current_category >= 0) { - channel = lookup_channel(yyvsp[0].cp); - if (channel != NULL) { - add_log_channel(current_logging, - current_category, channel); - } else - parser_error(0, "unknown channel '%s'", yyvsp[0].cp); - } - freestr(yyvsp[0].cp); - } -break; -case 186: -#line 1145 "ns_parser.y" -{ yyval.cp = savestr("default", 1); } -break; -case 187: -#line 1146 "ns_parser.y" -{ yyval.cp = savestr("notify", 1); } -break; -case 188: -#line 1150 "ns_parser.y" -{ - symbol_value value; - - if (lookup_symbol(constants, yyvsp[0].cp, SYM_CATEGORY, &value)) - yyval.s_int = value.integer; - else { - parser_error(0, "invalid logging category '%s'", - yyvsp[0].cp); - yyval.s_int = -1; - } - freestr(yyvsp[0].cp); - } -break; -case 189: -#line 1169 "ns_parser.y" -{ - const char *ip_printable; - symbol_value value; - - ip_printable = inet_ntoa(yyvsp[0].ip_addr); - value.pointer = NULL; - if (lookup_symbol(symtab, ip_printable, SYM_SERVER, NULL)) - seen_server = 1; - else - seen_server = 0; - if (seen_server) - parser_error(0, "cannot redefine server '%s'", - ip_printable); - else - define_symbol(symtab, savestr(ip_printable, 1), - SYM_SERVER, value, - SYMBOL_FREE_KEY); - current_server = begin_server(yyvsp[0].ip_addr); - } -break; -case 190: -#line 1189 "ns_parser.y" -{ - end_server(current_server, !seen_server); - } -break; -case 193: -#line 1199 "ns_parser.y" -{ - set_server_option(current_server, SERVER_INFO_BOGUS, yyvsp[0].num); - } -break; -case 194: -#line 1203 "ns_parser.y" -{ - set_server_option(current_server, SERVER_INFO_SUPPORT_IXFR, yyvsp[0].num); - } -break; -case 195: -#line 1207 "ns_parser.y" -{ - set_server_transfers(current_server, (int)yyvsp[0].num); - } -break; -case 196: -#line 1211 "ns_parser.y" -{ - set_server_transfer_format(current_server, yyvsp[0].axfr_fmt); - } -break; -case 199: -#line 1223 "ns_parser.y" -{ - ip_match_list iml; - - iml = new_ip_match_list(); - if (yyvsp[-1].ime != NULL) - add_to_ip_match_list(iml, yyvsp[-1].ime); - yyval.iml = iml; - } -break; -case 200: -#line 1232 "ns_parser.y" -{ - if (yyvsp[-1].ime != NULL) - add_to_ip_match_list(yyvsp[-2].iml, yyvsp[-1].ime); - yyval.iml = yyvsp[-2].iml; - } -break; -case 202: -#line 1241 "ns_parser.y" -{ - if (yyvsp[0].ime != NULL) - ip_match_negate(yyvsp[0].ime); - yyval.ime = yyvsp[0].ime; - } -break; -case 203: -#line 1247 "ns_parser.y" -{ - char *key_name; - struct dst_key *dst_key; - - key_name = canonical_name(yyvsp[0].cp); - if (key_name == NULL) { - parser_error(0, "can't make key name '%s' canonical", - yyvsp[0].cp); - key_name = savestr("__bad_key__", 1); - } - dst_key = find_key(key_name, NULL); - if (dst_key == NULL) { - parser_error(0, "key \"%s\" not found", key_name); - yyval.ime = NULL; - } - else - yyval.ime = new_ip_match_key(dst_key); - } -break; -case 204: -#line 1268 "ns_parser.y" -{ - yyval.ime = new_ip_match_pattern(yyvsp[0].ip_addr, 32); - } -break; -case 205: -#line 1272 "ns_parser.y" -{ - if (yyvsp[0].num < 0 || yyvsp[0].num > 32) { - parser_error(0, "mask bits out of range; skipping"); - yyval.ime = NULL; - } else { - yyval.ime = new_ip_match_pattern(yyvsp[-2].ip_addr, yyvsp[0].num); - if (yyval.ime == NULL) - parser_error(0, - "address/mask mismatch; skipping"); - } - } -break; -case 206: -#line 1284 "ns_parser.y" -{ - struct in_addr ia; - - if (yyvsp[-2].num > 255) { - parser_error(0, "address out of range; skipping"); - yyval.ime = NULL; - } else { - if (yyvsp[0].num < 0 || yyvsp[0].num > 32) { - parser_error(0, - "mask bits out of range; skipping"); - yyval.ime = NULL; - } else { - ia.s_addr = htonl((yyvsp[-2].num & 0xff) << 24); - yyval.ime = new_ip_match_pattern(ia, yyvsp[0].num); - if (yyval.ime == NULL) - parser_error(0, - "address/mask mismatch; skipping"); - } - } - } -break; -case 208: -#line 1306 "ns_parser.y" -{ - char name[256]; - - /* - * We want to be able to clean up this iml later so - * we give it a name and treat it like any other acl. - */ - sprintf(name, "__internal_%p", yyvsp[-1].iml); - define_acl(savestr(name, 1), yyvsp[-1].iml); - yyval.ime = new_ip_match_indirect(yyvsp[-1].iml); - } -break; -case 209: -#line 1320 "ns_parser.y" -{ - ip_match_list iml; - - iml = lookup_acl(yyvsp[0].cp); - if (iml == NULL) { - parser_error(0, "unknown ACL '%s'", yyvsp[0].cp); - yyval.ime = NULL; - } else - yyval.ime = new_ip_match_indirect(iml); - freestr(yyvsp[0].cp); - } -break; -case 210: -#line 1338 "ns_parser.y" -{ - struct dst_key *dst_key; - char *key_name; - - key_name = canonical_name(yyvsp[0].cp); - if (key_name == NULL) { - parser_error(0, "can't make key name '%s' canonical", - yyvsp[0].cp); - yyval.keyi = NULL; - } else { - dst_key = lookup_key(key_name); - if (dst_key == NULL) { - parser_error(0, "unknown key '%s'", key_name); - yyval.keyi = NULL; - } else - yyval.keyi = dst_key; - freestr(key_name); - } - freestr(yyvsp[0].cp); - } -break; -case 211: -#line 1361 "ns_parser.y" -{ - if (yyvsp[0].keyi == NULL) - parser_error(0, "empty key not added to server list "); - else - add_server_key_info(current_server, yyvsp[0].keyi); - } -break; -case 215: -#line 1375 "ns_parser.y" -{ - current_algorithm = NULL; - current_secret = NULL; - } -break; -case 216: -#line 1380 "ns_parser.y" -{ - struct dst_key *dst_key; - char *key_name; - - key_name = canonical_name(yyvsp[-3].cp); - if (key_name == NULL) { - parser_error(0, "can't make key name '%s' canonical", - yyvsp[-3].cp); - } else if (lookup_key(key_name) != NULL) { - parser_error(0, "can't redefine key '%s'", key_name); - freestr(key_name); - } else { - if (current_algorithm == NULL || - current_secret == NULL) { - parser_error(0, "skipping bad key '%s'", - key_name); - freestr(key_name); - } else { - dst_key = new_key_info(key_name, - current_algorithm, - current_secret); - if (dst_key != NULL) { - define_key(key_name, dst_key); - if (secretkey_info == NULL) - secretkey_info = - new_key_info_list(); - add_to_key_info_list(secretkey_info, - dst_key); - } - } - } - freestr(yyvsp[-3].cp); - } -break; -case 217: -#line 1416 "ns_parser.y" -{ - current_algorithm = yyvsp[-1].cp; - current_secret = yyvsp[0].cp; - } -break; -case 218: -#line 1421 "ns_parser.y" -{ - current_algorithm = yyvsp[0].cp; - current_secret = yyvsp[-1].cp; - } -break; -case 219: -#line 1426 "ns_parser.y" -{ - current_algorithm = NULL; - current_secret = NULL; - } -break; -case 220: -#line 1432 "ns_parser.y" -{ yyval.cp = yyvsp[-1].cp; } -break; -case 221: -#line 1435 "ns_parser.y" -{ yyval.cp = yyvsp[-1].cp; } -break; -case 222: -#line 1443 "ns_parser.y" -{ - if (lookup_acl(yyvsp[-3].cp) != NULL) { - parser_error(0, "can't redefine ACL '%s'", yyvsp[-3].cp); - freestr(yyvsp[-3].cp); - } else - define_acl(yyvsp[-3].cp, yyvsp[-1].iml); - } -break; -case 223: -#line 1457 "ns_parser.y" -{ - int sym_type; - symbol_value value; - char *zone_name; - - if (!seen_options) - parser_error(0, - "no options statement before first zone; using previous/default"); - sym_type = SYM_ZONE | (yyvsp[0].num & 0xffff); - value.pointer = NULL; - zone_name = canonical_name(yyvsp[-1].cp); - if (zone_name == NULL) { - parser_error(0, "can't make zone name '%s' canonical", - yyvsp[-1].cp); - should_install = 0; - zone_name = savestr("__bad_zone__", 1); - } else { - if (lookup_symbol(symtab, zone_name, sym_type, NULL)) { - should_install = 0; - parser_error(0, - "cannot redefine zone '%s' class %s", - *zone_name ? zone_name : ".", - p_class(yyvsp[0].num)); - } else { - should_install = 1; - define_symbol(symtab, savestr(zone_name, 1), - sym_type, value, - SYMBOL_FREE_KEY); - } - } - freestr(yyvsp[-1].cp); - current_zone = begin_zone(zone_name, yyvsp[0].num); - } -break; -case 224: -#line 1491 "ns_parser.y" -{ - end_zone(current_zone, should_install); - } -break; -case 227: -#line 1501 "ns_parser.y" -{ - yyval.num = C_IN; - } -break; -case 228: -#line 1505 "ns_parser.y" -{ - symbol_value value; - - if (lookup_symbol(constants, yyvsp[0].cp, SYM_CLASS, &value)) - yyval.num = value.integer; - else { - /* the zone validator will give the error */ - yyval.num = C_NONE; - } - freestr(yyvsp[0].cp); - } -break; -case 229: -#line 1519 "ns_parser.y" -{ - yyval.s_int = Z_MASTER; - } -break; -case 230: -#line 1523 "ns_parser.y" -{ - yyval.s_int = Z_SLAVE; - } -break; -case 231: -#line 1527 "ns_parser.y" -{ - yyval.s_int = Z_HINT; - } -break; -case 232: -#line 1531 "ns_parser.y" -{ - yyval.s_int = Z_STUB; - } -break; -case 233: -#line 1535 "ns_parser.y" -{ - yyval.s_int = Z_FORWARD; - } -break; -case 236: -#line 1545 "ns_parser.y" -{ - if (!set_zone_type(current_zone, yyvsp[0].s_int)) - parser_warning(0, "zone type already set; skipping"); - } -break; -case 237: -#line 1550 "ns_parser.y" -{ - if (!set_zone_filename(current_zone, yyvsp[0].cp)) - parser_warning(0, - "zone filename already set; skipping"); - } -break; -case 238: -#line 1556 "ns_parser.y" -{ - if (!set_zone_ixfr_file(current_zone, yyvsp[0].cp)) - parser_warning(0, - "zone ixfr data base already set; skipping"); - } -break; -case 239: -#line 1562 "ns_parser.y" -{ - if (!set_zone_ixfr_tmp(current_zone, yyvsp[0].cp)) - parser_warning(0, - "zone ixfr temp filename already set; skipping"); - } -break; -case 240: -#line 1568 "ns_parser.y" -{ - set_zone_master_port(current_zone, yyvsp[-3].us_int); - } -break; -case 241: -#line 1572 "ns_parser.y" -{ - set_zone_transfer_source(current_zone, yyvsp[0].ip_addr); - } -break; -case 242: -#line 1576 "ns_parser.y" -{ - if (!set_zone_checknames(current_zone, (enum severity)yyvsp[0].s_int)) - parser_warning(0, - "zone checknames already set; skipping"); - } -break; -case 243: -#line 1582 "ns_parser.y" -{ - if (!set_zone_update_acl(current_zone, yyvsp[-1].iml)) - parser_warning(0, - "zone update acl already set; skipping"); - } -break; -case 244: -#line 1588 "ns_parser.y" -{ - if (!set_zone_query_acl(current_zone, yyvsp[-1].iml)) - parser_warning(0, - "zone query acl already set; skipping"); - } -break; -case 245: -#line 1594 "ns_parser.y" -{ - if (!set_zone_transfer_acl(current_zone, yyvsp[-1].iml)) - parser_warning(0, - "zone transfer acl already set; skipping"); - } -break; -case 247: -#line 1601 "ns_parser.y" -{ - struct zoneinfo *zp = current_zone.opaque; - if (zp->z_fwdtab) { - free_forwarders(zp->z_fwdtab); - zp->z_fwdtab = NULL; - } - - } -break; -case 249: -#line 1611 "ns_parser.y" -{ - if (!set_zone_transfer_time_in(current_zone, yyvsp[0].num*60)) - parser_warning(0, - "zone max transfer time (in) already set; skipping"); - } -break; -case 250: -#line 1617 "ns_parser.y" -{ - set_zone_max_log_size_ixfr(current_zone, yyvsp[0].num); - } -break; -case 251: -#line 1621 "ns_parser.y" -{ - set_zone_notify(current_zone, yyvsp[0].num); - } -break; -case 252: -#line 1625 "ns_parser.y" -{ - set_zone_maintain_ixfr_base(current_zone, yyvsp[0].num); - } -break; -case 253: -#line 1629 "ns_parser.y" -{ - /* flags proto alg key */ - set_zone_pubkey(current_zone, yyvsp[-3].num, yyvsp[-2].num, yyvsp[-1].num, yyvsp[0].cp); - } -break; -case 254: -#line 1634 "ns_parser.y" -{ - /* flags proto alg key */ - char *endp; - int flags = (int) strtol(yyvsp[-3].cp, &endp, 0); - if (*endp != '\0') - ns_panic(ns_log_parser, 1, - "Invalid flags string: %s", yyvsp[-3].cp); - set_zone_pubkey(current_zone, flags, yyvsp[-2].num, yyvsp[-1].num, yyvsp[0].cp); - - } -break; -case 256: -#line 1646 "ns_parser.y" -{ - set_zone_dialup(current_zone, yyvsp[0].num); - } -break; -case 258: -#line 1653 "ns_parser.y" -{ - /* nothing */ - } -break; -case 259: -#line 1657 "ns_parser.y" -{ - /* nothing */ - } -break; -case 260: -#line 1663 "ns_parser.y" -{ - add_zone_master(current_zone, yyvsp[0].ip_addr); - } -break; -case 263: -#line 1673 "ns_parser.y" -{ - /* nothing */ - } -break; -case 264: -#line 1677 "ns_parser.y" -{ - /* nothing */ - } -break; -case 265: -#line 1683 "ns_parser.y" -{ - add_zone_notify(current_zone, yyvsp[0].ip_addr); - } -break; -case 266: -#line 1689 "ns_parser.y" -{ - set_zone_boolean_option(current_zone, OPTION_FORWARD_ONLY, 1); - } -break; -case 267: -#line 1693 "ns_parser.y" -{ - set_zone_boolean_option(current_zone, OPTION_FORWARD_ONLY, 0); - } -break; -case 268: -#line 1699 "ns_parser.y" -{ - set_zone_forward(current_zone); - } -break; -case 270: -#line 1706 "ns_parser.y" -{ - /* nothing */ - } -break; -case 271: -#line 1710 "ns_parser.y" -{ - /* nothing */ - } -break; -case 272: -#line 1716 "ns_parser.y" -{ - add_zone_forwarder(current_zone, yyvsp[0].ip_addr); - } -break; -case 273: -#line 1726 "ns_parser.y" -{ - } -break; -case 274: -#line 1730 "ns_parser.y" -{ - /* nothing */ - } -break; -case 275: -#line 1734 "ns_parser.y" -{ - /* nothing */ - } -break; -case 276: -#line 1739 "ns_parser.y" -{ - /* name flags proto alg key */ - set_trusted_key(yyvsp[-4].cp, yyvsp[-3].num, yyvsp[-2].num, yyvsp[-1].num, yyvsp[0].cp); - } -break; -case 277: -#line 1744 "ns_parser.y" -{ - /* name flags proto alg key */ - char *endp; - int flags = (int) strtol(yyvsp[-3].cp, &endp, 0); - if (*endp != '\0') - ns_panic(ns_log_parser, 1, - "Invalid flags string: %s", yyvsp[-3].cp); - set_trusted_key(yyvsp[-4].cp, flags, yyvsp[-2].num, yyvsp[-1].num, yyvsp[0].cp); - } -break; -case 278: -#line 1760 "ns_parser.y" -{ - if (yyvsp[0].num < 0 || yyvsp[0].num > 65535) { - parser_warning(0, - "invalid IP port number '%d'; setting port to 0", - yyvsp[0].num); - yyvsp[0].num = 0; - } else - yyval.us_int = htons(yyvsp[0].num); - } -break; -#line 3093 "y.tab.c" - } - yystk.ssp -= yym; - yystate = *yystk.ssp; - yystk.vsp -= yym; - yym = yylhs[yyn]; - yych = yychar; - if (yystate == 0 && yym == 0) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state 0 to\ - state %d\n", YYPREFIX, YYFINAL); -#endif - yystate = YYFINAL; - *++yystk.ssp = YYFINAL; - *++yystk.vsp = yyval; - if (yych < 0) - { - if ((yych = YYLEX) < 0) yych = 0; - yychar = yych; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yych <= YYMAXTOKEN) yys = yyname[yych]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, YYFINAL, yych, yys); - } -#endif - } - if (yych == 0) goto yyaccept; - goto yyloop; - } - if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yystate) - yystate = yytable[yyn]; - else - yystate = yydgoto[yym]; -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state %d \ -to state %d\n", YYPREFIX, *yystk.ssp, yystate); -#endif - if (yystk.ssp >= yystk.sslim && yygrowstack(&yystk)) - goto yyoverflow; - *++yystk.ssp = yystate; - *++yystk.vsp = yyval; - goto yyloop; -yyoverflow: - yyerror("yacc stack overflow"); -yyabort: - YYFREESTACK(&yystk); - return (1); -yyaccept: - YYFREESTACK(&yystk); - return (0); -} diff --git a/contrib/bind/bin/named/ns_parser.h b/contrib/bind/bin/named/ns_parser.h deleted file mode 100644 index 571fb473ea7b3..0000000000000 --- a/contrib/bind/bin/named/ns_parser.h +++ /dev/null @@ -1,145 +0,0 @@ -#define YYEMPTY (-1) -#define L_EOS 257 -#define L_IPADDR 258 -#define L_NUMBER 259 -#define L_STRING 260 -#define L_QSTRING 261 -#define L_END_INCLUDE 262 -#define T_INCLUDE 263 -#define T_OPTIONS 264 -#define T_DIRECTORY 265 -#define T_PIDFILE 266 -#define T_NAMED_XFER 267 -#define T_DUMP_FILE 268 -#define T_STATS_FILE 269 -#define T_MEMSTATS_FILE 270 -#define T_FAKE_IQUERY 271 -#define T_RECURSION 272 -#define T_FETCH_GLUE 273 -#define T_QUERY_SOURCE 274 -#define T_LISTEN_ON 275 -#define T_PORT 276 -#define T_ADDRESS 277 -#define T_RRSET_ORDER 278 -#define T_ORDER 279 -#define T_NAME 280 -#define T_CLASS 281 -#define T_CONTROLS 282 -#define T_INET 283 -#define T_UNIX 284 -#define T_PERM 285 -#define T_OWNER 286 -#define T_GROUP 287 -#define T_ALLOW 288 -#define T_DATASIZE 289 -#define T_STACKSIZE 290 -#define T_CORESIZE 291 -#define T_DEFAULT 292 -#define T_UNLIMITED 293 -#define T_FILES 294 -#define T_VERSION 295 -#define T_HOSTSTATS 296 -#define T_DEALLOC_ON_EXIT 297 -#define T_TRANSFERS_IN 298 -#define T_TRANSFERS_OUT 299 -#define T_TRANSFERS_PER_NS 300 -#define T_TRANSFER_FORMAT 301 -#define T_MAX_TRANSFER_TIME_IN 302 -#define T_SERIAL_QUERIES 303 -#define T_ONE_ANSWER 304 -#define T_MANY_ANSWERS 305 -#define T_NOTIFY 306 -#define T_AUTH_NXDOMAIN 307 -#define T_MULTIPLE_CNAMES 308 -#define T_USE_IXFR 309 -#define T_MAINTAIN_IXFR_BASE 310 -#define T_CLEAN_INTERVAL 311 -#define T_INTERFACE_INTERVAL 312 -#define T_STATS_INTERVAL 313 -#define T_MAX_LOG_SIZE_IXFR 314 -#define T_HEARTBEAT 315 -#define T_USE_ID_POOL 316 -#define T_MAX_NCACHE_TTL 317 -#define T_HAS_OLD_CLIENTS 318 -#define T_RFC2308_TYPE1 319 -#define T_LAME_TTL 320 -#define T_MIN_ROOTS 321 -#define T_TREAT_CR_AS_SPACE 322 -#define T_LOGGING 323 -#define T_CATEGORY 324 -#define T_CHANNEL 325 -#define T_SEVERITY 326 -#define T_DYNAMIC 327 -#define T_FILE 328 -#define T_VERSIONS 329 -#define T_SIZE 330 -#define T_SYSLOG 331 -#define T_DEBUG 332 -#define T_NULL_OUTPUT 333 -#define T_PRINT_TIME 334 -#define T_PRINT_CATEGORY 335 -#define T_PRINT_SEVERITY 336 -#define T_SORTLIST 337 -#define T_TOPOLOGY 338 -#define T_SERVER 339 -#define T_LONG_AXFR 340 -#define T_BOGUS 341 -#define T_TRANSFERS 342 -#define T_KEYS 343 -#define T_SUPPORT_IXFR 344 -#define T_ZONE 345 -#define T_IN 346 -#define T_CHAOS 347 -#define T_HESIOD 348 -#define T_TYPE 349 -#define T_MASTER 350 -#define T_SLAVE 351 -#define T_STUB 352 -#define T_RESPONSE 353 -#define T_HINT 354 -#define T_MASTERS 355 -#define T_TRANSFER_SOURCE 356 -#define T_PUBKEY 357 -#define T_ALSO_NOTIFY 358 -#define T_DIALUP 359 -#define T_FILE_IXFR 360 -#define T_IXFR_TMP 361 -#define T_TRUSTED_KEYS 362 -#define T_ACL 363 -#define T_ALLOW_UPDATE 364 -#define T_ALLOW_QUERY 365 -#define T_ALLOW_TRANSFER 366 -#define T_ALLOW_RECURSION 367 -#define T_BLACKHOLE 368 -#define T_SEC_KEY 369 -#define T_ALGID 370 -#define T_SECRET 371 -#define T_CHECK_NAMES 372 -#define T_WARN 373 -#define T_FAIL 374 -#define T_IGNORE 375 -#define T_FORWARD 376 -#define T_FORWARDERS 377 -#define T_ONLY 378 -#define T_FIRST 379 -#define T_IF_NO_ANSWER 380 -#define T_IF_NO_DOMAIN 381 -#define T_YES 382 -#define T_TRUE 383 -#define T_NO 384 -#define T_FALSE 385 -typedef union { - char * cp; - int s_int; - long num; - u_long ul_int; - u_int16_t us_int; - struct in_addr ip_addr; - ip_match_element ime; - ip_match_list iml; - rrset_order_list rol; - rrset_order_element roe; - struct dst_key * keyi; - enum axfr_format axfr_fmt; -} YYSTYPE; -extern YYSTYPE yylval; diff --git a/contrib/bind/bin/named/ns_parser.y b/contrib/bind/bin/named/ns_parser.y deleted file mode 100644 index c987e2b404be1..0000000000000 --- a/contrib/bind/bin/named/ns_parser.y +++ /dev/null @@ -1,1970 +0,0 @@ -%{ -#if !defined(lint) && !defined(SABER) -static char rcsid[] = "$Id: ns_parser.y,v 8.55 2000/04/23 02:18:59 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* Global C stuff goes here. */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <limits.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" -#include "ns_parseutil.h" -#include "ns_lexer.h" - -#define SYM_ZONE 0x010000 -#define SYM_SERVER 0x020000 -#define SYM_KEY 0x030000 -#define SYM_ACL 0x040000 -#define SYM_CHANNEL 0x050000 -#define SYM_PORT 0x060000 - -#define SYMBOL_TABLE_SIZE 29989 /* should always be prime */ -static symbol_table symtab; - -#define AUTH_TABLE_SIZE 397 /* should always be prime */ -static symbol_table authtab = NULL; - -static zone_config current_zone; -static int should_install; - -static options current_options; -static int seen_options; - -static controls current_controls; - -static topology_config current_topology; -static int seen_topology; - -static server_config current_server; -static int seen_server; - -static char *current_algorithm; -static char *current_secret; - -static log_config current_logging; -static int current_category; -static int chan_type; -static int chan_level; -static u_int chan_flags; -static int chan_facility; -static char *chan_name; -static int chan_versions; -static u_long chan_max_size; - -static log_channel lookup_channel(char *); -static void define_channel(char *, log_channel); -static char *canonical_name(char *); - -int yyparse(); - -%} - -%union { - char * cp; - int s_int; - long num; - u_long ul_int; - u_int16_t us_int; - struct in_addr ip_addr; - ip_match_element ime; - ip_match_list iml; - rrset_order_list rol; - rrset_order_element roe; - struct dst_key * keyi; - enum axfr_format axfr_fmt; -} - -/* Lexical analyzer return values. */ -%token L_EOS -%token <ip_addr> L_IPADDR -%token <num> L_NUMBER -%token <cp> L_STRING -%token <cp> L_QSTRING -%token L_END_INCLUDE - -/* Include support */ -%token T_INCLUDE - -/* Items related to the "options" statement: */ -%token T_OPTIONS -%token T_DIRECTORY T_PIDFILE T_NAMED_XFER -%token T_DUMP_FILE T_STATS_FILE T_MEMSTATS_FILE -%token T_FAKE_IQUERY T_RECURSION T_FETCH_GLUE -%token T_QUERY_SOURCE T_LISTEN_ON T_PORT T_ADDRESS -%token T_RRSET_ORDER T_ORDER T_NAME T_CLASS -%token T_CONTROLS T_INET T_UNIX T_PERM T_OWNER T_GROUP T_ALLOW -%type <us_int> in_port -%type <us_int> maybe_port -%type <us_int> maybe_zero_port -%type <us_int> maybe_wild_port -%type <ip_addr> maybe_wild_addr -%token T_DATASIZE T_STACKSIZE T_CORESIZE -%token T_DEFAULT T_UNLIMITED -%token T_FILES T_VERSION -%token T_HOSTSTATS T_DEALLOC_ON_EXIT -%token T_TRANSFERS_IN T_TRANSFERS_OUT T_TRANSFERS_PER_NS -%token T_TRANSFER_FORMAT T_MAX_TRANSFER_TIME_IN -%token T_SERIAL_QUERIES T_ONE_ANSWER T_MANY_ANSWERS -%type <axfr_fmt> transfer_format -%token T_NOTIFY T_AUTH_NXDOMAIN T_MULTIPLE_CNAMES T_USE_IXFR T_MAINTAIN_IXFR_BASE -%token T_CLEAN_INTERVAL T_INTERFACE_INTERVAL T_STATS_INTERVAL T_MAX_LOG_SIZE_IXFR -%token T_HEARTBEAT T_USE_ID_POOL -%token T_MAX_NCACHE_TTL T_HAS_OLD_CLIENTS T_RFC2308_TYPE1 -%token T_LAME_TTL T_MIN_ROOTS -%token T_TREAT_CR_AS_SPACE - -/* Items used for the "logging" statement: */ -%token T_LOGGING T_CATEGORY T_CHANNEL T_SEVERITY T_DYNAMIC -%token T_FILE T_VERSIONS T_SIZE -%token T_SYSLOG T_DEBUG T_NULL_OUTPUT -%token T_PRINT_TIME T_PRINT_CATEGORY T_PRINT_SEVERITY -%type <s_int> category -%type <cp> category_name channel_name facility_name -%type <s_int> maybe_syslog_facility - -/* Items used for the "sortlist" statement: */ -%token T_SORTLIST - -/* Items used for the "topology" statement: */ -%token T_TOPOLOGY - -%type <s_int> ordering_class -%type <s_int> ordering_type -%type <cp> ordering_name -%type <rol> rrset_ordering_list -%type <roe> rrset_ordering_element - -/* ip_match_list */ -%type <ime> address_match_simple address_match_element address_name -%type <iml> address_match_list - -/* Items used for "server" statements: */ -%token T_SERVER -%token T_LONG_AXFR -%token T_BOGUS -%token T_TRANSFERS -%token T_KEYS -%token T_SUPPORT_IXFR - -/* Items used for "zone" statements: */ -%token T_ZONE -%type <num> optional_class -%type <s_int> zone_type -%token T_IN T_CHAOS T_HESIOD -%token T_TYPE -%token T_MASTER T_SLAVE T_STUB T_RESPONSE -%token T_HINT -%token T_MASTERS T_TRANSFER_SOURCE -%token T_PUBKEY -%token T_ALSO_NOTIFY -%token T_DIALUP -%token T_FILE_IXFR -%token T_IXFR_TMP - -/* Items used for "trusted-keys" statements: */ -%token T_TRUSTED_KEYS - -/* Items used for access control lists and "allow" clauses: */ -%token T_ACL -%token T_ALLOW_UPDATE T_ALLOW_QUERY T_ALLOW_TRANSFER -%token T_ALLOW_RECURSION -%token T_BLACKHOLE - -/* Items related to the "key" statement: */ -%token T_SEC_KEY T_ALGID T_SECRET -%type <keyi> key_ref -%type <cp> algorithm_id secret - -/* Items used for "size_spec" clauses: */ -%type <ul_int> size_spec - -/* Items used for a "check-names" clause: */ -%token T_CHECK_NAMES -%type <s_int> check_names_type -%type <s_int> check_names_opt -%token T_WARN T_FAIL T_IGNORE - -/* Items used for "forward" clauses: */ -%token T_FORWARD T_FORWARDERS -%token T_ONLY T_FIRST T_IF_NO_ANSWER T_IF_NO_DOMAIN - -/* Items used for yes/no responses: */ -%type <num> yea_or_nay -%token T_YES T_TRUE T_NO T_FALSE - -/* Miscellaneous items (used in several places): */ -%type <cp> any_string - -%% -config_file: statement_list - { - if (EMPTY(current_controls)) - ns_ctl_defaults(¤t_controls); - ns_ctl_install(¤t_controls); - } - ; - -statement_list: statement - | statement_list statement - ; - -statement: include_stmt - | options_stmt L_EOS - | controls_stmt L_EOS - | logging_stmt L_EOS - | server_stmt L_EOS - | zone_stmt L_EOS - | trusted_keys_stmt L_EOS - | acl_stmt L_EOS - | key_stmt L_EOS - | L_END_INCLUDE - | error L_EOS - | error L_END_INCLUDE - ; - -include_stmt: T_INCLUDE L_QSTRING L_EOS { lexer_begin_file($2, NULL); } - ; - -/* - * Options - */ - -options_stmt: T_OPTIONS - { - if (seen_options) - parser_error(0, "cannot redefine options"); - current_options = new_options(); - } - '{' options '}' - { - if (!seen_options) - set_options(current_options, 0); - else - free_options(current_options); - current_options = NULL; - seen_options = 1; - } - ; - -options: option L_EOS - | options option L_EOS - ; - -option: /* Empty */ - | T_VERSION L_QSTRING - { - if (current_options->version != NULL) - freestr(current_options->version); - current_options->version = $2; - } - | T_DIRECTORY L_QSTRING - { - if (current_options->directory != NULL) - freestr(current_options->directory); - current_options->directory = $2; - } - | T_NAMED_XFER L_QSTRING - { - if (current_options->named_xfer != NULL) - freestr(current_options->named_xfer); - current_options->named_xfer = $2; - } - | T_PIDFILE L_QSTRING - { - if (current_options->pid_filename != NULL) - freestr(current_options->pid_filename); - current_options->pid_filename = $2; - } - | T_STATS_FILE L_QSTRING - { - if (current_options->stats_filename != NULL) - freestr(current_options->stats_filename); - current_options->stats_filename = $2; - } - | T_MEMSTATS_FILE L_QSTRING - { - if (current_options->memstats_filename != NULL) - freestr(current_options->memstats_filename); - current_options->memstats_filename = $2; - } - | T_DUMP_FILE L_QSTRING - { - if (current_options->dump_filename != NULL) - freestr(current_options->dump_filename); - current_options->dump_filename = $2; - } - | T_FAKE_IQUERY yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_FAKE_IQUERY, $2); - } - | T_RECURSION yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_NORECURSE, !$2); - } - | T_FETCH_GLUE yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_NOFETCHGLUE, !$2); - } - | T_NOTIFY yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_NONOTIFY, !$2); - } - | T_HOSTSTATS yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_HOSTSTATS, $2); - } - | T_DEALLOC_ON_EXIT yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_DEALLOC_ON_EXIT, $2); - } - | T_USE_IXFR yea_or_nay - { - set_global_boolean_option(current_options, OPTION_USE_IXFR, $2); - } - | T_MAINTAIN_IXFR_BASE yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_MAINTAIN_IXFR_BASE, $2); - } - | T_HAS_OLD_CLIENTS yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_NORFC2308_TYPE1, $2); - set_global_boolean_option(current_options, - OPTION_NONAUTH_NXDOMAIN, !$2); - } - | T_AUTH_NXDOMAIN yea_or_nay - { - set_global_boolean_option(current_options, OPTION_NONAUTH_NXDOMAIN, - !$2); - } - | T_MULTIPLE_CNAMES yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_MULTIPLE_CNAMES, $2); - } - | T_CHECK_NAMES check_names_type check_names_opt - { - current_options->check_names[$2] = (enum severity)$3; - } - | T_USE_ID_POOL yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_USE_ID_POOL, $2); - } - | T_RFC2308_TYPE1 yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_NORFC2308_TYPE1, !$2); - } - | T_LISTEN_ON maybe_port '{' address_match_list '}' - { - char port_string[10]; - symbol_value value; - - (void)sprintf(port_string, "%u", $2); - if (lookup_symbol(symtab, port_string, SYM_PORT, NULL)) - parser_error(0, - "cannot redefine listen-on for port %u", - ntohs($2)); - else { - add_listen_on(current_options, $2, $4); - value.pointer = NULL; - define_symbol(symtab, savestr(port_string, 1), - SYM_PORT, value, SYMBOL_FREE_KEY); - } - - } - | T_FORWARD forward_opt - | T_FORWARDERS - { - if (current_options->fwdtab) { - free_forwarders(current_options->fwdtab); - current_options->fwdtab = NULL; - } - } - '{' opt_forwarders_list '}' - | T_QUERY_SOURCE query_source - | T_TRANSFER_SOURCE maybe_wild_addr - { - current_options->axfr_src = $2; - } - | T_ALLOW_QUERY '{' address_match_list '}' - { - if (current_options->query_acl) { - parser_warning(0, - "options allow-query acl already set; skipping"); - free_ip_match_list($3); - } else - current_options->query_acl = $3; - } - | T_ALLOW_RECURSION '{' address_match_list '}' - { - if (current_options->recursion_acl) { - parser_warning(0, - "options allow-recursion acl already set; skipping"); - free_ip_match_list($3); - } else - current_options->recursion_acl = $3; - } - | T_ALLOW_TRANSFER '{' address_match_list '}' - { - if (current_options->transfer_acl) { - parser_warning(0, - "options allow-transfer acl already set; skipping"); - free_ip_match_list($3); - } else - current_options->transfer_acl = $3; - } - | T_SORTLIST '{' address_match_list '}' - { - if (current_options->sortlist) { - parser_warning(0, - "options sortlist already set; skipping"); - free_ip_match_list($3); - } else - current_options->sortlist = $3; - } - | T_ALSO_NOTIFY - { - if (current_options->also_notify) { - parser_warning(0, - "duplicate also-notify clause: overwriting"); - free_also_notify(current_options); - current_options->also_notify = NULL; - } - } - '{' opt_also_notify_list '}' - | T_BLACKHOLE '{' address_match_list '}' - { - if (current_options->blackhole_acl) { - parser_warning(0, - "options blackhole already set; skipping"); - free_ip_match_list($3); - } else - current_options->blackhole_acl = $3; - } - | T_TOPOLOGY '{' address_match_list '}' - { - if (current_options->topology) { - parser_warning(0, - "options topology already set; skipping"); - free_ip_match_list($3); - } else - current_options->topology = $3; - } - | size_clause - { - /* To get around the $$ = $1 default rule. */ - } - | transfer_clause - | T_TRANSFER_FORMAT transfer_format - { - current_options->transfer_format = $2; - } - | T_MAX_TRANSFER_TIME_IN L_NUMBER - { - current_options->max_transfer_time_in = $2 * 60; - } - | T_SERIAL_QUERIES L_NUMBER - { - current_options->serial_queries = $2; - } - | T_CLEAN_INTERVAL L_NUMBER - { - current_options->clean_interval = $2 * 60; - } - | T_INTERFACE_INTERVAL L_NUMBER - { - current_options->interface_interval = $2 * 60; - } - | T_STATS_INTERVAL L_NUMBER - { - current_options->stats_interval = $2 * 60; - } - | T_MAX_LOG_SIZE_IXFR L_NUMBER - { - current_options->max_log_size_ixfr = $2; - } - | T_MAX_NCACHE_TTL L_NUMBER - { - current_options->max_ncache_ttl = $2; - } - | T_LAME_TTL L_NUMBER - { - current_options->lame_ttl = $2; - } - | T_HEARTBEAT L_NUMBER - { - current_options->heartbeat_interval = $2 * 60; - } - | T_DIALUP yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_NODIALUP, !$2); - } - | T_RRSET_ORDER '{' rrset_ordering_list '}' - { - if (current_options->ordering) - free_rrset_order_list(current_options->ordering); - current_options->ordering = $3; - } - | T_TREAT_CR_AS_SPACE yea_or_nay - { - set_global_boolean_option(current_options, - OPTION_TREAT_CR_AS_SPACE, $2); - } - | T_MIN_ROOTS L_NUMBER - { - if ($2 >= 1) - current_options->minroots = $2; - } - | error - ; - -/* - * Controls. - */ -controls_stmt: T_CONTROLS '{' controls '}' - ; - -controls: control L_EOS - | controls control L_EOS - ; - -control: /* Empty */ - | T_INET maybe_wild_addr T_PORT in_port - T_ALLOW '{' address_match_list '}' - { - ns_ctl_add(¤t_controls, ns_ctl_new_inet($2, $4, $7)); - } - | T_UNIX L_QSTRING T_PERM L_NUMBER T_OWNER L_NUMBER T_GROUP L_NUMBER - { -#ifndef NO_SOCKADDR_UN - ns_ctl_add(¤t_controls, ns_ctl_new_unix($2, $4, $6, $8)); -#endif - } - | error - ; - -rrset_ordering_list: rrset_ordering_element L_EOS - { - rrset_order_list rol; - - rol = new_rrset_order_list(); - if ($1 != NULL) { - add_to_rrset_order_list(rol, $1); - } - - $$ = rol; - } - | rrset_ordering_list rrset_ordering_element L_EOS - { - if ($2 != NULL) { - add_to_rrset_order_list($1, $2); - } - $$ = $1; - } - ; - -ordering_class: /* nothing */ - { - $$ = C_ANY; - } - | T_CLASS any_string - { - symbol_value value; - - if (lookup_symbol(constants, $2, SYM_CLASS, &value)) - $$ = value.integer; - else { - parser_error(0, "unknown class '%s'; using ANY", $2); - $$ = C_ANY; - } - freestr($2); - } - ; - -ordering_type: /* nothing */ - { - $$ = ns_t_any; - } - | T_TYPE any_string - { - int success; - - if (strcmp($2, "*") == 0) { - $$ = ns_t_any; - } else { - $$ = __sym_ston(__p_type_syms, $2, &success); - if (success == 0) { - $$ = ns_t_any; - parser_error(0, - "unknown type '%s'; assuming ANY", - $2); - } - } - freestr($2); - } - -ordering_name: /* nothing */ - { - $$ = savestr("*", 1); - } - | T_NAME L_QSTRING - { - if (strcmp(".",$2) == 0 || strcmp("*.",$2) == 0) { - $$ = savestr("*", 1); - freestr($2); - } else { - $$ = $2 ; - } - /* XXX Should do any more name validation here? */ - } - - -rrset_ordering_element: ordering_class ordering_type ordering_name T_ORDER L_STRING - { - enum ordering o; - - if (strlen($5) == 0) { - parser_error(0, "null order name"); - $$ = NULL ; - } else { - o = lookup_ordering($5); - if (o == unknown_order) { - o = (enum ordering)DEFAULT_ORDERING; - parser_error(0, - "invalid order name '%s'; using %s", - $5, p_order(o)); - } - - freestr($5); - - $$ = new_rrset_order_element($1, $2, $3, o); - } - } - - -transfer_format: T_ONE_ANSWER - { - $$ = axfr_one_answer; - } - | T_MANY_ANSWERS - { - $$ = axfr_many_answers; - } - ; - -maybe_wild_addr: L_IPADDR { $$ = $1; } - | '*' { $$.s_addr = htonl(INADDR_ANY); } - ; - -maybe_wild_port: in_port { $$ = $1; } - | '*' { $$ = htons(0); } - ; - -query_source_address: T_ADDRESS maybe_wild_addr - { - current_options->query_source.sin_addr = $2; - } - ; - -query_source_port: T_PORT maybe_wild_port - { - current_options->query_source.sin_port = $2; - } - ; - -query_source: query_source_address - | query_source_port - | query_source_address query_source_port - | query_source_port query_source_address - ; - -maybe_port: /* nothing */ { $$ = htons(NS_DEFAULTPORT); } - | T_PORT in_port { $$ = $2; } - ; - -maybe_zero_port: /* nothing */ { $$ = htons(0); } - | T_PORT in_port { $$ = $2; } - ; - - -yea_or_nay: T_YES - { - $$ = 1; - } - | T_TRUE - { - $$ = 1; - } - | T_NO - { - $$ = 0; - } - | T_FALSE - { - $$ = 0; - } - | L_NUMBER - { - if ($1 == 1 || $1 == 0) { - $$ = $1; - } else { - parser_warning(0, - "number should be 0 or 1; assuming 1"); - $$ = 1; - } - } - ; - -check_names_type: T_MASTER - { - $$ = primary_trans; - } - | T_SLAVE - { - $$ = secondary_trans; - } - | T_RESPONSE - { - $$ = response_trans; - } - ; - -check_names_opt: T_WARN - { - $$ = warn; - } - | T_FAIL - { - $$ = fail; - } - | T_IGNORE - { - $$ = ignore; - } - ; - -forward_opt: T_ONLY - { - set_global_boolean_option(current_options, - OPTION_FORWARD_ONLY, 1); - } - | T_FIRST - { - set_global_boolean_option(current_options, - OPTION_FORWARD_ONLY, 0); - } - | T_IF_NO_ANSWER - { - parser_warning(0, "forward if-no-answer is unimplemented"); - } - | T_IF_NO_DOMAIN - { - parser_warning(0, "forward if-no-domain is unimplemented"); - } - ; - -size_clause: T_DATASIZE size_spec - { - current_options->data_size = $2; - } - | T_STACKSIZE size_spec - { - current_options->stack_size = $2; - } - | T_CORESIZE size_spec - { - current_options->core_size = $2; - } - | T_FILES size_spec - { - current_options->files = $2; - } - ; - -size_spec: any_string - { - u_long result; - - if (unit_to_ulong($1, &result)) - $$ = result; - else { - parser_error(0, "invalid unit string '%s'", $1); - /* 0 means "use default" */ - $$ = 0; - } - freestr($1); - } - | L_NUMBER - { - $$ = (u_long)$1; - } - | T_DEFAULT - { - $$ = 0; - } - | T_UNLIMITED - { - $$ = ULONG_MAX; - } - ; - -transfer_clause: T_TRANSFERS_IN L_NUMBER - { - current_options->transfers_in = (u_long) $2; - } - | T_TRANSFERS_OUT L_NUMBER - { - current_options->transfers_out = (u_long) $2; - } - | T_TRANSFERS_PER_NS L_NUMBER - { - current_options->transfers_per_ns = (u_long) $2; - } - ; - -opt_forwarders_list: /* nothing */ - | forwarders_in_addr_list - ; - -forwarders_in_addr_list: forwarders_in_addr L_EOS - { - /* nothing */ - } - | forwarders_in_addr_list forwarders_in_addr L_EOS - { - /* nothing */ - } - ; - -forwarders_in_addr: L_IPADDR - { - add_global_forwarder(current_options, $1); - } - ; - -opt_also_notify_list: /* nothing */ - | also_notify_in_addr_list - ; - -also_notify_in_addr_list: also_notify_in_addr L_EOS - { - /* nothing */ - } - | also_notify_in_addr_list also_notify_in_addr L_EOS - { - /* nothing */ - } - ; - -also_notify_in_addr: L_IPADDR - { - add_global_also_notify(current_options, $1); - } - ; - -/* - * Logging - */ - -logging_stmt: T_LOGGING - { - current_logging = begin_logging(); - } - '{' logging_opts_list '}' - { - end_logging(current_logging, 1); - current_logging = NULL; - } - ; - -logging_opts_list: logging_opt L_EOS - | logging_opts_list logging_opt L_EOS - | error - ; - -logging_opt: T_CATEGORY category - { - current_category = $2; - } - '{' channel_list '}' - | T_CHANNEL channel_name - { - chan_type = log_null; - chan_flags = 0; - chan_level = log_info; - } - '{' channel_opt_list '}' - { - log_channel current_channel = NULL; - - if (lookup_channel($2) != NULL) { - parser_error(0, "can't redefine channel '%s'", $2); - freestr($2); - } else { - switch (chan_type) { - case log_file: - current_channel = - log_new_file_channel(chan_flags, - chan_level, - chan_name, NULL, - chan_versions, - chan_max_size); - log_set_file_owner(current_channel, - user_id, group_id); - freestr(chan_name); - chan_name = NULL; - break; - case log_syslog: - current_channel = - log_new_syslog_channel(chan_flags, - chan_level, - chan_facility); - break; - case log_null: - current_channel = log_new_null_channel(); - break; - default: - ns_panic(ns_log_parser, 1, - "unknown channel type: %d", - chan_type); - } - if (current_channel == NULL) - ns_panic(ns_log_parser, 0, - "couldn't create channel"); - define_channel($2, current_channel); - } - } - ; - -channel_severity: any_string - { - symbol_value value; - - if (lookup_symbol(constants, $1, SYM_LOGGING, &value)) { - chan_level = value.integer; - } else { - parser_error(0, "unknown severity '%s'", $1); - chan_level = log_debug(99); - } - freestr($1); - } - | T_DEBUG - { - chan_level = log_debug(1); - } - | T_DEBUG L_NUMBER - { - chan_level = $2; - } - | T_DYNAMIC - { - chan_level = 0; - chan_flags |= LOG_USE_CONTEXT_LEVEL|LOG_REQUIRE_DEBUG; - } - ; - -version_modifier: T_VERSIONS L_NUMBER - { - chan_versions = $2; - } - | T_VERSIONS T_UNLIMITED - { - chan_versions = LOG_MAX_VERSIONS; - } - ; - -size_modifier: T_SIZE size_spec - { - chan_max_size = $2; - } - ; - -maybe_file_modifiers: /* nothing */ - { - chan_versions = 0; - chan_max_size = ULONG_MAX; - } - | version_modifier - { - chan_max_size = ULONG_MAX; - } - | size_modifier - { - chan_versions = 0; - } - | version_modifier size_modifier - | size_modifier version_modifier - ; - -channel_file: T_FILE L_QSTRING maybe_file_modifiers - { - chan_flags |= LOG_CLOSE_STREAM; - chan_type = log_file; - chan_name = $2; - } - ; - - -facility_name: any_string { $$ = $1; } - | T_SYSLOG { $$ = savestr("syslog", 1); } - ; - -maybe_syslog_facility: /* nothing */ { $$ = LOG_DAEMON; } - | facility_name - { - symbol_value value; - - if (lookup_symbol(constants, $1, SYM_SYSLOG, &value)) { - $$ = value.integer; - } else { - parser_error(0, "unknown facility '%s'", $1); - $$ = LOG_DAEMON; - } - freestr($1); - } - ; - -channel_syslog: T_SYSLOG maybe_syslog_facility - { - chan_type = log_syslog; - chan_facility = $2; - } - ; - -channel_opt: channel_file { /* nothing to do */ } - | channel_syslog { /* nothing to do */ } - | T_NULL_OUTPUT - { - chan_type = log_null; - } - | T_SEVERITY channel_severity { /* nothing to do */ } - | T_PRINT_TIME yea_or_nay - { - if ($2) - chan_flags |= LOG_TIMESTAMP; - else - chan_flags &= ~LOG_TIMESTAMP; - } - | T_PRINT_CATEGORY yea_or_nay - { - if ($2) - chan_flags |= LOG_PRINT_CATEGORY; - else - chan_flags &= ~LOG_PRINT_CATEGORY; - } - | T_PRINT_SEVERITY yea_or_nay - { - if ($2) - chan_flags |= LOG_PRINT_LEVEL; - else - chan_flags &= ~LOG_PRINT_LEVEL; - } - ; - -channel_opt_list: channel_opt L_EOS - | channel_opt_list channel_opt L_EOS - | error - ; - -channel_name: any_string - | T_NULL_OUTPUT { $$ = savestr("null", 1); } - ; - -channel: channel_name - { - log_channel channel; - symbol_value value; - - if (current_category >= 0) { - channel = lookup_channel($1); - if (channel != NULL) { - add_log_channel(current_logging, - current_category, channel); - } else - parser_error(0, "unknown channel '%s'", $1); - } - freestr($1); - } - ; - -channel_list: channel L_EOS - | channel_list channel L_EOS - | error - ; - -category_name: any_string - | T_DEFAULT { $$ = savestr("default", 1); } - | T_NOTIFY { $$ = savestr("notify", 1); } - ; - -category: category_name - { - symbol_value value; - - if (lookup_symbol(constants, $1, SYM_CATEGORY, &value)) - $$ = value.integer; - else { - parser_error(0, "invalid logging category '%s'", - $1); - $$ = -1; - } - freestr($1); - } - ; - -/* - * Server Information - */ - -server_stmt: T_SERVER L_IPADDR - { - const char *ip_printable; - symbol_value value; - - ip_printable = inet_ntoa($2); - value.pointer = NULL; - if (lookup_symbol(symtab, ip_printable, SYM_SERVER, NULL)) - seen_server = 1; - else - seen_server = 0; - if (seen_server) - parser_error(0, "cannot redefine server '%s'", - ip_printable); - else - define_symbol(symtab, savestr(ip_printable, 1), - SYM_SERVER, value, - SYMBOL_FREE_KEY); - current_server = begin_server($2); - } - '{' server_info_list '}' - { - end_server(current_server, !seen_server); - } - ; - -server_info_list: server_info L_EOS - | server_info_list server_info L_EOS - ; - -server_info: T_BOGUS yea_or_nay - { - set_server_option(current_server, SERVER_INFO_BOGUS, $2); - } - | T_SUPPORT_IXFR yea_or_nay - { - set_server_option(current_server, SERVER_INFO_SUPPORT_IXFR, $2); - } - | T_TRANSFERS L_NUMBER - { - set_server_transfers(current_server, (int)$2); - } - | T_TRANSFER_FORMAT transfer_format - { - set_server_transfer_format(current_server, $2); - } - | T_KEYS '{' key_list '}' - | error - ; - -/* - * Address Matching - */ - -address_match_list: address_match_element L_EOS - { - ip_match_list iml; - - iml = new_ip_match_list(); - if ($1 != NULL) - add_to_ip_match_list(iml, $1); - $$ = iml; - } - | address_match_list address_match_element L_EOS - { - if ($2 != NULL) - add_to_ip_match_list($1, $2); - $$ = $1; - } - ; - -address_match_element: address_match_simple - | '!' address_match_simple - { - if ($2 != NULL) - ip_match_negate($2); - $$ = $2; - } - | T_SEC_KEY L_STRING - { - char *key_name; - struct dst_key *dst_key; - - key_name = canonical_name($2); - if (key_name == NULL) { - parser_error(0, "can't make key name '%s' canonical", - $2); - key_name = savestr("__bad_key__", 1); - } - dst_key = find_key(key_name, NULL); - if (dst_key == NULL) { - parser_error(0, "key \"%s\" not found", key_name); - $$ = NULL; - } - else - $$ = new_ip_match_key(dst_key); - } - ; - -address_match_simple: L_IPADDR - { - $$ = new_ip_match_pattern($1, 32); - } - | L_IPADDR '/' L_NUMBER - { - if ($3 < 0 || $3 > 32) { - parser_error(0, "mask bits out of range; skipping"); - $$ = NULL; - } else { - $$ = new_ip_match_pattern($1, $3); - if ($$ == NULL) - parser_error(0, - "address/mask mismatch; skipping"); - } - } - | L_NUMBER '/' L_NUMBER - { - struct in_addr ia; - - if ($1 > 255) { - parser_error(0, "address out of range; skipping"); - $$ = NULL; - } else { - if ($3 < 0 || $3 > 32) { - parser_error(0, - "mask bits out of range; skipping"); - $$ = NULL; - } else { - ia.s_addr = htonl(($1 & 0xff) << 24); - $$ = new_ip_match_pattern(ia, $3); - if ($$ == NULL) - parser_error(0, - "address/mask mismatch; skipping"); - } - } - } - | address_name - | '{' address_match_list '}' - { - char name[256]; - - /* - * We want to be able to clean up this iml later so - * we give it a name and treat it like any other acl. - */ - sprintf(name, "__internal_%p", $2); - define_acl(savestr(name, 1), $2); - $$ = new_ip_match_indirect($2); - } - ; - -address_name: any_string - { - ip_match_list iml; - - iml = lookup_acl($1); - if (iml == NULL) { - parser_error(0, "unknown ACL '%s'", $1); - $$ = NULL; - } else - $$ = new_ip_match_indirect(iml); - freestr($1); - } - ; - -/* - * Keys - */ - -key_ref: any_string - { - struct dst_key *dst_key; - char *key_name; - - key_name = canonical_name($1); - if (key_name == NULL) { - parser_error(0, "can't make key name '%s' canonical", - $1); - $$ = NULL; - } else { - dst_key = lookup_key(key_name); - if (dst_key == NULL) { - parser_error(0, "unknown key '%s'", key_name); - $$ = NULL; - } else - $$ = dst_key; - freestr(key_name); - } - freestr($1); - } - ; - -key_list_element: key_ref - { - if ($1 == NULL) - parser_error(0, "empty key not added to server list "); - else - add_server_key_info(current_server, $1); - } - ; - -key_list: key_list_element L_EOS - | key_list key_list_element L_EOS - | error - ; - -key_stmt: T_SEC_KEY - { - current_algorithm = NULL; - current_secret = NULL; - } - any_string '{' key_definition '}' - { - struct dst_key *dst_key; - char *key_name; - - key_name = canonical_name($3); - if (key_name == NULL) { - parser_error(0, "can't make key name '%s' canonical", - $3); - } else if (lookup_key(key_name) != NULL) { - parser_error(0, "can't redefine key '%s'", key_name); - freestr(key_name); - } else { - if (current_algorithm == NULL || - current_secret == NULL) { - parser_error(0, "skipping bad key '%s'", - key_name); - freestr(key_name); - } else { - dst_key = new_key_info(key_name, - current_algorithm, - current_secret); - if (dst_key != NULL) { - define_key(key_name, dst_key); - if (secretkey_info == NULL) - secretkey_info = - new_key_info_list(); - add_to_key_info_list(secretkey_info, - dst_key); - } - } - } - freestr($3); - } - ; - -key_definition: algorithm_id secret - { - current_algorithm = $1; - current_secret = $2; - } - | secret algorithm_id - { - current_algorithm = $2; - current_secret = $1; - } - | error - { - current_algorithm = NULL; - current_secret = NULL; - } - ; - -algorithm_id: T_ALGID any_string L_EOS { $$ = $2; } - ; - -secret: T_SECRET any_string L_EOS { $$ = $2; } - ; - -/* - * ACLs - */ - -acl_stmt: T_ACL any_string '{' address_match_list '}' - { - if (lookup_acl($2) != NULL) { - parser_error(0, "can't redefine ACL '%s'", $2); - freestr($2); - } else - define_acl($2, $4); - } - ; - -/* - * Zones - */ - -zone_stmt: T_ZONE L_QSTRING optional_class - { - int sym_type; - symbol_value value; - char *zone_name; - - if (!seen_options) - parser_error(0, - "no options statement before first zone; using previous/default"); - sym_type = SYM_ZONE | ($3 & 0xffff); - value.pointer = NULL; - zone_name = canonical_name($2); - if (zone_name == NULL) { - parser_error(0, "can't make zone name '%s' canonical", - $2); - should_install = 0; - zone_name = savestr("__bad_zone__", 1); - } else { - if (lookup_symbol(symtab, zone_name, sym_type, NULL)) { - should_install = 0; - parser_error(0, - "cannot redefine zone '%s' class %s", - *zone_name ? zone_name : ".", - p_class($3)); - } else { - should_install = 1; - define_symbol(symtab, savestr(zone_name, 1), - sym_type, value, - SYMBOL_FREE_KEY); - } - } - freestr($2); - current_zone = begin_zone(zone_name, $3); - } - optional_zone_options_list - { - end_zone(current_zone, should_install); - } - ; - -optional_zone_options_list: /* Empty */ - | '{' zone_option_list '}' - ; - -optional_class: /* Empty */ - { - $$ = C_IN; - } - | any_string - { - symbol_value value; - - if (lookup_symbol(constants, $1, SYM_CLASS, &value)) - $$ = value.integer; - else { - /* the zone validator will give the error */ - $$ = C_NONE; - } - freestr($1); - } - ; - -zone_type: T_MASTER - { - $$ = Z_MASTER; - } - | T_SLAVE - { - $$ = Z_SLAVE; - } - | T_HINT - { - $$ = Z_HINT; - } - | T_STUB - { - $$ = Z_STUB; - } - | T_FORWARD - { - $$ = Z_FORWARD; - } - ; - -zone_option_list: zone_option L_EOS - | zone_option_list zone_option L_EOS - ; - -zone_option: T_TYPE zone_type - { - if (!set_zone_type(current_zone, $2)) - parser_warning(0, "zone type already set; skipping"); - } - | T_FILE L_QSTRING - { - if (!set_zone_filename(current_zone, $2)) - parser_warning(0, - "zone filename already set; skipping"); - } - | T_FILE_IXFR L_QSTRING - { - if (!set_zone_ixfr_file(current_zone, $2)) - parser_warning(0, - "zone ixfr data base already set; skipping"); - } - | T_IXFR_TMP L_QSTRING - { - if (!set_zone_ixfr_tmp(current_zone, $2)) - parser_warning(0, - "zone ixfr temp filename already set; skipping"); - } - | T_MASTERS maybe_zero_port '{' master_in_addr_list '}' - { - set_zone_master_port(current_zone, $2); - } - | T_TRANSFER_SOURCE maybe_wild_addr - { - set_zone_transfer_source(current_zone, $2); - } - | T_CHECK_NAMES check_names_opt - { - if (!set_zone_checknames(current_zone, (enum severity)$2)) - parser_warning(0, - "zone checknames already set; skipping"); - } - | T_ALLOW_UPDATE '{' address_match_list '}' - { - if (!set_zone_update_acl(current_zone, $3)) - parser_warning(0, - "zone update acl already set; skipping"); - } - | T_ALLOW_QUERY '{' address_match_list '}' - { - if (!set_zone_query_acl(current_zone, $3)) - parser_warning(0, - "zone query acl already set; skipping"); - } - | T_ALLOW_TRANSFER '{' address_match_list '}' - { - if (!set_zone_transfer_acl(current_zone, $3)) - parser_warning(0, - "zone transfer acl already set; skipping"); - } - | T_FORWARD zone_forward_opt - | T_FORWARDERS - { - struct zoneinfo *zp = current_zone.opaque; - if (zp->z_fwdtab) { - free_forwarders(zp->z_fwdtab); - zp->z_fwdtab = NULL; - } - - } - '{' opt_zone_forwarders_list '}' - | T_MAX_TRANSFER_TIME_IN L_NUMBER - { - if (!set_zone_transfer_time_in(current_zone, $2*60)) - parser_warning(0, - "zone max transfer time (in) already set; skipping"); - } - | T_MAX_LOG_SIZE_IXFR L_NUMBER - { - set_zone_max_log_size_ixfr(current_zone, $2); - } - | T_NOTIFY yea_or_nay - { - set_zone_notify(current_zone, $2); - } - | T_MAINTAIN_IXFR_BASE yea_or_nay - { - set_zone_maintain_ixfr_base(current_zone, $2); - } - | T_PUBKEY L_NUMBER L_NUMBER L_NUMBER L_QSTRING - { - /* flags proto alg key */ - set_zone_pubkey(current_zone, $2, $3, $4, $5); - } - | T_PUBKEY L_STRING L_NUMBER L_NUMBER L_QSTRING - { - /* flags proto alg key */ - char *endp; - int flags = (int) strtol($2, &endp, 0); - if (*endp != '\0') - ns_panic(ns_log_parser, 1, - "Invalid flags string: %s", $2); - set_zone_pubkey(current_zone, flags, $3, $4, $5); - - } - | T_ALSO_NOTIFY '{' opt_notify_in_addr_list '}' - | T_DIALUP yea_or_nay - { - set_zone_dialup(current_zone, $2); - } - | error - ; - -master_in_addr_list: master_in_addr L_EOS - { - /* nothing */ - } - | master_in_addr_list master_in_addr L_EOS - { - /* nothing */ - } - ; - -master_in_addr: L_IPADDR - { - add_zone_master(current_zone, $1); - } - ; - -opt_notify_in_addr_list: /* nothing */ - | notify_in_addr_list - ; - -notify_in_addr_list: notify_in_addr L_EOS - { - /* nothing */ - } - | notify_in_addr_list notify_in_addr L_EOS - { - /* nothing */ - } - ; - -notify_in_addr: L_IPADDR - { - add_zone_notify(current_zone, $1); - } - ; - -zone_forward_opt: T_ONLY - { - set_zone_boolean_option(current_zone, OPTION_FORWARD_ONLY, 1); - } - | T_FIRST - { - set_zone_boolean_option(current_zone, OPTION_FORWARD_ONLY, 0); - } - ; - -opt_zone_forwarders_list: /* nothing */ - { - set_zone_forward(current_zone); - } - | zone_forwarders_in_addr_list - ; - -zone_forwarders_in_addr_list: zone_forwarders_in_addr L_EOS - { - /* nothing */ - } - | zone_forwarders_in_addr_list zone_forwarders_in_addr L_EOS - { - /* nothing */ - } - ; - -zone_forwarders_in_addr: L_IPADDR - { - add_zone_forwarder(current_zone, $1); - } - ; - -/* - * Trusted Key statement - */ - -trusted_keys_stmt: T_TRUSTED_KEYS '{' trusted_keys_list '}' - { - } - ; -trusted_keys_list: trusted_key L_EOS - { - /* nothing */ - } - | trusted_keys_list trusted_key L_EOS - { - /* nothing */ - } - ; -trusted_key: L_STRING L_NUMBER L_NUMBER L_NUMBER L_QSTRING - { - /* name flags proto alg key */ - set_trusted_key($1, $2, $3, $4, $5); - } - | L_STRING L_STRING L_NUMBER L_NUMBER L_QSTRING - { - /* name flags proto alg key */ - char *endp; - int flags = (int) strtol($2, &endp, 0); - if (*endp != '\0') - ns_panic(ns_log_parser, 1, - "Invalid flags string: %s", $2); - set_trusted_key($1, flags, $3, $4, $5); - } - ; - -/* - * Misc. - */ - -in_port: L_NUMBER - { - if ($1 < 0 || $1 > 65535) { - parser_warning(0, - "invalid IP port number '%d'; setting port to 0", - $1); - $1 = 0; - } else - $$ = htons($1); - } - ; - -any_string: L_STRING - | L_QSTRING - ; - -%% - -static char * -canonical_name(char *name) { - char canonical[MAXDNAME]; - - if (strlen(name) >= MAXDNAME) - return (NULL); - strcpy(canonical, name); - if (makename(canonical, ".", sizeof canonical) < 0) - return (NULL); - return (savestr(canonical, 0)); -} - -static void -init_acls() { - ip_match_element ime; - ip_match_list iml; - struct in_addr address; - - /* Create the predefined ACLs */ - - address.s_addr = 0U; - - /* ACL "any" */ - ime = new_ip_match_pattern(address, 0); - iml = new_ip_match_list(); - add_to_ip_match_list(iml, ime); - define_acl(savestr("any", 1), iml); - - /* ACL "none" */ - ime = new_ip_match_pattern(address, 0); - ip_match_negate(ime); - iml = new_ip_match_list(); - add_to_ip_match_list(iml, ime); - define_acl(savestr("none", 1), iml); - - /* ACL "localhost" */ - ime = new_ip_match_localhost(); - iml = new_ip_match_list(); - add_to_ip_match_list(iml, ime); - define_acl(savestr("localhost", 1), iml); - - /* ACL "localnets" */ - ime = new_ip_match_localnets(); - iml = new_ip_match_list(); - add_to_ip_match_list(iml, ime); - define_acl(savestr("localnets", 1), iml); -} - -static void -free_sym_value(int type, void *value) { - ns_debug(ns_log_parser, 99, "free_sym_value: type %06x value %p", - type, value); - type &= ~0xffff; - switch (type) { - case SYM_ACL: - free_ip_match_list(value); - break; - case SYM_KEY: - free_key_info(value); - break; - default: - ns_panic(ns_log_parser, 1, - "unhandled case in free_sym_value()"); - /* NOTREACHED */ - break; - } -} - -static log_channel -lookup_channel(char *name) { - symbol_value value; - - if (lookup_symbol(symtab, name, SYM_CHANNEL, &value)) - return ((log_channel)(value.pointer)); - return (NULL); -} - -static void -define_channel(char *name, log_channel channel) { - symbol_value value; - - value.pointer = channel; - define_symbol(symtab, name, SYM_CHANNEL, value, SYMBOL_FREE_KEY); -} - -static void -define_builtin_channels() { - define_channel(savestr("default_syslog", 1), syslog_channel); - define_channel(savestr("default_debug", 1), debug_channel); - define_channel(savestr("default_stderr", 1), stderr_channel); - define_channel(savestr("null", 1), null_channel); -} - -static void -parser_setup() { - seen_options = 0; - seen_topology = 0; - symtab = new_symbol_table(SYMBOL_TABLE_SIZE, NULL); - if (authtab != NULL) - free_symbol_table(authtab); - authtab = new_symbol_table(AUTH_TABLE_SIZE, free_sym_value); - init_acls(); - define_builtin_channels(); - INIT_LIST(current_controls); -} - -static void -parser_cleanup() { - if (symtab != NULL) - free_symbol_table(symtab); - symtab = NULL; - /* - * We don't clean up authtab here because the ip_match_lists are in - * use. - */ -} - -/* - * Public Interface - */ - -ip_match_list -lookup_acl(char *name) { - symbol_value value; - - if (lookup_symbol(authtab, name, SYM_ACL, &value)) - return ((ip_match_list)(value.pointer)); - return (NULL); -} - -void -define_acl(char *name, ip_match_list iml) { - symbol_value value; - - INSIST(name != NULL); - INSIST(iml != NULL); - - value.pointer = iml; - define_symbol(authtab, name, SYM_ACL, value, - SYMBOL_FREE_KEY|SYMBOL_FREE_VALUE); - ns_debug(ns_log_parser, 7, "acl %s", name); - dprint_ip_match_list(ns_log_parser, iml, 2, "allow ", "deny "); -} - -struct dst_key * -lookup_key(char *name) { - symbol_value value; - - if (lookup_symbol(authtab, name, SYM_KEY, &value)) - return ((struct dst_key *)(value.pointer)); - return (NULL); -} - -void -define_key(char *name, struct dst_key *dst_key) { - symbol_value value; - - INSIST(name != NULL); - INSIST(dst_key != NULL); - - value.pointer = dst_key; - define_symbol(authtab, name, SYM_KEY, value, SYMBOL_FREE_VALUE); - dprint_key_info(dst_key); -} - -void -parse_configuration(const char *filename) { - FILE *config_stream; - - config_stream = fopen(filename, "r"); - if (config_stream == NULL) - ns_panic(ns_log_parser, 0, "can't open '%s'", filename); - - lexer_setup(); - parser_setup(); - lexer_begin_file(filename, config_stream); - (void)yyparse(); - lexer_end_file(); - parser_cleanup(); -} - -void -parser_initialize(void) { - lexer_initialize(); -} - -void -parser_shutdown(void) { - if (authtab != NULL) - free_symbol_table(authtab); - lexer_shutdown(); -} diff --git a/contrib/bind/bin/named/ns_parseutil.c b/contrib/bind/bin/named/ns_parseutil.c deleted file mode 100644 index 4a26337d95f92..0000000000000 --- a/contrib/bind/bin/named/ns_parseutil.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* Global C stuff goes here. */ - - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include "port_after.h" - -#include "named.h" -#include "ns_parseutil.h" - - -/* - * Symbol Table - */ - -symbol_table -new_symbol_table(int size_guess, free_function free_value) { - symbol_table st; - - st = (symbol_table)memget(sizeof (struct symbol_table)); - if (st == NULL) - panic("memget failed in new_symbol_table()", NULL); - st->table = (symbol_entry *)memget(size_guess * sizeof *st->table); - if (st->table == NULL) - panic("memget failed in new_symbol_table()", NULL); - memset(st->table, 0, size_guess * sizeof (symbol_entry)); - st->size = size_guess; /* size_guess should be prime */ - st->free_value = free_value; - return (st); -} - -void -free_symbol(symbol_table st, symbol_entry ste) { - if (ste->flags & SYMBOL_FREE_KEY) - freestr(ste->key); - if (ste->flags & SYMBOL_FREE_VALUE) - (st->free_value)(ste->type, ste->value.pointer); -} - -void -free_symbol_table(symbol_table st) { - int i; - symbol_entry ste, ste_next; - - for (i = 0; i < st->size; i++) { - for (ste = st->table[i]; ste != NULL; ste = ste_next) { - ste_next = ste->next; - free_symbol(st, ste); - memput(ste, sizeof *ste); - } - } - memput(st->table, st->size * sizeof (symbol_entry)); - memput(st, sizeof *st); -} - -void -dprint_symbol_table(int level, symbol_table st) { - int i; - symbol_entry ste; - - for (i = 0; i < st->size; i++) { - for (ste = st->table[i]; ste != NULL; ste = ste->next) - ns_debug(ns_log_parser, level, - "%7d: (%s: %d %p/%d %04x) ", - i, ste->key, ste->type, ste->value.pointer, - ste->value.integer, ste->flags); - } -} - -/* - * P. J. Weinberger's hash function, adapted from p. 436 of - * _Compilers: Principles, Techniques, and Tools_, Aho, Sethi - * and Ullman, Addison-Wesley, 1986, ISBN 0-201-10088-6. - */ -static int -symbol_hash(const char *key, int prime) { - const char *s; - unsigned int h = 0; - unsigned int g; - int c; - - for (s = key; *s != '\0'; s++) { - c = *s; - if (isascii(c) && isupper(c)) - c = tolower(c); - h = ( h << 4 ) + c; - if ((g = ( h & 0xf0000000 )) != 0) { - h = h ^ (g >> 24); - h = h ^ g; - } - } - return (h % prime); -} - -int -lookup_symbol(symbol_table st, const char *key, int type, - symbol_value *value) { - int hash; - symbol_entry ste; - - hash = symbol_hash(key, st->size); - for (ste = st->table[hash]; ste != NULL; ste = ste->next) - if ((type == 0 || ste->type == type) && - strcasecmp(ste->key, key) == 0) - break; - if (ste != NULL) { - if (value != NULL) - *value = ste->value; - return (1); - } - return (0); -} - -void -define_symbol(symbol_table st, char *key, int type, symbol_value value, - unsigned int flags) { - int hash; - symbol_entry ste; - - hash = symbol_hash(key, st->size); - for (ste = st->table[hash]; ste != NULL; ste = ste->next) - if ((type == 0 || ste->type == type) && - strcasecmp(ste->key, key) == 0) - break; - if (ste == NULL) { - ste = (symbol_entry)memget(sizeof *ste); - if (ste == NULL) - panic("memget failed in define_symbol()", NULL); - ste->key = key; - ste->type = type; - ste->value = value; - ste->flags = flags; - ste->next = st->table[hash]; - st->table[hash] = ste; - } else { - ns_debug(ns_log_parser, 7, "redefined symbol %s type %d", - key, type); - free_symbol(st, ste); - ste->key = key; - ste->value = value; - ste->flags = flags; - } -} - -void -undefine_symbol(symbol_table st, char *key, int type) { - int hash; - symbol_entry prev_ste, ste; - - hash = symbol_hash(key, st->size); - for (prev_ste = NULL, ste = st->table[hash]; - ste != NULL; - prev_ste = ste, ste = ste->next) - if ((type == 0 || ste->type == type) && - strcasecmp(ste->key, key) == 0) - break; - if (ste != NULL) { - free_symbol(st, ste); - if (prev_ste != NULL) - prev_ste->next = ste->next; - else - st->table[hash] = ste->next; - memput(ste, sizeof *ste); - } -} - -/* - * Conversion Routines - */ - -int -unit_to_ulong(char *in, u_long *out) { - int c, units_done = 0; - u_long result = 0L; - - INSIST(in != NULL); - - for (; (c = *in) != '\0'; in++) { - if (units_done) - return (0); - if (isdigit(c)) { - result *= 10; - result += (c - '0'); - } else { - switch (c) { - case 'k': - case 'K': - result *= 1024; - units_done = 1; - break; - case 'm': - case 'M': - result *= (1024*1024); - units_done = 1; - break; - case 'g': - case 'G': - result *= (1024*1024*1024); - units_done = 1; - break; - default: - return (0); - } - } - } - - *out = result; - return (1); -} diff --git a/contrib/bind/bin/named/ns_parseutil.h b/contrib/bind/bin/named/ns_parseutil.h deleted file mode 100644 index 77fc878881b54..0000000000000 --- a/contrib/bind/bin/named/ns_parseutil.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef _NS_PARSEUTIL_H -#define _NS_PARSEUTIL_H - -/* - * Symbol Table - */ - -#define SYMBOL_FREE_KEY 0x01 -#define SYMBOL_FREE_VALUE 0x02 - -typedef union symbol_value { - void *pointer; - int integer; -} symbol_value; - -typedef void (*free_function)(int, void *); - -typedef struct symbol_entry { - char *key; - int type; - symbol_value value; - unsigned int flags; - struct symbol_entry *next; -} *symbol_entry; - -typedef struct symbol_table { - int size; - symbol_entry *table; - free_function free_value; -} *symbol_table; - -symbol_table new_symbol_table(int, free_function); -void free_symbol(symbol_table, symbol_entry); -void free_symbol_table(symbol_table); -void dprint_symbol_table(int, symbol_table); -int lookup_symbol(symbol_table, const char *, int, - symbol_value *); -void define_symbol(symbol_table, char *, int, symbol_value, - unsigned int); -void undefine_symbol(symbol_table, char *, int type); - -/* - * Conversion Routines - */ - -int unit_to_ulong(char *, u_long *); - -#endif /* !_NS_PARSEUTIL_H */ diff --git a/contrib/bind/bin/named/ns_resp.c b/contrib/bind/bin/named/ns_resp.c deleted file mode 100644 index 36e3626bcba24..0000000000000 --- a/contrib/bind/bin/named/ns_resp.c +++ /dev/null @@ -1,4005 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)ns_resp.c 4.65 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: ns_resp.c,v 8.144 2000/07/11 08:26:09 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1988, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1995 by International Business Machines, Inc. - * - * International Business Machines, Inc. (hereinafter called IBM) grants - * permission under its copyrights to use, copy, modify, and distribute this - * Software with or without fee, provided that the above copyright notice and - * all paragraphs of this notice appear in all copies, and that the name of IBM - * not be used in connection with the marketing of any product incorporating - * the Software or modifications thereof, without specific, written prior - * permission. - * - * To the extent it has a right to do so, IBM grants an immunity from suit - * under its patents, if any, for the use, sale or manufacture of products to - * the extent that such products are used for performing Domain Name System - * dynamic updates in TCP/IP networks by means of the Software. No immunity is - * granted for any product per se or for any other function of any product. - * - * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, - * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN - * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <limits.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" - -static u_int8_t norootlogged[MAXCLASS]; /* XXX- should be a bitmap */ - -static const char skipnameFailedAnswer[] = "skipname failed in answer", - skipnameFailedAuth[] = "skipname failed in authority", - skipnameFailedQuery[] = "skipname failed in query", - outofDataQuery[] = "ran out of data in query", - outofDataAnswer[] = "ran out of data in answer", - notSingleQuery[] = "not exactly one query", - expandFailedQuery[] = "dn_expand failed in query", - expandFailedAnswer[] = "dn_expand failed in answer", - expandFailedAuth[] = "dn_expand failed in authority", - outofDataAuth[] = "ran out of data in authority", - dlenOverrunAnswer[] = "dlen overrun in answer", - dlenOverrunAuth[] = "dlen overrun in authority", - dlenUnderrunAnswer[] = "dlen underrun in answer", - outofDataFinal[] = "out of data in final pass", - outofDataAFinal[] = "out of data after final pass", - badNameFound[] = "found an invalid domain name", - wrongQuestion[] = "answer to wrong question", - danglingCname[] = "dangling CNAME pointer", - nonRecursiveForwarder[]= "non-recursive forwarder"; - -struct db_list { - struct db_list *db_next; - struct databuf *db_dp; -}; - -struct flush_set { - char * fs_name; - int fs_type; - int fs_class; - u_int fs_cred; - struct db_list *fs_list; - struct db_list *fs_last; -}; - -static void rrsetadd(struct flush_set *, const char *, - struct databuf *), - rrsetupdate(struct flush_set *, int flags, - struct sockaddr_in, int), - flushrrset(struct flush_set *, struct sockaddr_in), - free_flushset(struct flush_set *, int), - check_hints(struct flush_set *); -static int rrsetcmp(char *, struct db_list *, struct hashbuf *), - check_root(void), - check_ns(void), - wanted(const struct databuf *, int, int), - wantedsig(const struct databuf *, int, int), - rrextract(u_char *, int, u_char *, - struct databuf **, char *, int, - struct sockaddr_in, char **); -static void mark_bad(struct qinfo *qp, struct sockaddr_in from); -static void mark_lame(struct qinfo *qp, struct sockaddr_in from); -static void fast_retry(struct qinfo *qp, struct sockaddr_in from); -static void add_related_additional(char *); -static void free_related_additional(void); -static int related_additional(char *); -static void freestr_maybe(char **); -static enum ordering match_order(const struct namebuf *, int, int); -static int match_name(const struct namebuf *, const char *, size_t); - -#define MAX_RELATED 100 - -static int num_related = 0; -static char *related[MAX_RELATED]; - -static char * -learntFrom(struct qinfo *qp, struct sockaddr_in *server) { - static char *buf = NULL; - char *a, *ns, *na; - struct databuf *db; - int i; - - a = ns = na = "<Not Available>"; - - for (i = 0; (u_int)i < qp->q_naddr; i++) { - if (ina_equal(qp->q_addr[i].ns_addr.sin_addr, - server->sin_addr)) { - db = qp->q_addr[i].ns; - if (db != NULL) { - if (NS_OPTION_P(OPTION_HOSTSTATS)) { - char nsbuf[20]; - - if (db->d_ns != NULL) { - strcpy(nsbuf, - inet_ntoa(db->d_ns->addr)); - ns = nsbuf; - } else { - ns = zones[db->d_zone] - .z_origin; - } - } - if (db->d_rcode == 0) - na = (char*)qp->q_addr[i].ns->d_data; - } - - if (NS_OPTION_P(OPTION_HOSTSTATS)) { - char abuf[20]; - - db = qp->q_addr[i].nsdata; - if (db != NULL) { - if (db->d_ns != NULL) { - strcpy(abuf, - inet_ntoa(db->d_ns->addr)); - a = abuf; - } else { - a = zones[db->d_zone].z_origin; - } - } - } - break; - } - } - - if (a == ns && ns == na) /* all "UNKNOWN" */ - return (NULL); - - if (*a == '\0') - a = "\".\""; - if (*ns == '\0') - ns = "\".\""; - if (*na == '\0') - na = "\".\""; - - if (NS_OPTION_P(OPTION_HOSTSTATS)) { - static const char fmt[] = " '%s': learnt (A=%s,NS=%s)"; - - buf = newstr(sizeof fmt + strlen(na) + strlen(a) + strlen(ns), - 0); - if (buf == NULL) - return (NULL); - sprintf(buf, fmt, na, a, ns); - } else { - static const char fmt[] = " '%s'"; - - buf = newstr(sizeof fmt + strlen(na), 0); - if (buf == NULL) - return (NULL); - sprintf(buf, fmt, na); - } - - return (buf); -} - -void -ns_resp(u_char *msg, int msglen, struct sockaddr_in from, struct qstream *qsp) -{ - struct qinfo *qp; - HEADER *hp; - struct qserv *qs = NULL; - struct databuf *ns, *ns2; - u_char *cp, *answers, *eom = msg + msglen; - struct flush_set *flushset = NULL; - int flushset_size = 0; - struct sockaddr_in *nsa; - struct databuf *nsp[NSMAX]; - int i, c, n, qdcount, ancount, aucount, nscount, arcount, arfirst; - int soacount; - u_int qtype, qclass; - int restart; /* flag for processing cname response */ - int validanswer, dbflags; - int cname, lastwascname, externalcname; - int count, founddata, foundname; - int buflen; - int newmsglen; - char name[MAXDNAME], qname[MAXDNAME], aname[MAXDNAME]; - char msgbuf[MAXDNAME+100]; - char *dname, tmpdomain[MAXDNAME]; - const char *fname; - const char *formerrmsg = "brain damage"; - u_char newmsg[PACKETSZ]; - u_char **dpp, *tp; - time_t rtrip; - struct hashbuf *htp; - struct namebuf *np; - struct fwdinfo *fwd; - struct databuf *dp; - int forcecmsg = 0; - char *tname = NULL; - int sendto_errno = 0; - int has_tsig, oldqlen; - u_char *oldqbuf; - u_char *smsg; - int smsglen, smsgsize, siglen; - u_char sig[TSIG_SIG_SIZE]; - time_t tsig_time; - DST_KEY *key; - - nameserIncr(from.sin_addr, nssRcvdR); - nsp[0] = NULL; - hp = (HEADER *) msg; - if ((qp = qfindid(hp->id)) == NULL ) { - ns_debug(ns_log_default, 1, "DUP? dropped (id %d)", - ntohs(hp->id)); - nameserIncr(from.sin_addr, nssRcvdDupR); - return; - } - - if (ns_wouldlog(ns_log_default, 2)) { - ns_debug(ns_log_default, 2, "Response (%s %s %s) nsid=%d id=%d", - (qp->q_flags & Q_SYSTEM) ?"SYSTEM" :"USER", - (qp->q_flags & Q_PRIMING) ?"PRIMING" :"NORMAL", - (qp->q_flags & Q_ZSERIAL) ?"ZSERIAL" :"-", - ntohs(qp->q_nsid), ntohs(qp->q_id)); - } - - if (qp->q_nstsig == NULL) - has_tsig = 0; - else { - int ret; - - ret = ns_verify(msg, &msglen, qp->q_nstsig->key, - qp->q_nstsig->sig, qp->q_nstsig->siglen, - NULL, NULL, &tsig_time, 0); - if (ret == 0) - has_tsig = 1; - else { - if (hp->rcode == NOERROR) - hp->rcode = NOTAUTH; - ns_debug(ns_log_default, 1, - "resp: error bad tsig, record dropped"); - return; - } - } - - /* - * Here we handle high level formatting problems by parsing the header. - */ - qdcount = ntohs(hp->qdcount); - ancount = ntohs(hp->ancount); - aucount = ntohs(hp->nscount); - arcount = ntohs(hp->arcount); - free_addinfo(); /* sets addcount to zero */ - cp = msg + HFIXEDSZ; - dpp = dnptrs; - *dpp++ = msg; - if ((*cp & INDIR_MASK) == 0) - *dpp++ = cp; - *dpp = NULL; - if (qdcount == 1) { - n = dn_expand(msg, eom, cp, qname, sizeof(qname)); - if (n <= 0) { - formerrmsg = expandFailedQuery; - goto formerr; - } - cp += n; - if (cp + 2 * INT16SZ > eom) { - formerrmsg = outofDataQuery; - goto formerr; - } - GETSHORT(qtype, cp); - GETSHORT(qclass, cp); - if (!ns_nameok(qp, qname, qclass, NULL, response_trans, - ns_ownercontext(qtype, response_trans), - qname, from.sin_addr)) { - formerrmsg = badNameFound; - goto refused; - } - if (cp > eom) { - formerrmsg = outofDataQuery; - goto formerr; - } - if (qp->q_msg && qp->q_msglen && - !res_nameinquery(qname, qtype, qclass, - qp->q_msg, qp->q_msg + qp->q_msglen)) { - sprintf(msgbuf, - "query section mismatch (%s %s %s)", - qname, p_class(qclass), p_type(qtype)); - formerrmsg = msgbuf; - goto formerr; - } - if (ns_samename(qp->q_name, qname) != 1 || - qp->q_class != qclass || - qp->q_type != qtype) { - formerrmsg = wrongQuestion; - goto formerr; - } - } else { - strcpy(qname, qp->q_name); - qclass = qp->q_class; - qtype = qp->q_type; - } - - /* cp now points after the query section. */ - - /* - * Here we handle bad responses from servers. - * Several possibilities come to mind: - * The server is sick and returns SERVFAIL - * The server returns some garbage opcode (it's sick) - * The server can't understand our query and return FORMERR - * In all these cases, we drop the packet, disable retries on - * this server and immediately force a retry. - */ - if ((hp->rcode != NOERROR && hp->rcode != NXDOMAIN) - || (hp->opcode != QUERY -#ifdef BIND_NOTIFY - && hp->opcode != NS_NOTIFY_OP -#endif - )) { - ns_debug(ns_log_default, 2, - "resp: error (ret %d, op %d), dropped", - hp->rcode, hp->opcode); - switch (hp->rcode) { - case SERVFAIL: - nameserIncr(from.sin_addr, nssRcvdFail); - break; - case FORMERR: - nameserIncr(from.sin_addr, nssRcvdFErr); - break; - default: - nameserIncr(from.sin_addr, nssRcvdErr); - break; - } - if (ns_samename(qp->q_name, qp->q_domain) == 1 && - hp->rcode == SERVFAIL && hp->opcode == QUERY) - mark_lame(qp, from); - mark_bad(qp, from); - fast_retry(qp, from); - return; - } - - if (qdcount != 1) { - /* We don't generate or forward these (yet). */ - formerrmsg = notSingleQuery; - goto formerr; - } - - /* - * Determine if the response came from a forwarder. Packets from - * anyplace not listed as a forwarder or as a server to whom we - * might have forwarded the query will be dropped. - * XXX - should put this in STATS somewhere. - */ - for (fwd = NS_ZFWDTAB(qp->q_fzone); fwd; fwd = fwd->next) - if (ina_equal(fwd->fwddata->fwdaddr.sin_addr, from.sin_addr)) - break; - /* - /* - * find the qinfo pointer and update - * the rtt and fact that we have called on this server before. - */ - { - struct timeval *stp; - - for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr; n++, qs++) - if (ina_equal(qs->ns_addr.sin_addr, from.sin_addr)) - break; - if ((u_int)n >= qp->q_naddr) { - if (!haveComplained(ina_ulong(from.sin_addr), - (u_long)"unexpected source")) { - ns_info(ns_log_default, - "Response from unexpected source (%s)", - sin_ntoa(from)); - } - /* - * We don't know who this response came from so it - * gets dropped on the floor. - */ - return; - } - stp = &qs->stime; - - /* Handle response from different (untried) interface. */ - if (qs->ns != NULL && stp->tv_sec == 0) { - ns = qs->ns; - while (qs > qp->q_addr - && (qs->stime.tv_sec == 0 || qs->ns != ns)) - qs--; - *stp = qs->stime; - /* XXX - sometimes stp still ends up pointing to - * a zero timeval, in spite of the above attempt. - * Why? What should we do about it? - */ - /* XXX - catch aliases here */ - } - - /* compute query round trip time */ - /* XXX - avoid integer overflow, which is quite likely if stp - * points to a zero timeval (see above). - * rtrip is of type time_t, which we assume is at least - * as big as an int. - */ - if ((tt.tv_sec - stp->tv_sec) > (INT_MAX-999)/1000) { - rtrip = INT_MAX; - } else { - rtrip = ((tt.tv_sec - stp->tv_sec) * 1000 + - (tt.tv_usec - stp->tv_usec) / 1000); - } - - if (ns_wouldlog(ns_log_default,3)) { - ns_debug(ns_log_default, 3, - "stime %lu/%lu now %lu/%lu rtt %ld", - (u_long)stp->tv_sec, (u_long)stp->tv_usec, - (u_long)tt.tv_sec, (u_long)tt.tv_usec, - (long)rtrip); - } - - /* prevent floating point overflow, limit to 1000 sec */ - if (rtrip > 1000000) { - rtrip = 1000000; - } - ns = qs->nsdata; - /* - * Don't update nstime if this doesn't look - * like an address databuf now. XXX - */ - if (ns && - ns->d_type == T_A && - ns->d_class == qs->ns->d_class) { - u_long t; - - if (ns->d_nstime == 0) - t = rtrip; - else - t = ns->d_nstime * ALPHA - + - (1 - ALPHA) * rtrip; - if (t > 65535) - t = 65535; - ns->d_nstime = (u_int16_t)t; - } - - /* - * Record the source so that we do not use this NS again. - */ - if (ns && qs->ns && (qp->q_nusedns < NSMAX)) { - qp->q_usedns[qp->q_nusedns++] = qs->ns; - if (ns_wouldlog(ns_log_default,2)) { - ns_debug(ns_log_default, 2, - "NS #%d addr %s used, rtt %d", - n, sin_ntoa(qs->ns_addr), ns->d_nstime); - } - } - - /* - * Penalize those who had earlier chances but failed - * by multiplying round-trip times by BETA (>1). - * Improve nstime for unused addresses by applying GAMMA. - * The GAMMA factor makes unused entries slowly - * improve, so they eventually get tried again. - * GAMMA should be slightly less than 1. - * Watch out for records that may have timed out - * and are no longer the correct type. XXX - */ - - for (n = 0, qs = qp->q_addr; - (u_int)n < qp->q_naddr; - n++, qs++) { - u_long t; - - ns2 = qs->nsdata; - if (!ns2 || ns2 == ns) - continue; - if (ns2->d_type != T_A || - ns2->d_class != qs->ns->d_class) /* XXX */ - continue; - if (qs->stime.tv_sec) { - if (ns2->d_nstime == 0) - t = (rtrip * BETA); - else - t = ns2->d_nstime * BETA - + - (1 - ALPHA) * rtrip; - } else - t = ns2->d_nstime * GAMMA; - if (t > 65535) - t = 65535; - ns2->d_nstime = (u_int16_t)t; - if (ns_wouldlog(ns_log_default,2)) { - ns_debug(ns_log_default, 2, "NS #%d %s rtt now %d", n, - sin_ntoa(qs->ns_addr), - ns2->d_nstime); - } - } - } - -#ifdef BIND_NOTIFY - /* - * For now, NOTIFY isn't defined for ANCOUNT!=0, AUCOUNT!=0, - * or ADCOUNT!=0. Therefore the only real work to be done for - * a NOTIFY-QR is to remove it from the query queue. - */ - if (hp->opcode == NS_NOTIFY_OP) { - ns_info(ns_log_notify, - "Received NOTIFY answer (%sAA) from %s for \"%s %s %s\"", - hp->aa ? "" : "!", - inet_ntoa(from.sin_addr), - *(qp->q_name) ? qp->q_name : ".", - p_class(qp->q_class), p_type(qp->q_type)); - qremove(qp); - return; - } -#endif - - if ((qp->q_flags & Q_ZSERIAL) != 0) { - if (hp->aa && ancount > 0 && hp->rcode == NOERROR && - qtype == T_SOA && (qclass == C_IN || qclass == C_HS)) - { - int n; - u_int type, class, dlen; - u_int32_t serial; - u_char *tp = cp; - u_char *rdatap; - - n = dn_expand(msg, eom, tp, name, sizeof name); - if (n < 0) { - formerrmsg = expandFailedAnswer; - goto formerr; - } - tp += n; /* name */ - if (tp + 3 * INT16SZ + INT32SZ > eom) { - formerrmsg = outofDataAnswer; - goto formerr; - } - GETSHORT(type, tp); /* type */ - GETSHORT(class, tp); /* class */ - tp += INT32SZ; /* ttl */ - GETSHORT(dlen, tp); /* dlen */ - rdatap = tp; /* start of rdata */ - if (!ns_nameok(qp, name, class, NULL, response_trans, - ns_ownercontext(type, response_trans), - name, from.sin_addr)) { - formerrmsg = badNameFound; - goto refused; - } - if (ns_samename(qname, name) != 1 || - qtype != type || qclass != class) { - sprintf(msgbuf, - "qserial answer mismatch (%s %s %s)", - name, p_class(class), p_type(type)); - formerrmsg = msgbuf; - goto formerr; - } - if (0 >= (n = dn_skipname(tp, eom))) { - formerrmsg = skipnameFailedAnswer; - goto formerr; - } - tp += n; /* mname */ - if (0 >= (n = dn_skipname(tp, eom))) { - formerrmsg = skipnameFailedAnswer; - goto formerr; - } - tp += n; /* rname */ - if (tp + 5 * INT32SZ > eom) { - formerrmsg = dlenUnderrunAnswer; - goto formerr; - } - GETLONG(serial, tp); - tp += 4 * INT32SZ; /* Skip rest of SOA. */ - if ((u_int)(tp - rdatap) != dlen) { - formerrmsg = dlenOverrunAnswer; - goto formerr; - } - for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr; - n++, qs++) - if (ina_equal(qs->ns_addr.sin_addr, - from.sin_addr)) - break; - if (n == qp->q_naddr) { - qserial_answer(qp); - qremove(qp); - return; - } - qs->serial = serial; - } - retry(qp); - return; - } - - /* - * Non-authoritative, no answer, no error, with referral. - */ - if (hp->rcode == NOERROR && !hp->tc && !hp->aa && - ancount == 0 && aucount > 0 -#ifdef BIND_NOTIFY - && hp->opcode != NS_NOTIFY_OP -#endif - ) { - u_char *tp; - int type, class, dlen; - int foundns, foundsoa; -#ifdef DEBUG - if (debug > 0) - res_pquery(&res, msg, msglen, - log_get_stream(packet_channel)); -#endif - /* - * Since there is no answer section (ancount == 0), - * we must be pointing at the authority section (aucount > 0). - */ - tp = cp; - foundns = foundsoa = 0; - for (i = 0 ; i < aucount ; i++) { - n = dn_expand(msg, eom, tp, name, sizeof name); - if (n < 0) { - formerrmsg = expandFailedAuth; - goto formerr; - } - tp += n; - if (tp + 3 * INT16SZ + INT32SZ > eom) { - formerrmsg = outofDataAuth; - goto formerr; - } - GETSHORT(type, tp); - GETSHORT(class, tp); - tp += INT32SZ; /* ttl */ - GETSHORT(dlen, tp); - if (!ns_nameok(qp, name, class, NULL, response_trans, - ns_ownercontext(type, response_trans), - name, from.sin_addr)) { - formerrmsg = badNameFound; - goto refused; - } - /* skip rest of record */ - if (tp + dlen > eom) { - formerrmsg = outofDataAuth; - goto formerr; - } - tp += dlen; - if (type == T_NS) { - strcpy(aname, name); - foundns = 1; - } - if (type == T_SOA) - foundsoa = 1; - } - - /* - * If the answer delegates us either to the same level in - * the hierarchy or closer to the root, we consider this - * server lame. Note that for now we only log the message - * if the T_NS was C_IN, which is technically wrong (NS is - * visible in all classes) but necessary anyway (non-IN - * classes tend to not have good strong delegation graphs). - */ - - if (foundns && !foundsoa && - ns_samedomain(qp->q_domain, aname)) { - if (fwd == NULL) { - nameserIncr(from.sin_addr, nssRcvdLDel); - mark_lame(qp, from); - } - mark_bad(qp, from); - if (class == C_IN && fwd == NULL && - !haveComplained(ina_ulong(from.sin_addr), - nhash(qp->q_domain))) { - char *learnt_from = learntFrom(qp, &from); - - ns_info(ns_log_lame_servers, - "Lame server on '%s' (in '%s'?): %s%s", - qname, qp->q_domain, - sin_ntoa(from), - (learnt_from == NULL) ? "" : - learnt_from); - if (learnt_from != NULL) - freestr(learnt_from); - } else if (fwd != NULL) { - if (!haveComplained(ina_ulong(from.sin_addr), - (u_long)nonRecursiveForwarder)) - ns_warning(ns_log_default, "%s: %s", - nonRecursiveForwarder, - sin_ntoa(from)); - } - - fast_retry(qp, from); - return; - } - } - - /* - * Add the info received in the response to the data base. - */ - arfirst = ancount + aucount; - c = arfirst + arcount; - - /* Don't return if it's a TSIG signed truncated message */ - if (has_tsig > 0 && hp->tc) - goto tcp_retry; - - /* -ve $ing non-existence of record, must handle non-authoritative - * NOERRORs with c == 0. - */ - if (!hp->aa && !hp->tc && hp->rcode == NOERROR && c == 0) - goto return_msg; - - if (qp->q_flags & Q_SYSTEM) - dbflags = DB_NOTAUTH | DB_NODATA; - else - dbflags = DB_NOTAUTH | DB_NODATA | DB_NOHINTS; - count = c; - if (qp->q_flags & Q_PRIMING) - dbflags |= DB_PRIMING; - if (hp->tc) { - count -= arcount; /* truncation had to affect this */ - if (!arcount) { - count -= aucount; /* guess it got this too */ - } - if (!(arcount || aucount)) { - count -= ancount; /* things are pretty grim */ - } - -tcp_retry: - /* retry using tcp provided this was not a tcp query */ - if (!(qp->q_flags & Q_USEVC)) { - qp->q_flags |= Q_USEVC; - unsched(qp); - schedretry(qp, 60); - - nsa = Q_NEXTADDR(qp, 0); - - key = tsig_key_from_addr(nsa->sin_addr); - if (key != NULL) { - smsgsize = qp->q_msglen + TSIG_BUF_SIZE; - smsg = memget(smsgsize); - smsglen = qp->q_msglen; - siglen = sizeof(sig); - memcpy(smsg, qp->q_msg, qp->q_msglen); - n = ns_sign(smsg, &smsglen, smsgsize, - NOERROR, key, NULL, 0, - sig, &siglen, 0); - if (n == 0) { - oldqbuf = qp->q_msg; - oldqlen = qp->q_msglen; - qp->q_msglen = smsglen; - qp->q_msg = smsg; - has_tsig = 1; - qp->q_nstsig = new_tsig(key, sig, - siglen); - } - else { - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - INSIST(0); - } - } - else { - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - } - - if (tcp_send(qp) != NOERROR) - /* - * We're probably in trouble if tcp_send - * failed, but we'll try to press on because - * there isn't anything else to do. - */ - retry(qp); - - if (has_tsig == 1) { - memput(qp->q_msg, smsgsize); - qp->q_msg = oldqbuf; - qp->q_msglen = oldqlen; - } - return; - } else if (!qsp) { - /* outstanding udp response */ - return; - } - - /* XXX truncated tcp response */ - ns_error(ns_log_default, - "ns_resp: TCP truncated: \"%s\" %s %s from %s", - qname, p_class(qclass), p_type(qtype), - sin_ntoa(from)); - /* mark this server as bad */ - mark_bad(qp, from); - /* try another server, it may have a bigger write buffer */ - retry(qp); - return; - } - - tp = cp; - - restart = 0; - validanswer = 0; - nscount = 0; - soacount = 0; - cname = 0; - lastwascname = 0; - externalcname = 0; - strcpy(aname, qname); - - if (count) { - /* allocate 1 extra record for end of set detection */ - flushset_size = (count + 1) * sizeof *flushset; - flushset = memget(flushset_size); - if (flushset == NULL) - panic("flushset: out of memory", NULL); - memset(flushset, 0, flushset_size); - } else - flushset = NULL; - - for (i = 0; i < count; i++) { - struct databuf *dp; - int type; - - freestr_maybe(&tname); - if (cp >= eom) { - free_related_additional(); - if (flushset != NULL) - free_flushset(flushset, flushset_size); - formerrmsg = outofDataFinal; - goto formerr; - } - n = rrextract(msg, msglen, cp, &dp, name, sizeof name, from, - &tname); - if (n < 0) { - free_related_additional(); - freestr_maybe(&tname); - if (flushset != NULL) - free_flushset(flushset, flushset_size); - formerrmsg = outofDataFinal; - if (hp->rcode == REFUSED) - goto refused; - else - goto formerr; - } - cp += n; - if (!dp) - continue; - type = dp->d_type; - if (i < ancount) { - /* Answer section. */ - if (externalcname || ns_samename(name, aname) != 1) { - if (!externalcname) - ns_info(ns_log_resp_checks, - "wrong ans. name (%s != %s)", - name[0] ? name : ".", - aname[0] ? aname : "."); - else - ns_debug(ns_log_resp_checks, 3, - "ignoring answer '%s' after external cname", - name); - db_freedata(dp); - continue; - } - if (type == T_CNAME && - qtype != T_CNAME && qtype != T_ANY) { - strcpy(aname, (char *)dp->d_data); - if (!ns_samedomain(aname, qp->q_domain)) - externalcname = 1; - cname++; - lastwascname = 1; - } else { - validanswer = 1; - lastwascname = 0; - } - - if (tname != NULL) { - add_related_additional(tname); - tname = NULL; - } - - dp->d_cred = (hp->aa && ns_samename(name, qname) == 1) - ? DB_C_AUTH - : DB_C_ANSWER; - } else { - /* After answer section. */ - if (lastwascname) { - ns_debug(ns_log_resp_checks, 3, - "last was cname, ignoring auth. and add."); - db_freedata(dp); - break; - } - if (i < arfirst) { - /* Authority section. */ - switch (type) { - case T_NS: - case T_SOA: - if (!ns_samedomain(aname, name)) { - ns_info(ns_log_resp_checks, - "bad referral (%s !< %s) from %s", - aname[0] ? aname : ".", - name[0] ? name : ".", - sin_ntoa(from)); - db_freedata(dp); - continue; - } else if (fwd == NULL && - !ns_samedomain(name, - qp->q_domain)) { - if (!externalcname) - ns_info(ns_log_resp_checks, - "bad referral (%s !< %s) from %s", - name[0] ? name : ".", - qp->q_domain[0] ? - qp->q_domain : ".", - sin_ntoa(from)); - db_freedata(dp); - continue; - } - if (type == T_NS) { - nscount++; - add_related_additional(tname); - tname = NULL; - } - if (type == T_SOA) { - soacount++; - } - break; - case T_NXT: - /* XXX check */ - break; - case T_SIG: - /* XXX check that it relates to an - NS or SOA or NXT */ - break; - default: - ns_info(ns_log_resp_checks, - "invalid RR type '%s' in authority section (name = '%s') from %s", - p_type(type), name, - sin_ntoa(from)); - db_freedata(dp); - continue; - } - dp->d_cred = (hp->aa && (cname == 0)) ? - DB_C_AUTH : (qp->q_flags & Q_PRIMING) - ? DB_C_ANSWER - : DB_C_ADDITIONAL; - } else { - /* Additional section. */ - switch (type) { - case T_A: - case T_AAAA: - if (externalcname || - !ns_samedomain(name, qp->q_domain)) { - ns_debug(ns_log_resp_checks, 3, - "ignoring additional info '%s' type %s", - name, p_type(type)); - db_freedata(dp); - continue; - } - if (!related_additional(name)) { - ns_info(ns_log_resp_checks, - "unrelated additional info '%s' type %s from %s", - name, p_type(type), - sin_ntoa(from)); - db_freedata(dp); - continue; - } - break; - case T_KEY: - /* XXX check? */ - break; - case T_SIG: - /* - * XXX a SIG RR should relate - * to some other RR in this section, - * although if it's the last RR - * it might be a transaction signature. - */ - break; - default: - ns_info(ns_log_resp_checks, - "invalid RR type '%s' in additional section (name = '%s') from %s", - p_type(type), name, - sin_ntoa(from)); - db_freedata(dp); - continue; - } - dp->d_cred = (qp->q_flags & Q_PRIMING) - ? DB_C_ANSWER - : DB_C_ADDITIONAL; - } - } - rrsetadd(flushset, name, dp); - } - free_related_additional(); - freestr_maybe(&tname); - if (flushset != NULL) { - if ((qp->q_flags & Q_SYSTEM) && (qp->q_flags & Q_PRIMING)) { - check_hints(flushset); /* before rrsetupdate */ - rrsetupdate(flushset, dbflags, from, 1); - } else - rrsetupdate(flushset, dbflags, from, 0); - free_flushset(flushset, flushset_size); - } - if (lastwascname && !externalcname) - ns_debug(ns_log_cname, 3, "%s (%s) q(%s %s %s) %s qd(%s)", - danglingCname, aname, - (qname && *qname) ? qname : ".", - p_class(qclass), p_type(qtype), - sin_ntoa(from), qp->q_domain); - - if (cp > eom) { - formerrmsg = outofDataAFinal; - goto formerr; - } - - if ((qp->q_flags & Q_SYSTEM) && ancount) { - if ((qp->q_flags & Q_PRIMING) && !check_root()) { - /* mark server as bad */ - mark_bad(qp, from); - fast_retry(qp, from); - return; - } - ns_debug(ns_log_default, 3, - "resp: leaving, SYSQUERY ancount %d", ancount); -#ifdef BIND_NOTIFY - if (qp->q_notifyzone != DB_Z_CACHE) { - struct zoneinfo *zp = &zones[qp->q_notifyzone]; - - qp->q_notifyzone = DB_Z_CACHE; - ns_notify(zp->z_origin, zp->z_class, ns_t_soa); - } -#endif - qremove(qp); - return; - } - - if (ancount && count && !validanswer) { - /* - * Everything passed validation but we didn't get the - * final answer. The response must have contained - * a dangling CNAME. Force a restart of the query. - * - * Don't set restart if count==0, since this means - * the response was truncated in the answer section, - * causing us to set count to 0 which will cause - * validanswer to be 0 as well even though the answer - * section probably contained valid RRs (just not - * a complete set). - * XXX - this works right if we can just forward this - * response to the client, but not if we found a CNAME - * in a prior response and restarted the query. - */ - restart = 1; - } - - if (!restart && !qp->q_cmsglen && ancount > 1 && qtype == T_A) - sort_response(tp, eom, ancount, &qp->q_from); - - /* - * An answer to a T_ANY query or a successful answer to a - * regular query with no indirection, then just return answer. - */ - if (!restart && ancount && (qtype == T_ANY || !qp->q_cmsglen)) { - ns_debug(ns_log_default, 3, - "resp: got as much answer as there is"); - goto return_msg; - } - - /* - * We might want to cache this negative answer. - * - * if ancount != 0 and rcode == NOERROR we cannot determine if the - * CNAME chain has been processed to completion or not, so just - * restart the query. DNS needs a NODATA return code! - * - * As some servers incorrectly return a NODATA indication when - * there is a CNAME chain instead of NXDOMAIN, we requery to get - * a definitive answer. - */ - if ((hp->rcode == NXDOMAIN && cname == ancount) || - (hp->rcode == NOERROR && ancount == 0 && - (nscount == 0 || soacount != 0) - ) - ) - { - cache_n_resp(msg, msglen, from, qp->q_name, - qp->q_class, qp->q_type); - - if (!qp->q_cmsglen) { - ns_debug(ns_log_default, 3, - "resp: leaving NO: auth = %d", hp->aa); - goto return_msg; - } - forcecmsg = 1; - } - - /* - * All messages in here need further processing. i.e. they - * are either CNAMEs or we got referred again. - */ - count = 0; - founddata = 0; - dname = name; - /* - * XXX - the restart stuff doesn't work if any of the answer RRs - * is not cacheable (TTL==0 or unknown RR type), since all of the - * answer must pass through the cache and be re-assembled. - */ - if (qp->q_cmsglen != 0) { - ns_debug(ns_log_default, 1, "Cname second pass"); - newmsglen = MIN(PACKETSZ, qp->q_cmsglen); - memcpy(newmsg, qp->q_cmsg, newmsglen); - } else { - newmsglen = MIN(PACKETSZ, msglen); - memcpy(newmsg, msg, newmsglen); - } - hp = (HEADER *) newmsg; - hp->ancount = htons(0); - hp->nscount = htons(0); - hp->arcount = htons(0); - hp->rcode = NOERROR; - dnptrs[0] = newmsg; - dnptrs[1] = NULL; - cp = newmsg + HFIXEDSZ; - /* - * Keep in mind that none of this code works when QDCOUNT>1. - * cp ends up pointed just past the query section in both cases. - */ - /* - * Arrange for dname to contain the query name. The query - * name can be either the original query name if restart==0 - * or the target of the last CNAME if we are following a - * CNAME chain and were referred. - */ - n = dn_expand(newmsg, newmsg + newmsglen, cp, dname, sizeof name); - if (n < 0) { - ns_debug(ns_log_default, 1, "dn_expand failed"); - goto servfail; - } - if (!res_dnok(dname)) { - ns_debug(ns_log_default, 1, "bad name (%s)", dname); - goto servfail; - } - cp += n + QFIXEDSZ; - buflen = sizeof(newmsg) - (cp - newmsg); - - cname = 0; - - try_again: - ns_debug(ns_log_default, 1, "resp: nlookup(%s) qtype=%d", dname, - qtype); - foundname = 0; - fname = ""; - htp = hashtab; /* lookup relative to root */ - np = nlookup(dname, &htp, &fname, 0); - ns_debug(ns_log_default, 1, "resp: %s '%s' as '%s' (cname=%d)", - np == NULL ? "missed" : "found", dname, fname, cname); - if (np == NULL || fname != dname) - goto fetch_ns; - - foundname++; - answers = cp; - count = cp - newmsg; - /* - * Look for NXDOMAIN record. - */ - for (dp = np->n_data; dp; dp = dp->d_next) { - if (!stale(dp) && (dp->d_rcode == NXDOMAIN) && - (dp->d_class == (int)qclass)) { -#ifdef RETURNSOA - n = finddata(np, qclass, T_SOA, hp, &dname, - &buflen, &count); - if ( n != 0) { - if (count) { - cp += n; - buflen -= n; - newmsglen += n; - hp->nscount = htons((u_int16_t)count); - } - if (hp->rcode == NOERROR_NODATA) { - hp->rcode = NOERROR; - goto return_newmsg; - } - } -#else - count = 0; -#endif - hp->rcode = NXDOMAIN; - /* - * XXX forcing AA all the time isn't right, but - * we have to work that way by default - * for compatibility with older servers. - */ - if (!NS_OPTION_P(OPTION_NONAUTH_NXDOMAIN)) - hp->aa = 1; - ns_debug(ns_log_default, 3, "resp: NXDOMAIN aa = %d", - hp->aa); - if ((count == 0) || NS_OPTION_P(OPTION_NORFC2308_TYPE1)) - goto return_newmsg; - founddata = 1; - goto fetch_ns; - } - } - n = finddata(np, qclass, qtype, hp, &dname, &buflen, &count); - if (n == 0) - goto fetch_ns; /* NO data available */ - if (hp->rcode) { - if (hp->rcode == NOERROR_NODATA) - hp->rcode = NOERROR; -#ifdef RETURNSOA - if (count) { - cp += n; - buflen -= n; - hp->nscount = htons((u_int16_t)count); - } -#endif - if ((count == 0) || NS_OPTION_P(OPTION_NORFC2308_TYPE1)) - goto return_newmsg; - founddata = 1; - goto fetch_ns; - } - cp += n; - buflen -= n; - hp->ancount = htons(ntohs(hp->ancount) + (u_int16_t)count); - if (fname != dname && qtype != T_CNAME && qtype != T_ANY) { - cname++; - goto try_again; - } - founddata = 1; - - ns_debug(ns_log_default, 3, - "resp: foundname=%d, count=%d, founddata=%d, cname=%d", - foundname, count, founddata, cname); - - if (count > 1 && qtype == T_A) - sort_response(answers, cp, count, &qp->q_from); - - fetch_ns: - if (hp->tc) - goto return_newmsg; - - /* - * Look for name servers to refer to and fill in the authority - * section or record the address for forwarding the query - * (recursion desired). - */ - free_nsp(nsp); - switch (findns(&np, qclass, nsp, &count, 0)) { - case NXDOMAIN: /* shouldn't happen */ - ns_debug(ns_log_default, 3, "req: leaving (%s, rcode %d)", - dname, hp->rcode); - if (!foundname) - hp->rcode = NXDOMAIN; - if (qclass != C_ANY) { - hp->aa = 1; - if (np && (!foundname || !founddata)) { - n = doaddauth(hp, cp, buflen, np, nsp[0]); - cp += n; - buflen -= n; - } - } - goto return_newmsg; - - case SERVFAIL: - goto servfail; - } - - if (founddata) { - hp = (HEADER *)newmsg; - n = add_data(np, nsp, cp, buflen, &count); - if (n < 0) { - hp->tc = 1; - n = (-n); - } - cp += n; - buflen -= n; - hp->nscount = htons((u_int16_t)count + ntohs(hp->nscount)); - goto return_newmsg; - } - - /* - * If we get here, we don't have the answer yet and are about - * to iterate to try and get it. First, infinite loop avoidance. - */ - if (qp->q_nqueries++ > MAXQUERIES) { - ns_debug(ns_log_default, 1, - "resp: MAXQUERIES exceeded (%s %s %s)", - dname, p_class(qclass), p_type(qtype)); - ns_info(ns_log_default, - "MAXQUERIES exceeded, possible data loop in resolving (%s)", - dname); - goto servfail; - } - - /* Reset the query control structure */ - - ns_freeqns(qp, "ns_resp"); - qp->q_naddr = 0; - qp->q_curaddr = 0; - nsfwdadd(qp, NS_ZFWDTAB(qp->q_fzone)); - - if (qp->q_domain != NULL) - freestr(qp->q_domain); - getname(np, tmpdomain, sizeof tmpdomain); - qp->q_domain = savestr(tmpdomain, 1); - - if (NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) - n = 0; - else if ((n = nslookup(nsp, qp, dname, "ns_resp")) <= 0) { - if (n < 0) { - if (n == -1) - ns_debug(ns_log_default, 3, - "resp: nslookup reports danger"); - if (cname) /* a remote CNAME that does not have data */ - goto return_newmsg; - goto servfail; - } else { - ns_debug(ns_log_default, 3, - "resp: no addrs found for NS's"); - /* - * Timeout while sysquery looks up the NS addresses. - * - * Hopefully we'll have them when the client asks - * again. - * - * too bad we can't just wait for the sysquery - * response to restart this query (it's too hard). - * - * We could try to crawl back up the tree looking - * for reachable servers, but we may have just - * gotten delegated down here by a response with - * no A RRs for the servers. If we blindly tried - * this strategy, we bang on the same server forever. - */ - goto timeout; - } - } - for (n = 0; (u_int)n < qp->q_naddr; n++) - qp->q_addr[n].stime.tv_sec = 0; - qp->q_addr[0].stime = tt; - if (cname) { - if (qp->q_cname++ == MAXCNAMES) { - ns_debug(ns_log_default, 3, - "resp: leaving, MAXCNAMES exceeded"); - goto servfail; - } - ns_debug(ns_log_default, 1, "q_cname = %d", qp->q_cname); - ns_debug(ns_log_default, 3, - "resp: building recursive query; nslookup"); - if (qp->q_cmsg == NULL) { - qp->q_cmsg = qp->q_msg; - qp->q_cmsglen = qp->q_msglen; - qp->q_cmsgsize = qp->q_msgsize; - } else if (qp->q_msg != NULL) - memput(qp->q_msg, qp->q_msgsize); - qp->q_msg = (u_char *)memget(PACKETSZ); - if (qp->q_msg == NULL) { - ns_notice(ns_log_default, "resp: memget error"); - goto servfail; - } - qp->q_msgsize = PACKETSZ; - n = res_nmkquery(&res, QUERY, dname, qclass, qtype, - NULL, 0, NULL, qp->q_msg, PACKETSZ); - if (n < 0) { - ns_info(ns_log_default, "resp: res_mkquery(%s) failed", - dname); - goto servfail; - } - if (qp->q_name != NULL) - freestr(qp->q_name); - qp->q_name = savestr(dname, 1); - qp->q_msglen = n; - hp = (HEADER *) qp->q_msg; - hp->rd = 0; - } else - hp = (HEADER *) qp->q_msg; - hp->id = qp->q_nsid = htons(nsid_next()); - hp->rd = (qp->q_addr[0].forwarder ? 1 : 0); - unsched(qp); - schedretry(qp, retrytime(qp)); - nsa = Q_NEXTADDR(qp, 0); - if (ns_wouldlog(ns_log_default,1)) { - ns_debug(ns_log_default, 1, - "resp: forw -> %s ds=%d nsid=%d id=%d %dms", - sin_ntoa(*nsa), ds, - ntohs(qp->q_nsid), ntohs(qp->q_id), - (qp->q_addr[0].nsdata != NULL) - ? qp->q_addr[0].nsdata->d_nstime - : -1); - } -#ifdef DEBUG - if (debug >= 10) - res_pquery(&res, qp->q_msg, qp->q_msglen, - log_get_stream(packet_channel)); -#endif - key = tsig_key_from_addr(nsa->sin_addr); - if (key != NULL) { - smsgsize = qp->q_msglen + TSIG_BUF_SIZE; - smsg = memget(smsgsize); - smsglen = qp->q_msglen; - siglen = sizeof(sig); - memcpy(smsg, qp->q_msg, qp->q_msglen); - n = ns_sign(smsg, &smsglen, smsgsize, NOERROR, key, NULL, 0, - sig, &siglen, 0); - if (n == 0) { - oldqbuf = qp->q_msg; - oldqlen = qp->q_msglen; - qp->q_msglen = smsglen; - qp->q_msg = smsg; - has_tsig = 1; - qp->q_nstsig = new_tsig(key, sig, siglen); - } - else { - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - INSIST(0); - } - } - else { - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - } - - if (qp->q_flags & Q_USEVC) { - if (tcp_send(qp) != NOERROR) { - if (!haveComplained(ina_ulong(nsa->sin_addr), - (u_long)tcpsendStr)) - ns_info(ns_log_default, - "ns_forw: tcp_send(%s) failed: %s", - sin_ntoa(*nsa), strerror(errno)); - } - } else if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0, - (struct sockaddr *)nsa, - sizeof(struct sockaddr_in)) < 0) - { - sendto_errno = errno; - if (!haveComplained(ina_ulong(nsa->sin_addr), - (u_long)sendtoStr)) - ns_info(ns_log_default, "ns_resp: sendto(%s): %s", - sin_ntoa(*nsa), strerror(errno)); - nameserIncr(nsa->sin_addr, nssSendtoErr); - } - if (has_tsig == 1) { - memput(qp->q_msg, smsgsize); - qp->q_msg = oldqbuf; - qp->q_msglen = oldqlen; - } - hp->rd = 0; /* leave set to 0 for dup detection */ - nameserIncr(nsa->sin_addr, nssSentFwdR); - nameserIncr(qp->q_from.sin_addr, nssRcvdFwdR); - ns_debug(ns_log_default, 3, "resp: Query sent."); - free_nsp(nsp); - switch (sendto_errno) { - case ENETDOWN: - case ENETUNREACH: - case EHOSTDOWN: - case EHOSTUNREACH: - unsched(qp); - schedretry(qp, (time_t) 0); - } - return; - - formerr: - if (!haveComplained(ina_ulong(from.sin_addr), (u_long)formerrmsg)) - ns_info(ns_log_resp_checks, "Malformed response from %s (%s)", - sin_ntoa(from), formerrmsg); - fast_retry(qp, from); - free_nsp(nsp); - return; - - return_msg: - nameserIncr(from.sin_addr, nssRcvdFwdR); - nameserIncr(qp->q_from.sin_addr, nssSentFwdR); - nameserIncr(qp->q_from.sin_addr, nssSentAns); - if (!hp->aa) - nameserIncr(qp->q_from.sin_addr, nssSentNaAns); - if (hp->rcode == NXDOMAIN) - nameserIncr(qp->q_from.sin_addr, nssSentNXD); - /* The "standard" return code */ - hp->qr = 1; - hp->id = qp->q_id; - hp->rd = 1; - hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0); - (void) send_msg(msg, msglen, qp); - qremove(qp); - free_nsp(nsp); - return; - - return_newmsg: - nameserIncr(qp->q_from.sin_addr, nssSentAns); - - if (!hp->aa) - nameserIncr(qp->q_from.sin_addr, nssSentNaAns); - if (hp->rcode == NXDOMAIN) - nameserIncr(qp->q_from.sin_addr, nssSentNXD); - n = doaddinfo(hp, cp, buflen); - cp += n; - buflen -= n; - hp->qr = 1; - hp->id = qp->q_id; - hp->rd = 1; - hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0); - (void) send_msg(newmsg, cp - newmsg, qp); - qremove(qp); - free_nsp(nsp); - return; - - refused: - hp = (HEADER *)(qp->q_cmsglen ? qp->q_cmsg : qp->q_msg); - hp->rcode = REFUSED; - hp->qr = 1; - hp->id = qp->q_id; - hp->rd = 1; - hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0); - (void) send_msg((u_char *)hp, - (qp->q_cmsglen ? qp->q_cmsglen : qp->q_msglen), - qp); - qremove(qp); - free_nsp(nsp); - return; - - servfail: - nameserIncr(qp->q_from.sin_addr, nssSentFail); - hp = (HEADER *)(qp->q_cmsglen ? qp->q_cmsg : qp->q_msg); - hp->rcode = SERVFAIL; - hp->qr = 1; - hp->id = qp->q_id; - hp->rd = 1; - hp->ra = (NS_OPTION_P(OPTION_NORECURSE) == 0); - (void) send_msg((u_char *)hp, - (qp->q_cmsglen ? qp->q_cmsglen : qp->q_msglen), - qp); - qremove(qp); - free_nsp(nsp); - return; - - timeout: - if (qp->q_stream) - sq_remove(qp->q_stream); - qremove(qp); - free_nsp(nsp); - return; -} - -#define BOUNDS_CHECK(ptr, count) \ - do { \ - if ((ptr) + (count) > eom) { \ - hp->rcode = FORMERR; \ - return (-1); \ - } \ - } while (0) - -static int -rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp, - char *dname, int namelen, struct sockaddr_in from, char **tnamep) -{ - u_char *cp, *eom, *rdatap; - u_int class, type, dlen; - int n, n1, n2; - u_int32_t ttl; - u_char *cp1, data[MAXDATA*2]; - HEADER *hp = (HEADER *)msg; - enum context context; - - if (tnamep != NULL) - *tnamep = NULL; - - *dpp = NULL; - cp = rrp; - eom = msg + msglen; - if ((n = dn_expand(msg, eom, cp, dname, namelen)) < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - BOUNDS_CHECK(cp, 2*INT16SZ + INT32SZ + INT16SZ); - GETSHORT(type, cp); - GETSHORT(class, cp); - if (class > CLASS_MAX) { - ns_debug(ns_log_default, 3, "bad class in rrextract"); - hp->rcode = FORMERR; - return (-1); - } - GETLONG(ttl, cp); - if (ttl > MAXIMUM_TTL) { - ns_debug(ns_log_default, 5, "%s: converted TTL > %u to 0", - dname, MAXIMUM_TTL); - ttl = 0; - } - GETSHORT(dlen, cp); - BOUNDS_CHECK(cp, dlen); - rdatap = cp; - if (!ns_nameok(NULL, dname, class, NULL, response_trans, - ns_ownercontext(type, response_trans), - dname, from.sin_addr)) { - hp->rcode = REFUSED; - return (-1); - } - ns_debug(ns_log_default, 3, - "rrextract: dname %s type %d class %d ttl %d", - dname, type, class, ttl); - /* - * Convert the resource record data into the internal - * database format. - * - * On entry to the switch: - * CP points to the RDATA section of the wire-format RR. - * DLEN is its length. - * The memory area at DATA is available for processing. - * - * On exit from the switch: - * CP has been incremented past the RR. - * CP1 points to the RDATA section of the database-format RR. - * N contains the length of the RDATA section of the dbase-format RR. - * - * The new data at CP1 for length N will be copied into the database, - * so it need not be in any particular storage location. - */ - switch (type) { - case T_A: - if (dlen != INT32SZ) { - hp->rcode = FORMERR; - return (-1); - } - /*FALLTHROUGH*/ - case T_WKS: - case T_HINFO: - case T_TXT: - case T_X25: - case T_ISDN: - case T_NSAP: - case T_AAAA: - case T_LOC: - case T_KEY: - case ns_t_cert: - cp1 = cp; - n = dlen; - cp += n; - break; - - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - n = dn_expand(msg, eom, cp, (char *)data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - if (!ns_nameok(NULL, (char *)data, class, NULL, response_trans, - type == T_PTR ?ns_ptrcontext(dname) :domain_ctx, - dname, from.sin_addr)) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 = data; - n = strlen((char *)data) + 1; - if (tnamep != NULL && (type == T_NS || type == T_MB)) - *tnamep = savestr((char *)cp1, 1); - break; - - case T_SOA: - context = hostname_ctx; - goto soa_rp_minfo; - case T_RP: - case T_MINFO: - context = mailname_ctx; - /* FALLTHROUGH */ - soa_rp_minfo: - n = dn_expand(msg, eom, cp, (char *)data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - if (!ns_nameok(NULL, (char *)data, class, NULL, response_trans, - context, dname, from.sin_addr)) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - /* - * The next use of 'cp' is dn_expand(), so we don't have - * to BOUNDS_CHECK() here. - */ - cp1 = data + (n = strlen((char *)data) + 1); - n1 = sizeof(data) - n; - if (type == T_SOA) - n1 -= 5 * INT32SZ; - n = dn_expand(msg, eom, cp, (char *)cp1, n1); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - if (type == T_RP) - context = domain_ctx; - else - context = mailname_ctx; - if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans, - context, dname, from.sin_addr)) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 += strlen((char *)cp1) + 1; - if (type == T_SOA) { - n = 5 * INT32SZ; - BOUNDS_CHECK(cp, n); - memcpy(cp1, cp, n); - cp += n; - cp1 += n; - } - n = cp1 - data; - cp1 = data; - break; - - case T_NAPTR: - /* Grab weight and port. */ - BOUNDS_CHECK(cp, INT16SZ*2); - memcpy(data, cp, INT16SZ*2); - cp1 = data + INT16SZ*2; - cp += INT16SZ*2; - - /* Flags */ - BOUNDS_CHECK(cp, 1); - n = *cp++; - BOUNDS_CHECK(cp, n); - *cp1++ = n; - memcpy(cp1, cp, n); - cp += n; cp1 += n; - - /* Service */ - BOUNDS_CHECK(cp, 1); - n = *cp++; - BOUNDS_CHECK(cp, n); - *cp1++ = n; - memcpy(cp1, cp, n); - cp += n; cp1 += n; - - /* Regexp */ - BOUNDS_CHECK(cp, 1); - n = *cp++; - BOUNDS_CHECK(cp, n); - *cp1++ = n; - memcpy(cp1, cp, n); - cp += n; cp1 += n; - - /* Replacement */ - n = dn_expand(msg, eom, cp, (char *)cp1, - sizeof data - (cp1 - data)); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans, - hostname_ctx, dname, from.sin_addr)) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - - /* compute end of data */ - cp1 += strlen((char *)cp1) + 1; - /* compute size of data */ - n = cp1 - data; - cp1 = data; - break; - - case T_MX: - case T_AFSDB: - case T_RT: - case T_SRV: - /* grab preference */ - BOUNDS_CHECK(cp, INT16SZ); - memcpy(data, cp, INT16SZ); - cp1 = data + INT16SZ; - cp += INT16SZ; - - if (type == T_SRV) { - /* Grab weight and port. */ - BOUNDS_CHECK(cp, INT16SZ*2); - memcpy(cp1, cp, INT16SZ*2); - cp1 += INT16SZ*2; - cp += INT16SZ*2; - } - - /* get name */ - n = dn_expand(msg, eom, cp, (char *)cp1, - sizeof data - (cp1 - data)); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans, - hostname_ctx, dname, from.sin_addr)) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - - if (tnamep != NULL) - *tnamep = savestr((char *)cp1, 1); - - /* compute end of data */ - cp1 += strlen((char *)cp1) + 1; - /* compute size of data */ - n = cp1 - data; - cp1 = data; - break; - - case T_PX: - /* grab preference */ - BOUNDS_CHECK(cp, INT16SZ); - memcpy(data, cp, INT16SZ); - cp1 = data + INT16SZ; - cp += INT16SZ; - - /* get MAP822 name */ - n = dn_expand(msg, eom, cp, (char *)cp1, - sizeof data - INT16SZ); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans, - domain_ctx, dname, from.sin_addr)) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - /* - * The next use of 'cp' is dn_expand(), so we don't have - * to BOUNDS_CHECK() here. - */ - cp1 += (n = strlen((char *)cp1) + 1); - n1 = sizeof(data) - n; - n = dn_expand(msg, eom, cp, (char *)cp1, n1); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - if (!ns_nameok(NULL, (char *)cp1, class, NULL, response_trans, - domain_ctx, dname, from.sin_addr)) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 += strlen((char *)cp1) + 1; - n = cp1 - data; - cp1 = data; - break; - - case T_SIG: { - u_long origTTL, exptime, signtime, timetilexp, now; - u_int8_t alg; - - /* Check signature time, expiration, and adjust TTL. */ - /* This code is similar to that in db_load.c. */ - - /* Skip coveredType, save alg, skip labels */ - BOUNDS_CHECK(cp, INT16SZ + 1 + 1 + 3*INT32SZ); - cp1 = cp + INT16SZ; - alg = *cp1++; - cp1++; - GETLONG(origTTL, cp1); - GETLONG(exptime, cp1); - GETLONG(signtime, cp1); - now = time(NULL); /* Get current time in GMT/UTC */ - - /* Don't let bogus name servers increase the signed TTL */ - if (ttl > origTTL) { - ns_debug(ns_log_default, 3, - "shrinking SIG TTL from %d to origTTL %d", - ttl, origTTL); - ttl = origTTL; - } - - /* Don't let bogus signers "sign" in the future. */ - if (signtime > now) { - ns_debug(ns_log_default, 3, - "ignoring SIG: signature date %s is in the future", - p_secstodate (signtime)); - return ((cp - rrp) + dlen); - } - - /* Ignore received SIG RR's that are already expired. */ - if (exptime <= now) { - ns_debug(ns_log_default, 3, - "ignoring SIG: expiration %s is in the past", - p_secstodate (exptime)); - return ((cp - rrp) + dlen); - } - - /* Lop off the TTL at the expiration time. */ - timetilexp = exptime - now; - if (timetilexp < ttl) { - ns_debug(ns_log_default, 3, - "shrinking expiring %s SIG TTL from %d to %d", - p_secstodate (exptime), ttl, timetilexp); - ttl = timetilexp; - } - - /* The following code is copied from named-xfer.c. */ - cp1 = (u_char *)data; - - /* first just copy over the type_covered, algorithm, */ - /* labels, orig ttl, two timestamps, and the footprint */ - BOUNDS_CHECK(cp, 18); - memcpy(cp1, cp, 18); - cp += 18; - cp1 += 18; - - /* then the signer's name */ - n = dn_expand(msg, eom, cp, (char *)cp1, (sizeof data) - 18); - if (n < 0 || n + NS_SIG_SIGNER > dlen) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 += strlen((char*)cp1)+1; - - /* finally, we copy over the variable-length signature. - Its size is the total data length, minus what we copied. */ - n = dlen - (NS_SIG_SIGNER + n); - - if (n > (sizeof data) - (cp1 - (u_char *)data)) { - hp->rcode = FORMERR; - return (-1); /* out of room! */ - } - - switch (alg) { - case NS_ALG_MD5RSA: - if (n < NS_MD5RSA_MIN_SIZE || n > NS_MD5RSA_MAX_SIZE) - hp->rcode = FORMERR; - break; - - case NS_ALG_DSA: - if (n != NS_DSA_SIG_SIZE) - hp->rcode = FORMERR; - break; - - default: - break; - } - - if (hp->rcode == FORMERR) - return (-1); - - memcpy(cp1, cp, n); - cp += n; - cp1 += n; - - /* compute size of data */ - n = cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - } - - case T_NXT: - n = dn_expand(msg, eom, cp, (char *)data, sizeof data); - /* - * By testing if n >= dlen, we are requiring that the type - * bitmap be at least one octet. This is reasonable - * because we always have to look at the 0 bit to see if - * this is a "different format" NXT or not. - */ - if (n < 0 || n >= dlen) { - hp->rcode = FORMERR; - return (-1); - } - if (!ns_nameok(NULL, (char *)data, class, NULL, response_trans, - domain_ctx, dname, from.sin_addr)) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - n1 = strlen((char *)data) + 1; - cp1 = data + n1; - /* - * We don't need to BOUNDS_CHECK() cp here because we've - * previously checked that 'dlen' bytes are in bounds, and - * we know that n < dlen. - */ - n2 = dlen - n; - /* - * The first bit of the first octet determines the format - * of the NXT record. A format for types >= 128 has not - * yet been defined, so if bit zero is set, we just copy - * what's there because we don't understand it. - */ - if ((*cp & 0x80) == 0) { - /* - * Bit zero is not set; this is an ordinary NXT - * record. The bitmap must be at least 4 octets - * because the NXT bit should be set. It should be - * less than or equal to 16 octets because this NXT - * format is only defined for types < 128. - */ - if (n2 < 4 || n2 > 16) { - hp->rcode = FORMERR; - return (-1); - } - } - if (n2 > sizeof data - n1) { - hp->rcode = FORMERR; - return (-1); - } - memcpy(cp1, cp, n2); - cp += n2; - cp1 += n2; - - /* compute size of data */ - n = cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - - default: - ns_debug(ns_log_default, 3, "unknown type %d", type); - return ((cp - rrp) + dlen); - } - - if (cp > eom) { - hp->rcode = FORMERR; - return (-1); - } - if ((u_int)(cp - rdatap) != dlen) { - ns_debug(ns_log_default, 3, - "encoded rdata length is %u, but actual length was %u", - dlen, (u_int)(cp - rdatap)); - hp->rcode = FORMERR; - return (-1); - } - if (n > MAXDATA) { - ns_debug(ns_log_default, 1, - "update type %d: %d bytes is too much data", - type, n); - hp->rcode = FORMERR; - return (-1); - } - - ttl += tt.tv_sec; - *dpp = savedata(class, type, ttl, cp1, n); - return (cp - rrp); -} - -int -send_msg(u_char *msg, int msglen, struct qinfo *qp) { - HEADER *hp = (HEADER *) msg; - u_char *oldmsg; - int oldlen; - int msgsize; - int ret; - - if (qp->q_flags & Q_SYSTEM) - return (1); - if (!qp->q_stream && (msglen > PACKETSZ)) - msglen = trunc_adjust(msg, msglen, PACKETSZ); - if (ns_wouldlog(ns_log_default, 1)) { - ns_debug(ns_log_default, 1, "send_msg -> %s (%s %d) id=%d", - sin_ntoa(qp->q_from), - qp->q_stream == NULL ? "UDP" : "TCP", - qp->q_stream == NULL ? qp->q_dfd : qp->q_stream->s_rfd, - ntohs(qp->q_id)); - } -#ifdef DEBUG - if (ns_wouldlog(ns_log_default, 4)) { - struct qinfo *tqp; - - for (tqp = nsqhead; tqp != NULL; tqp = tqp->q_link) { - ns_debug(ns_log_default, 4, - "qp %#lx q_id: %d q_nsid: %d q_msglen: %d", - (u_long)tqp, tqp->q_id, - tqp->q_nsid, tqp->q_msglen); - ns_debug(ns_log_default, 4, - "\tq_naddr: %d q_curaddr: %d", - tqp->q_naddr, tqp->q_curaddr); - ns_debug(ns_log_default, 4, - "\tq_next: %#lx q_link: %#lx", - (u_long)qp->q_next, (u_long)qp->q_link); - } - } - if (debug >= 6) - res_pquery(&res, msg, msglen, log_get_stream(packet_channel)); -#endif /* DEBUG */ - - if (qp->q_tsig != NULL) { - u_char sig[TSIG_SIG_SIZE]; - int siglen = sizeof(sig); - - oldmsg = msg; - oldlen = msglen; - - msgsize = msglen + TSIG_BUF_SIZE; - msg = memget(msgsize); - memcpy(msg, oldmsg, oldlen); - - ret = ns_sign(msg, &msglen, msgsize, NOERROR, qp->q_tsig->key, - qp->q_tsig->sig, qp->q_tsig->siglen, - sig, &siglen, 0); - - if (ret != 0) { - INSIST(0); - } - } - - if (qp->q_stream == NULL) { - /* - * Don't send FORMERR to these well known ports - * (loop avoidance). - */ - switch (ntohs(qp->q_from.sin_port)) { - case 7: /* echo */ - case 13: /* daytime */ - case 19: /* chargen */ - case 37: /* time */ - if (hp->rcode == FORMERR) - return (-1); - default: - break; - } - if (sendto(qp->q_dfd, (char*)msg, msglen, 0, - (struct sockaddr *)&qp->q_from, - sizeof(qp->q_from)) < 0) { - if (!haveComplained(ina_ulong(qp->q_from.sin_addr), - (u_long)sendtoStr)) -#if defined(SPURIOUS_ECONNREFUSED) - if (errno != ECONNREFUSED) -#endif - ns_info(ns_log_default, - "send_msg: sendto(%s): %s", - sin_ntoa(qp->q_from), - strerror(errno)); - nameserIncr(qp->q_from.sin_addr, nssSendtoErr); - return (1); - } - } else - writestream(qp->q_stream, (u_char*)msg, msglen); - - if (qp->q_tsig != NULL) - memput(msg, oldlen + TSIG_BUF_SIZE); - - return (0); -} - -static int -root_server_p(ns_class class) { - struct zoneinfo *zp = find_zone("", class); - - return (zp != NULL && - (zp->z_type == z_master || zp->z_type == z_slave)); -} - -void -prime_cache(void) { - int root = root_server_p(ns_c_in); - - ns_debug(ns_log_default, 1, "prime_cache: priming = %d, root = %d", - priming, root); - if (!priming && !root) { - struct qinfo *qp = sysquery("", ns_c_in, ns_t_ns, - NULL, 0, ns_port, ns_o_query); - - if (qp != NULL) { - qp->q_flags |= (Q_SYSTEM | Q_PRIMING); - priming++; - } - } - needs_prime_cache = 0; -} - -struct qinfo * -sysquery(const char *dname, int class, int type, - struct in_addr *nss, int nsc, u_int16_t port, int opcode) -{ - struct qinfo *qp, *oqp; - HEADER *hp; - char tmpdomain[MAXDNAME]; - struct namebuf *np = NULL; - struct databuf *nsp[NSMAX]; - struct hashbuf *htp1; - struct hashbuf *htp2; - struct hashbuf *htp3; - struct sockaddr_in *nsa; - const char *fname; - int n, count; - int sendto_errno = 0; - u_char *oldqbuf; - int oldqlen, has_tsig; - u_char *smsg; - int smsglen, smsgsize, siglen; - u_char sig[TSIG_SIG_SIZE]; - DST_KEY *key; - - nsp[0] = NULL; - ns_debug(ns_log_default, 3, "sysquery(%s, %d, %d, %#x, %d, %d)", - dname, class, type, nss, nsc, ntohs(port)); - qp = qnew(dname, class, type, (nss != NULL && nsc != 0) ? 0 : 1); - - if (nss != NULL && nsc != 0) - np = NULL; - else if (!NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) { - htp1 = hashtab; - htp2 = hashtab; - htp3 = fcachetab; - if (priming && dname[0] == '\0') { - np = NULL; - } else if (((np = nlookup(dname, &htp1, &fname, 0)) == NULL) && - ((np = nlookup("", &htp2, &fname, 0)) == NULL) && - ((np = nlookup("", &htp3, &fname, 0)) == NULL)) { - ns_info(ns_log_default, - "sysquery: nlookup error on %s?", - dname); - err1: - ns_freeqry(qp); - return (NULL); - } - - n = findns(&np, class, nsp, &count, 0); - switch (n) { - case NXDOMAIN: - case SERVFAIL: - ns_info(ns_log_default, - "sysquery: findns error (%s) on %s?", - n == NXDOMAIN ? "NXDOMAIN" : "SERVFAIL", - dname); - err2: - free_nsp(nsp); - goto err1; - } - } - - /* Build new qinfo struct. */ - qp->q_cmsg = qp->q_msg = NULL; - qp->q_dfd = ds; - if (nss == NULL || nsc == 0) - nsfwdadd(qp, NS_ZFWDTAB(qp->q_fzone)); - qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2; - qp->q_flags |= Q_SYSTEM; - - getname(np, tmpdomain, sizeof tmpdomain); - qp->q_domain = savestr(tmpdomain, 1); - - if ((qp->q_msg = (u_char *)memget(PACKETSZ)) == NULL) { - ns_notice(ns_log_default, "sysquery: memget failed"); - goto err2; - } - qp->q_msgsize = PACKETSZ; - n = res_nmkquery(&res, opcode, dname, class, - type, NULL, 0, NULL, - qp->q_msg, PACKETSZ); - if (n < 0) { - ns_info(ns_log_default, - "sysquery: res_mkquery(%s) failed", dname); - goto err2; - } - qp->q_msglen = n; - hp = (HEADER *) qp->q_msg; - hp->id = qp->q_nsid = htons(nsid_next()); - hp->rd = (qp->q_addr[qp->q_curaddr].forwarder ? 1 : 0); - hp->aa = (opcode == NS_NOTIFY_OP); - - /* First check for an already pending query for this data. */ - for (oqp = nsqhead; oqp != NULL; oqp = oqp->q_link) { - if ((oqp != qp) - && (oqp->q_msglen == qp->q_msglen) - && memcmp(oqp->q_msg+2, qp->q_msg + 2, - qp->q_msglen - 2) == 0 - ) { -#ifdef BIND_NOTIFY - /* XXX - need fancier test to suppress duplicate - * NOTIFYs to the same server (compare nss?) - */ - if (opcode != NS_NOTIFY_OP) -#endif /*BIND_NOTIFY*/ - { - ns_debug(ns_log_default, 3, - "sysquery: duplicate"); - goto err2; - } - } - } - - if (nss != NULL && nsc != 0) { - int i; - struct qserv *qs; - - for (i = 0, qs = qp->q_addr; i < nsc; i++, qs++) { - qs->ns_addr.sin_family = AF_INET; - qs->ns_addr.sin_addr = nss[i]; - qs->ns_addr.sin_port = port; - qs->ns = NULL; - qs->nsdata = NULL; - qs->stime = tt; - qs->forwarder = 0; - qs->nretry = 0; - } - qp->q_naddr = nsc; - } else if (!NS_ZOPTION_P(qp->q_fzone, OPTION_FORWARD_ONLY)) { - fetch_a: - count = nslookup(nsp, qp, dname, "sysquery"); - if (count <= 0) { - if (count < 0) { - if (n == -1) - ns_info(ns_log_default, - "sysquery: nslookup reports danger (%s)", - dname); - goto err2; - } else if (np && NAME(*np)[0] == '\0') { - /* - * It's not too serious if we don't have - * the root server addresses if we have to - * go through a forwarder anyway. Don't - * bother to log it, since prime_cache() - * won't do anything about it as currently - * implemented. - * - * XXX - should we skip setting - * needs_prime_cache as well? - * - * XXX - what happens when we implement - * selective forwarding? - */ - if (!NS_OPTION_P(OPTION_FORWARD_ONLY)) - ns_warning(ns_log_default, - "sysquery: no addrs found for root NS (%s)", - dname); - if (class == C_IN && !priming) - needs_prime_cache = 1; - goto err2; - } - if (np) { - free_nsp(nsp); - nsp[0] = NULL; - np = np_parent(np); - n = findns(&np, class, nsp, &count, 0); - switch (n) { - case NXDOMAIN: /*FALLTHROUGH*/ - case SERVFAIL: - ns_info(ns_log_default, - "sysquery: findns error (%d) on %s?", - n, dname); - goto err2; - } - getname(np, tmpdomain, sizeof tmpdomain); - if (qp->q_domain != NULL) - freestr(qp->q_domain); - qp->q_domain = savestr(tmpdomain, 1); - goto fetch_a; - } - goto err2; - } - } - - schedretry(qp, retrytime(qp)); - qp->q_addr[0].stime = tt; /* XXX - why not every? */ - nsa = Q_NEXTADDR(qp, 0); - - ns_debug(ns_log_default, 1, - "sysquery: send -> %s dfd=%d nsid=%d id=%d retry=%ld", - sin_ntoa(*nsa), qp->q_dfd, - ntohs(qp->q_nsid), ntohs(qp->q_id), - (long)qp->q_time); -#ifdef DEBUG - if (debug >= 10) - res_pquery(&res, qp->q_msg, qp->q_msglen, - log_get_stream(packet_channel)); -#endif - - key = tsig_key_from_addr(nsa->sin_addr); - if (key != NULL) { - smsgsize = qp->q_msglen + TSIG_BUF_SIZE; - smsg = memget(smsgsize); - smsglen = qp->q_msglen; - siglen = sizeof(sig); - memcpy(smsg, qp->q_msg, qp->q_msglen); - n = ns_sign(smsg, &smsglen, smsgsize, NOERROR, key, NULL, 0, - sig, &siglen, 0); - if (n == 0) { - oldqbuf = qp->q_msg; - oldqlen = qp->q_msglen; - qp->q_msglen = smsglen; - qp->q_msg = smsg; - has_tsig = 1; - qp->q_nstsig = new_tsig(key, sig, siglen); /* BEW? */ - - } - else { - INSIST(0); - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - } - } - else { - has_tsig = 0; - free_tsig(qp->q_nstsig); - qp->q_nstsig = NULL; - } - - if (sendto(qp->q_dfd, (char*)qp->q_msg, qp->q_msglen, 0, - (struct sockaddr *)nsa, - sizeof(struct sockaddr_in)) < 0) { - sendto_errno = errno; - if (!haveComplained(ina_ulong(nsa->sin_addr), - (u_long)sendtoStr)) - ns_info(ns_log_default, "sysquery: sendto(%s): %s", - sin_ntoa(*nsa), strerror(errno)); - nameserIncr(nsa->sin_addr, nssSendtoErr); - } - if (has_tsig == 1) { - memput(qp->q_msg, smsgsize); - qp->q_msg = oldqbuf; - qp->q_msglen = oldqlen; - } - - nameserIncr(nsa->sin_addr, nssSentSysQ); - free_nsp(nsp); - switch (sendto_errno) { - case ENETDOWN: - case ENETUNREACH: - case EHOSTDOWN: - case EHOSTUNREACH: - unsched(qp); - schedretry(qp, (time_t) 0); - } - return (qp); -} - -/* - * Check the list of root servers after receiving a response - * to a query for the root servers. - */ -static int -check_root() { - struct databuf *dp, *pdp; - struct namebuf *np; - int count = 0; - - priming = 0; - for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next) - if (NAME(*np)[0] == '\0') - break; - if (np == NULL) { - ns_notice(ns_log_default, "check_root: Can't find root!"); - return (0); - } - for (dp = np->n_data; dp != NULL; dp = dp->d_next) - if (dp->d_type == T_NS) - count++; - ns_debug(ns_log_default, 1, "%d root servers", count); - if (count < server_options->minroots) { - ns_notice(ns_log_default, - "check_root: %d root servers after query to root server < min", - count); - return (0); - } - pdp = NULL; - dp = np->n_data; - while (dp != NULL) { - if (dp->d_type == T_NS && dp->d_zone == DB_Z_CACHE && - dp->d_ttl < (u_int32_t)tt.tv_sec) { - ns_debug(ns_log_default, 1, - "deleting old root server '%s'", - dp->d_data); - dp = rm_datum(dp, np, pdp, NULL); - /* SHOULD DELETE FROM HINTS ALSO */ - continue; - } - pdp = dp; - dp = dp->d_next; - } - if (check_ns()) - return (1); - else { - priming = 1; - return (0); - } -} - -/* - * Check the root to make sure that for each NS record we have a A RR - */ -static int -check_ns() { - struct databuf *dp, *tdp; - struct namebuf *np, *tnp; - struct hashbuf *htp; - char *dname; - int found_arr; - const char *fname; - time_t curtime; - int servers = 0, rrsets = 0; - - ns_debug(ns_log_default, 2, "check_ns()"); - - curtime = (u_int32_t) tt.tv_sec; - for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next) { - if (NAME(*np)[0] != '\0') - continue; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - int cnames = 0; - - if (dp->d_rcode) - continue; - - if (dp->d_type != T_NS) - continue; - - servers++; - - /* look for A records */ - dname = (caddr_t) dp->d_data; - htp = hashtab; - tnp = nlookup(dname, &htp, &fname, 0); - if (tnp == NULL || fname != dname) { - ns_debug(ns_log_default, 3, - "check_ns: %s: not found %s %#lx", - dname, fname, (u_long)tnp); - sysquery(dname, dp->d_class, T_A, NULL, - 0, ns_port, QUERY); - continue; - } - /* look for name server addresses */ - found_arr = 0; - (void)delete_stale(tnp); - for (tdp = tnp->n_data; - tdp != NULL; - tdp = tdp->d_next) { - if (tdp->d_rcode) - continue; - if (tdp->d_type == T_CNAME) - cnames++; - if (tdp->d_type != T_A || - tdp->d_class != dp->d_class) - continue; - if ((tdp->d_zone == DB_Z_CACHE) && - (tdp->d_ttl < (u_int32_t)curtime)) { - ns_debug(ns_log_default, 3, - "check_ns: stale entry '%s'", - NAME(*tnp)); - found_arr = 0; - break; - } - found_arr++; - } - if (found_arr) - rrsets++; - else if (cnames > 0) - ns_info(ns_log_default, - "Root NS %s -> CNAME %s", - NAME(*np), NAME(*tnp)); - else - sysquery(dname, dp->d_class, T_A, NULL, - 0, ns_port, QUERY); - } - } - - ns_debug(ns_log_default, 2, "check_ns: %d %d", servers, rrsets); - return ((servers <= 2) - ? (rrsets == servers) - : ((rrsets * 2) >= servers) - ); -} - -/* int findns(npp, class, nsp, countp, flag) - * Find NS's or an SOA - * npp, class: - * dname whose most enclosing NS is wanted - * nsp, countp: - * result array and count; array will also be NULL terminated - * flag: - * boolean: we're being called from ADDAUTH, bypass authority checks - * return value: - * NXDOMAIN: we are authoritative for this {dname,class} - * *countp is bogus, but nsp[] has a single SOA returned in it. - * SERVFAIL: we are auth but zone isn't loaded; or, no root servers found - * *countp and nsp[] are bogus. - * OK: we are not authoritative, and here are the NS records we found. - * *countp and nsp[] return NS records of interest. - */ -int -findns(struct namebuf **npp, int class, - struct databuf **nsp, int *countp, int flag) -{ - struct namebuf *np = *npp; - struct databuf *dp; - struct databuf **nspp; - struct hashbuf *htp; - - nsp[0] = NULL; - - if (priming && (np == NULL || NAME(*np)[0] == '\0')) - htp = fcachetab; - else - htp = hashtab; - - try_again: - if (htp == fcachetab && class == C_IN && !priming) - /* - * XXX - do we want to set needs_prime_cache if - * OPTION_FORWARD_ONLY? - */ - needs_prime_cache = 1; - if (np == NULL) { - /* find the root */ - for (np = htp->h_tab[0]; np != NULL; np = np->n_next) - if (NAME(*np)[0] == '\0') - break; - } - while (np != NULL) { - ns_debug(ns_log_default, 5, "findns: np %#x '%s'", np, - NAME(*np)); - /* Look first for SOA records. */ -#ifdef ADDAUTH - if (!flag) -#endif - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (dp->d_zone != DB_Z_CACHE && - ((zones[dp->d_zone].z_type == Z_PRIMARY) || - (zones[dp->d_zone].z_type == Z_SECONDARY)) && - match(dp, class, T_SOA) && dp->d_type == T_SOA) { - ns_debug(ns_log_default, 3, - "findns: SOA found"); - if (zones[dp->d_zone].z_flags & Z_AUTH) { - *npp = np; - nsp[0] = dp; - nsp[1] = NULL; - DRCNTINC(dp); - return (NXDOMAIN); - } else { - /* XXX: zone isn't loaded but we're - * primary or secondary for it. - * should we fwd this? - */ - return (SERVFAIL); - } - } - } - - /* If no SOA records, look for NS records. */ - nspp = &nsp[0]; - *nspp = NULL; - (void)delete_stale(np); - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!match(dp, class, T_NS)) - continue; - if (dp->d_rcode) - continue; - /* - * Don't use records that may become invalid to - * reference later when we do the rtt computation. - * Never delete our safety-belt information! - * - * XXX: this is horribly bogus. - */ - if ((dp->d_zone == DB_Z_CACHE) && - (dp->d_ttl < (u_int32_t)tt.tv_sec) && - !(dp->d_flags & DB_F_HINT)) { - ns_debug(ns_log_default, 1, - "findns: stale entry '%s'", - NAME(*np)); - /* - * We may have already added NS databufs - * and are going to throw them away. Fix - * reference counts. We don't need to free - * them here as we just got them from the - * cache. - */ - while (nspp > &nsp[0]) { - nspp--; - DRCNTDEC(*nspp); - } - nsp[0] = NULL; - goto try_parent; - } - if (nspp < &nsp[NSMAX-1]) { - *nspp++ = dp; - DRCNTINC(dp); - } - } - - *countp = nspp - nsp; - if (*countp > 0) { - ns_debug(ns_log_default, 3, - "findns: %d NS's added for '%s'", - *countp, NAME(*np)); - *nspp = NULL; - *npp = np; - return (OK); /* Success, got some NS's */ - } - try_parent: - np = np_parent(np); - } - if (htp == hashtab) { - htp = fcachetab; - goto try_again; - } - ns_debug(ns_log_default, 1, - "findns: No root nameservers for class %s?", p_class(class)); - if ((unsigned)class < MAXCLASS && norootlogged[class] == 0) { - norootlogged[class] = 1; - ns_info(ns_log_default, "No root nameservers for class %s", - p_class(class)); - } - return (SERVFAIL); -} - - -/* - * Extract RR's from the given node that match class and type. - * Return number of bytes added to response. - * If no matching data is found, then 0 is returned. - */ -int -finddata(struct namebuf *np, int class, int type, - HEADER *hp, char **dnamep, int *lenp, int *countp) -{ - struct databuf *dp; - char *cp; - int buflen, n, count = 0; - char *new_dnamep = NULL; - int defer = 0, found_count = 0, choice, i; - struct databuf **found = NULL; - struct databuf **tmpfound = NULL; - int foundcname; - int stalecount; - int ret = 0; - - stalecount = delete_stale(np); - - /* We don't want to return cached SIG records when asked for SIGs, - * since we may have an incomplete set. - */ - if (type == T_SIG && findMyZone(np, class) == DB_Z_CACHE) - return(0); - - if (type != T_ANY && type != T_PTR && type != T_NXT) { - found = memget((stalecount + 1) * sizeof *found); - tmpfound = memget((stalecount + 1) * sizeof *tmpfound); - if (found == NULL || tmpfound == NULL) - ns_panic(ns_log_default, 1, "finddata: out of memory"); - defer = 1; - } - - buflen = *lenp; - -#ifdef DEBUG - if (buflen > PACKETSZ) - ns_debug(ns_log_default, 1, "finddata(): buflen=%d", buflen); -#endif - cp = ((char *)hp) + *countp; - foundcname = 0; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!wanted(dp, class, type)) { - if (type == T_CNAME && class == dp->d_class) { - /* any data means no CNAME exists */ - if (dp->d_type != T_NXT && - dp->d_type != T_KEY && - dp->d_type != T_SIG) { - ret = 0; - goto done; - } - } - continue; - } - if (dp->d_cred == DB_C_ADDITIONAL) { -#ifdef NOADDITIONAL - continue; -#else - /* we want to expire additional data very - * quickly. current strategy is to cut 5% - * off each time it is accessed. this makes - * stale(dp) true earlier when this datum is - * used often. - */ - dp->d_ttl = tt.tv_sec - + - 0.95 * (int) (dp->d_ttl - tt.tv_sec); -#endif - } - /* -ve $ing stuff, anant@isi.edu - * if we have a -ve $ed record, change the rcode on the - * header to reflect that - */ - if (dp->d_rcode == NOERROR_NODATA) { - if (count != 0) { - /* - * This should not happen, yet it does... - */ - ns_info(ns_log_default, - "NODATA & data for \"%s\" type %d class %d", - *dnamep, type, class); - continue; - } - if (type == T_ANY) - continue; - hp->rcode = NOERROR_NODATA; - if (dp->d_size == 0) { /* !RETURNSOA */ - ret = 1; - goto done; - } - } - if (dp->d_rcode == NXDOMAIN) { - if (count != 0) { - /* - * This should not happen, yet it might... - */ - ns_info(ns_log_default, - "NXDOMAIN & data for \"%s\" type %d class %d", - *dnamep, type, class); - continue; - } - hp->rcode = NXDOMAIN; - if (dp->d_size == 0) { /* !RETURNSOA */ - ret = 1; - goto done; - } - } - - /* Don't put anything but key or sig RR's in response to - requests for key or sig */ - if (((type == T_SIG) || (type == T_KEY)) && - (!((dp->d_type == T_SIG) || (dp->d_type == T_KEY))) ) - continue; - - if (!defer) { - if (foundcname != 0 && dp->d_type == T_CNAME) - continue; - - if ((n = make_rr(*dnamep, dp, (u_char *)cp, buflen, 1, - dnptrs, dnptrs_end, 0)) < 0) { - hp->tc = 1; - ret = *lenp - buflen; - goto done; - } - if (dp->d_secure != DB_S_SECURE) - hp->ad = 0; - cp += n; - buflen -= n; - count++; - - if (dp->d_type == T_CNAME) { - foundcname = 1; -#define FOLLOWCNAME(type) \ - (type != T_KEY) && (type != T_SIG) && (type != T_NXT) && (type != T_ANY) - /* don't alias if querying for key, sig, nxt, or any */ - - if (FOLLOWCNAME(type)) - new_dnamep = (char *)dp->d_data; - } - } else { - if (dp->d_type == T_CNAME) - foundcname = 1; - found[found_count++] = dp; - } - } - - if (found_count == 0 && count == 0) { - ret = 0; - goto done; - } - - /* - * If the query type was SIG or ANY we will have returned the SIG - * records already. - */ - if (type != T_SIG && type != T_ANY) { - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!wantedsig(dp, class, type)) - continue; - if (dp->d_cred == DB_C_ADDITIONAL) { -#ifdef NOADDITIONAL - continue; -#else - /* we want to expire additional data very - * quickly. current strategy is to cut 5% - * off each time it is accessed. this makes - * stale(dp) true earlier when this datum is - * used often. - */ - dp->d_ttl = tt.tv_sec - + - 0.95 * (int) (dp->d_ttl - tt.tv_sec); -#endif - } - if (!defer) { - if ((n = make_rr(*dnamep, dp, (u_char *)cp, - buflen, 1, dnptrs, dnptrs_end, - 0)) < 0) { - hp->tc = 1; - ret = *lenp - buflen; - goto done; - } - if (dp->d_secure != DB_S_SECURE) - hp->ad = 0; - cp += n; - buflen -= n; - count++; - } else - found[found_count++] = dp; - } - } - - if (defer && found_count > 0) { - int first_sig; - int non_sig_count; - int sig_count; /* number of SIG records in found */ - int idx, jdx; - enum ordering order; - - order = match_order(np, class, foundcname ? T_CNAME : type); - - /* shuffle the SIG records down to the bottom of the array - * as we need to make sure they get packed last, no matter - * what the ordering is. We're sure to maintain the - * original ordering within the two sets of records (so - * that fixed_order can work). - * First we pack the non-SIG records into the temp array. - */ - for (idx = jdx = 0 ; idx < found_count ; idx++) { - if (found[idx]->d_type != T_SIG) { - tmpfound[jdx++] = found[idx]; - } - } - non_sig_count = jdx; - sig_count = found_count - jdx; - first_sig = jdx ; - - /* now shift the SIG records down to the end of the array - * and copy in the non-SIG records - */ - for (i = idx = found_count - 1 ; idx >= 0 ; idx--) { - if (i < non_sig_count) { - found[i] = tmpfound[i]; - i--; - } else if (found[idx]->d_type == T_SIG) { - found[i--] = found[idx] ; - } - } - - foundcname = 0; - switch (order) { - case fixed_order: - for (i = 0; i < found_count; i++) { - dp = found[i]; - if (foundcname != 0 && dp->d_type == T_CNAME) - continue; - if (dp->d_type == T_CNAME) { - foundcname = 1; - if (FOLLOWCNAME(type)) { - new_dnamep = (char *)dp->d_data; - } - } - if ((n = make_rr(*dnamep, dp, (u_char *)cp, - buflen, 1, - dnptrs, dnptrs_end, 0)) < 0) { - hp->tc = 1; - ret = *lenp - buflen; - goto done; - } - if (dp->d_secure != DB_S_SECURE) - hp->ad = 0; - cp += n; - buflen -= n; - count++; - } - break; - - case random_order: { - /* first we shuffle the non-SIG records */ - int iters = non_sig_count; - for (i = 0; i < iters; i++) { - choice = ((u_int)rand()>>3) % non_sig_count; - non_sig_count--; - dp = found[choice]; - found[choice] = found[non_sig_count]; - if (foundcname != 0 && dp->d_type == T_CNAME) - continue; - if (dp->d_type == T_CNAME) { - foundcname = 1; - if (FOLLOWCNAME(type)) { - new_dnamep = (char *)dp->d_data; - } - } - if ((n = make_rr(*dnamep, dp, (u_char *)cp, - buflen, 1, - dnptrs, dnptrs_end, 0)) < 0) { - hp->tc = 1; - ret = *lenp - buflen; - goto done; - } - if (dp->d_secure != DB_S_SECURE) - hp->ad = 0; - cp += n; - buflen -= n; - count++; - } - - /* now shuffle the SIG records */ - iters = sig_count; - for (i = 0; i < iters; i++) { - choice = ((u_int)rand()>>3) % sig_count; - choice += first_sig; - sig_count--; - dp = found[choice]; - found[choice] = found[sig_count + first_sig]; - if ((n = make_rr(*dnamep, dp, (u_char *)cp, - buflen, 1, - dnptrs, dnptrs_end, 0)) < 0) { - hp->tc = 1; - ret = *lenp - buflen; - goto done; - } - if (dp->d_secure != DB_S_SECURE) - hp->ad = 0; - cp += n; - buflen -= n; - count++; - } - break; - } - - case cyclic_order: - /* first we do the non-SIG records */ - if (non_sig_count > 0) - choice = ((u_int)rand()>>3) % non_sig_count; - else - choice = 0; - for (i = 0; i < non_sig_count ; i++) { - dp = found[(i + choice) % non_sig_count]; - if (foundcname != 0 && dp->d_type == T_CNAME) - continue; - if (dp->d_type == T_CNAME) { - foundcname = 1; - if (FOLLOWCNAME(type)) { - new_dnamep = (char *)dp->d_data; - } - } - if ((n = make_rr(*dnamep, dp, (u_char *)cp, - buflen, 1, - dnptrs, dnptrs_end, 0)) < 0) { - hp->tc = 1; - ret = *lenp - buflen; - goto done; - } - if (dp->d_secure != DB_S_SECURE) - hp->ad = 0; - cp += n; - buflen -= n; - count++; - } - - /* now do the SIG record rotation. */ - if (sig_count > 0) { - choice = ((u_int)rand()>>3) % sig_count; - choice += first_sig; - i = choice; - do { - dp = found[i]; - if ((n = make_rr(*dnamep, dp, - (u_char *)cp, - buflen, 1, - dnptrs, - dnptrs_end, 0)) < 0) { - hp->tc = 1; - ret = *lenp - buflen; - goto done; - } - if (dp->d_secure != DB_S_SECURE) - hp->ad = 0; - cp += n; - buflen -= n; - count++; - i++; - if (i >= found_count) - i = first_sig; - } while (i != choice); - } - - break; - - default: - ns_warning(ns_log_default, "finddata: unknown ordering: %d", - order); - break; - } - } - - if (new_dnamep != NULL) - *dnamep = new_dnamep; - - ns_debug(ns_log_default, 3, "finddata: added %d class %d type %d RRs", - count, class, type); - ret = *lenp - buflen; - done: - if (found != NULL) - memput(found, (stalecount + 1) * sizeof *found); - if (tmpfound != NULL) - memput(tmpfound, (stalecount + 1) * sizeof *tmpfound); - *countp = count; - return (ret); -} - -/* - * Do we want this data record based on the class and type? - */ -static int -wanted(const struct databuf *dp, int class, int type) { - const u_char *cp; - int coveredType; - time_t expiration; -#ifdef DEBUG - char pclass[15], ptype[15]; -#endif - -#ifdef DEBUG - strcpy(pclass, p_class(class)); - strcpy(ptype, p_type(type)); - ns_debug(ns_log_default, 3, "wanted(%#x, %s %s) [%s %s]", - dp, pclass, ptype, - p_class(dp->d_class), p_type(dp->d_type)); -#endif - - if (dp->d_class != class && class != C_ANY) - return (0); - /* - * Must check SIG for expiration below, other matches - * return OK here. - */ - if (type == dp->d_type && (type != T_SIG)) - return (1); - /* For a T_ANY query, we do not want to return -ve $ed RRs. */ - if (type == T_ANY && dp->d_rcode == NOERROR_NODATA) - return (0); - - /* First, look at the type of RR. */ - switch (dp->d_type) { - - /* Cases to deal with: - T_ANY search, return all unexpired SIGs. - T_SIG search, return all unexpired SIGs. - T_<foo> search, return all unexp SIG <FOO>s. - */ - case T_SIG: - cp = dp->d_data; - GETSHORT(coveredType, cp); - cp += INT16SZ + INT32SZ; /* skip alg, labels, & orig TTL */ - GETLONG(expiration,cp); - - if (type == T_ANY || type == T_SIG) { - if (expiration > time(0)) - return (1); /* Unexpired matching SIG */ - } - return (0); /* We don't return this SIG. */ - - case T_ANY: - return (1); - case T_CNAME: - if (dp->d_rcode != NOERROR_NODATA) - return (1); - else - break; - } - /* OK, now look at the type of query. */ - if (type == ns_t_any) - return (1); - else if (type == ns_t_mailb) - switch (dp->d_type) { - case T_MR: - case T_MB: - case T_MG: - case T_MINFO: - return (1); - } - else if (ns_t_xfr_p(type)) { - /* - * This is used to validate transfer requests, not - * generate transfer responses. Is there an SOA? - */ - if (dp->d_type == ns_t_soa && dp->d_zone != DB_Z_CACHE - && (zones[dp->d_zone].z_flags & Z_AUTH)) - return (1); - } - return (0); -} - -static int -wantedsig(const struct databuf *dp, int class, int type) { - const u_char *cp; - int coveredType; - time_t expiration; -#ifdef DEBUG - char pclass[15], ptype[15]; -#endif - -#ifdef DEBUG - strcpy(pclass, p_class(class)); - strcpy(ptype, p_type(type)); - ns_debug(ns_log_default, 3, "wantedtsig(%#x, %s %s) [%s %s]", - dp, pclass, ptype, - p_class(dp->d_class), p_type(dp->d_type)); -#endif - - if (dp->d_class != class && class != C_ANY) - return (0); - if (dp->d_type != T_SIG || dp->d_rcode != 0) - return (0); - - cp = dp->d_data; - GETSHORT(coveredType, cp); - cp += INT16SZ + INT32SZ; /* skip alg, labels, & orig TTL */ - GETLONG(expiration,cp); - if (expiration < time(0)) - return (0); - - if (type == T_ANY || type == T_SIG || type == coveredType) - return (1); - if (type == ns_t_mailb) { - switch (coveredType) { - case T_MR: - case T_MB: - case T_MG: - case T_MINFO: - return (1); - } - } - return (0); -} - -/* - * Add RR entries from dpp array to a query/response. - * Return the number of bytes added or negative the amount - * added if truncation occured. Typically you are - * adding NS records to a response. - */ -int -add_data(struct namebuf *np, struct databuf **dpp, - u_char *cp, int buflen, int *countp) -{ - struct databuf *dp; - char dname[MAXDNAME]; - int n, bytes; - - bytes = *countp = 0; - getname(np, dname, sizeof(dname)); - for (dp = *dpp++; dp != NULL; dp = *dpp++) { - if (stale(dp)) - continue; /* ignore old cache entry */ - if (dp->d_rcode) - continue; - if ((n = make_rr(dname, dp, cp, buflen, 1, - dnptrs, dnptrs_end, 0)) < 0) - return (-bytes); /* Truncation */ - cp += n; - buflen -= n; - bytes += n; - (*countp)++; - } - return (bytes); -} - -static void -rrsetadd(struct flush_set *flushset, const char *name, struct databuf *dp) { - struct flush_set *fs = flushset; - struct db_list *dbl; - - while (fs->fs_name && ( - ns_samename(fs->fs_name,name) != 1 || - (fs->fs_class != dp->d_class) || - (fs->fs_type != dp->d_type) || - (fs->fs_cred != dp->d_cred))) { - fs++; - } - if (!fs->fs_name) { - fs->fs_name = savestr(name, 1); - fs->fs_class = dp->d_class; - fs->fs_type = dp->d_type; - fs->fs_cred = dp->d_cred; - fs->fs_list = NULL; - fs->fs_last = NULL; - } - dbl = (struct db_list *)memget(sizeof(struct db_list)); - if (!dbl) - panic("rrsetadd: out of memory", NULL); - dbl->db_next = NULL; - dbl->db_dp = dp; - if (fs->fs_last == NULL) - fs->fs_list = dbl; - else - fs->fs_last->db_next = dbl; - fs->fs_last = dbl; -} - -static int -ttlcheck(const char *name, struct db_list *dbl, int update) { - int type = dbl->db_dp->d_type; - int class = dbl->db_dp->d_class; - struct hashbuf *htp = hashtab; - const char *fname; - struct namebuf *np; - struct db_list *dbp = dbl; - struct databuf *dp; - u_int32_t ttl = 0; /* Make gcc happy. */ - int first; - - - np = nlookup(name, &htp, &fname, 0); - if (np == NULL || fname != name || ns_wildcard(NAME(*np))) - return (1); - - /* check that all the ttl's we have are the same, if not return 1 */ - first = 1; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!match(dp, class, type)) - continue; - if (first) { - /* we can't update zone data so return early */ - if (dp->d_zone != DB_Z_CACHE) - return (0); - ttl = dp->d_ttl; - first = 0; - } else if (ttl != dp->d_ttl) - return (1); - } - - /* there are no records of this type in the cache */ - if (first) - return(1); - - /* - * the ttls of all records we have in the cache are the same - * if the ttls differ in the new set we don't want it. - */ - - /* check that all the ttl's we have are the same, if not return 0 */ - first = 1; - while (dbp) { - if (first) { - ttl = dbp->db_dp->d_ttl; - first = 0; - } else if (ttl != dbp->db_dp->d_ttl) { - return(0); - } - dbp = dbp->db_next; - } - - /* update ttl if required */ - if (update) { - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!match(dp, class, type)) - continue; - if (dp->d_ttl > ttl) - break; - dp->d_ttl = ttl; - fixttl(dp); - } - } - - return(1); -} - -/* - * lookup rrset in table and compare to dbl - * tri state result - * -1: lookup failed - * 0: rrsets same - * 1: rrsets differ - */ - -static int -rrsetcmp(char * name, struct db_list * dbl, struct hashbuf * table) { - int type = dbl->db_dp->d_type; - int class = dbl->db_dp->d_class; - struct hashbuf *htp = table; - const char *fname; - struct namebuf *np; - struct db_list *dbp = dbl; - struct databuf *dp; - int exists = 0; - - - np = nlookup(name, &htp, &fname, 0); - if (np == NULL || fname != name || ns_wildcard(NAME(*np))) { - ns_debug(ns_log_default, 3, "rrsetcmp: name not in database"); - return (-1); - } - - /* check that all entries in dbl are in the cache */ - while (dbp) { - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!match(dp, class, type)) - continue; - exists = 1; - if (!db_cmp(dp, dbp->db_dp) -#ifdef NOADDITIONAL - && ((dp->d_cred == dbp->db_dp->d_cred) || - (dp->d_cred != DB_C_ADDITIONAL)) -#endif - ) - break; - } - if (!dp) { - ns_debug(ns_log_default, 3, - "rrsetcmp: %srecord%s in database", - exists ? "" : "no ", exists ? " not" : "s"); - return (exists ? 1 : -1); - } - dbp = dbp->db_next; - } - - /* Check that all cache entries are in the list. */ - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!match(dp, class, type)) - continue; -#ifdef NCACHE - if (dp->d_rcode) - return (1); -#endif - dbp = dbl; - while (dbp) { - if (!db_cmp(dp, dbp->db_dp)) - break; - dbp = dbp->db_next; - } - if (!dbp) { - ns_debug(ns_log_default, 3, - "rrsetcmp: record not in rrset"); - return (1); - } - } - ns_debug(ns_log_default, 3, "rrsetcmp: rrsets matched"); - return (0); -} - -/* - * verify incoming answer against what we already have in the hints - * issue warnings / errors if differences detected. - */ - -static void -check_hints(struct flush_set * flushset) { - struct zoneinfo *zp; - struct flush_set *fs; - struct db_list *dbp; - - /* We don't use hints when in forward only mode */ - if (NS_OPTION_P(OPTION_FORWARD_ONLY)) - return; - - /* find "." NS rrset and hence class */ - for (fs = flushset; fs->fs_name != NULL; fs++) { - if ((fs->fs_name[0] != '\0') || (fs->fs_type != ns_t_ns)) - continue; - - /* see if we are a root server */ - zp = find_zone(fs->fs_name, fs->fs_class); - if (zp != NULL && - (zp->z_type == z_master || zp->z_type == z_slave)) - return; - switch (rrsetcmp(fs->fs_name, fs->fs_list, fcachetab)) { - case -1: - ns_error(ns_log_default, - "check_hints: no NS records for class %d in hints", - fs->fs_class); - break; - case 1: - ns_warning(ns_log_default, - "check_hints: root NS list in hints for class %d does not match root NS list", - fs->fs_class); - break; - case 0: - break; - default: - ns_error(ns_log_default, - "check_hints: unexpected response from rrsetcmp"); - break; - } - break; - } - - if (fs->fs_name == NULL) /* no root NS records */ - return; - - dbp = fs->fs_list; - while (dbp) { - /* for each NS find A rrset in answer and check */ - for (fs = flushset; fs->fs_name != NULL; fs++) { - if (ns_samename(fs->fs_name, (char *)dbp->db_dp->d_data) != 1 - || fs->fs_type != ns_t_a) - continue; - switch (rrsetcmp(fs->fs_name, fs->fs_list, fcachetab)) { - case -1: - ns_error(ns_log_default, - "check_hints: no A records for %s class %d in hints", - fs->fs_name[0] ? fs->fs_name : ".", - fs->fs_class); - break; - case 1: - ns_warning(ns_log_default, - "check_hints: A records for %s class %d do not match hint records", - fs->fs_name[0] ? fs->fs_name : ".", - fs->fs_class); - break; - case 0: - break; - default: - ns_error(ns_log_default, - "check_hints: unexpected response from rrsetcmp"); - break; - } - break; - } - - if (fs->fs_name == NULL) - ns_debug(ns_log_default, 2, - "check_hints: no A records for %s", - dbp->db_dp->d_data); - - dbp = dbp->db_next; - } -} - -static void -rrsetupdate(struct flush_set * flushset, int flags, struct sockaddr_in from, - int updatettl) { - struct flush_set *fs = flushset; - struct db_list *dbp, *odbp; - int n; - void *state = NULL; - - while (fs->fs_name) { - ns_debug(ns_log_default, 2, "rrsetupdate: %s", - fs->fs_name[0] ? fs->fs_name : "."); - if ((n = rrsetcmp(fs->fs_name, fs->fs_list, hashtab)) && - ttlcheck(fs->fs_name, fs->fs_list, 0)) { - if (n > 0) - flushrrset(fs, from); - - dbp = fs->fs_list; - while (dbp) { - n = db_set_update(fs->fs_name, dbp->db_dp, - &state, flags, - &hashtab, from, NULL, - 0, NULL); - ns_debug(ns_log_default, 3, - "rrsetupdate: %s %d", - fs->fs_name[0] ? fs->fs_name : ".", - n); - odbp = dbp; - dbp = dbp->db_next; - memput(odbp, sizeof *odbp); - } - ns_debug(ns_log_default, 3, - "rrsetupdate: %s %d", - fs->fs_name[0] ? fs->fs_name : ".", n); - } else { - if ((n == 0) && updatettl) - (void)ttlcheck(fs->fs_name,fs->fs_list, 1); - dbp = fs->fs_list; - while (dbp) { - db_freedata(dbp->db_dp); - odbp = dbp; - dbp = dbp->db_next; - memput(odbp, sizeof *odbp); - } - } - fs->fs_list = NULL; - fs++; - } - n = db_set_update(NULL, NULL, &state, flags, &hashtab, from, - NULL, 0, NULL); -} - -static void -flushrrset(struct flush_set * fs, struct sockaddr_in from) { - struct databuf *dp; - int n; - - ns_debug(ns_log_default, 2, "flushrrset(%s, %s, %s, %d)", - fs->fs_name[0]?fs->fs_name:".", p_type(fs->fs_type), - p_class(fs->fs_class), fs->fs_cred); - dp = savedata(fs->fs_class, fs->fs_type, 0, NULL, 0); - dp->d_zone = DB_Z_CACHE; - dp->d_cred = fs->fs_cred; - dp->d_clev = 0; - do { - n = db_update(fs->fs_name, dp, NULL, NULL, DB_DELETE, hashtab, - from); - ns_debug(ns_log_default, 3, "flushrrset: %d", n); - } while (n == OK); - db_freedata(dp); -} - -static void -free_flushset(struct flush_set *flushset, int flushset_size) { - struct flush_set *fs; - - for (fs = flushset; fs->fs_name != NULL; fs++) - freestr(fs->fs_name); - memput(flushset, flushset_size); -} - -/* - * This is best thought of as a "cache invalidate" function. - * It is called whenever a piece of data is determined to have - * become invalid either through a timeout or a validation - * failure. It is better to have no information, than to - * have partial information you pass off as complete. - */ -void -delete_all(struct namebuf *np, int class, int type) { - struct databuf *dp, *pdp; - - ns_debug(ns_log_default, 3, "delete_all(%#x:\"%s\" %s %s)", - np, NAME(*np), p_class(class), p_type(type)); - pdp = NULL; - dp = np->n_data; - while (dp != NULL) { - if (dp->d_zone == DB_Z_CACHE && (dp->d_flags & DB_F_HINT) == 0 - && match(dp, class, type)) { - dp = rm_datum(dp, np, pdp, NULL); - continue; - } - pdp = dp; - dp = dp->d_next; - } -} - -/* delete_stale(np) - * for all RRs associated with this name, check for staleness (& delete) - * arguments: - * np = pointer to namebuf to be cleaned. - * returns: - * number of RRs associated with this name. - * side effects: - * delete_all() can be called, freeing memory and relinking chains. - */ -int -delete_stale(np) - struct namebuf *np; -{ - struct databuf *dp; - int count; - again: - count = 0; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (dp->d_zone == DB_Z_CACHE && stale(dp)) { - delete_all(np, dp->d_class, dp->d_type); - goto again; - } - count++; - } - return (count); -} - - -/* - * Adjust answer message so that it fits in outlen. Set tc if required. - * - * If outlen = msglen, can be used to verify qdcount, ancount, nscount - * and arcount. - * - * return new length - */ - -int -trunc_adjust(u_char *msg, int msglen, int outlen) { - register HEADER *hp; - u_int qdcount, ancount, nscount, arcount, dlen; - u_char *cp = msg, *cp1, *eom_in, *eom_out; - int n; - - eom_in = msg + msglen; - eom_out = msg + outlen; - - hp = (HEADER *)msg; - qdcount = ntohs(hp->qdcount); - ancount = ntohs(hp->ancount); - nscount = ntohs(hp->nscount); - arcount = ntohs(hp->arcount); - cp += HFIXEDSZ; - - while ((qdcount || ancount || nscount || arcount) && - cp < eom_in && cp < eom_out) { - - cp1 = cp; /* use temporary in case we break */ - - n = dn_skipname(cp1, eom_in); - if (n < 0) - break; - cp1 += n + 2 * INT16SZ; /* type, class */ - - if (!qdcount) { - cp1 += INT32SZ; /* ttl */ - if (cp1 + INT16SZ > eom_in) - break; - GETSHORT(dlen, cp1); - cp1 += dlen; - } - - if (cp1 > eom_in || cp1 > eom_out) - break; - - cp = cp1; - - if (qdcount) - qdcount--; - else if (ancount) - ancount--; - else if (nscount) - nscount--; - else - arcount--; - } - - if (qdcount || ancount || nscount || arcount) { - ns_debug(ns_log_default, 1, - "trunc_adjust:%s %d %d %d %d %d, %d %d %d %d %d", - hp->tc?" tc":"", msglen, - ntohs(hp->qdcount), ntohs(hp->ancount), - ntohs(hp->nscount), ntohs(hp->arcount), - cp-msg, qdcount, ancount, nscount, arcount); - hp->tc = 1; - hp->qdcount = htons(ntohs(hp->qdcount) - qdcount); - hp->ancount = htons(ntohs(hp->ancount) - ancount); - hp->nscount = htons(ntohs(hp->nscount) - nscount); - hp->arcount = htons(ntohs(hp->arcount) - arcount); - } - ENSURE(cp <= eom_out); - return (cp - msg); -} - -/* - * mark the server "from" bad in the qp structure so it won't be retried. - */ -static void -mark_bad(struct qinfo *qp, struct sockaddr_in from) { - int i; - - for (i = 0; i < (int)qp->q_naddr; i++) - if (ina_equal(qp->q_addr[i].ns_addr.sin_addr, from.sin_addr)) - qp->q_addr[i].nretry = MAXRETRY; -} - -static void -mark_lame(struct qinfo *qp, struct sockaddr_in from) { - int i; - - for (i = 0; i < (int)qp->q_naddr; i++) - if (ina_equal(qp->q_addr[i].ns_addr.sin_addr, from.sin_addr) && - qp->q_addr[i].ns != NULL) { - qp->q_addr[i].ns->d_flags |= DB_F_LAME; - db_lame_add(qp->q_domain, - (char*)qp->q_addr[i].ns->d_data, - tt.tv_sec + server_options->lame_ttl); - } -} - -/* - * Retry the message if and only if from matches where the query was - * last sent to. The code does not handle responses sent from the - * wrong interface an a multihomed server. - */ -static void -fast_retry(struct qinfo *qp, struct sockaddr_in from) { - if (ina_equal(qp->q_addr[qp->q_curaddr].ns_addr.sin_addr, - from.sin_addr)) - retry(qp); -} - -static void -add_related_additional(char *name) { - int i; - - if (num_related >= MAX_RELATED - 1) - return; - for (i = 0; i < num_related; i++) - if (ns_samename(name, related[i]) == 1) { - freestr(name); - return; - } - related[num_related++] = name; -} - -static void -free_related_additional() { - int i; - - for (i = 0; i < num_related; i++) - freestr(related[i]); - num_related = 0; -} - -static int -related_additional(char *name) { - int i; - - for (i = 0; i < num_related; i++) - if (ns_samename(name, related[i]) == 1) - return (1); - return (0); -} - -static void -freestr_maybe(char **tname) { - if (tname == NULL || *tname == NULL) - return; - freestr(*tname); - *tname = NULL; -} - -/* - * Match a request namebuf against the configured rrset-order info. First - * match wins. There is an implicit '*.' at the front to the ordering names. - */ -static enum ordering -match_order(const struct namebuf *np, int class, int type) { - rrset_order_list orders = server_options->ordering; - rrset_order_element roe; - - if (orders == NULL) - return (DEFAULT_ORDERING); - - for (roe = orders->first ; roe != NULL ; roe = roe->next) { - if (roe->class != C_ANY && roe->class != class) - continue; - if (roe->type != T_ANY && roe->type != type) - continue; - - if (match_name(np, roe->name, strlen(roe->name)) == 0) { - return (roe->order); - } - } - - /* none matched so use default */ - return (DEFAULT_ORDERING); -} - -/* Do a simple compare of the NP data against the given NAME, recursively - * looking at the NP parent if necessary. NAMELEN is the length of the NAME - * that needs to be matched. Matching happen from right to left. Returns -1 - * on failure, on success the index of the first character of the matched - * portion of the string is returned. In the first level call a return - * value of 0 is of interest. - */ -static int -match_name(const struct namebuf *np, const char *name, size_t namelen) -{ - int matched ; - - if (name[0] == '*' && name[1] == '\0') - return 0; - - if (np->n_parent != NULL) { /* recurse to end of np list */ - matched = match_name(np->n_parent,name,namelen); - } else { - matched = namelen; - } - - if (matched > 0) { - int labellen = NAMELEN(*np); - char pch; - const char *start; - - if (labellen > matched) { - return -1; - } else if (labellen < matched) { - /* string is longer than this namebuf's data, so - make sure there's a period before the end of the - match so we don't just match a suffix. */ - start = name + (matched - labellen); - pch = start[-1]; - if (pch != '.') { - return -1; - } - } else { - start = name ; - } - - if (strncasecmp(start, NAME(*np), labellen) == 0) { - /* looking good. tell our caller what portion of - the tail of string has been matched */ - if (start == name) - return (0) ; - else - return (start - name - 1); /* matched '.' too */ - } else { - return (-1); - } - } - - return (matched); -} - diff --git a/contrib/bind/bin/named/ns_signal.c b/contrib/bind/bin/named/ns_signal.c deleted file mode 100644 index f5a6e24a00d48..0000000000000 --- a/contrib/bind/bin/named/ns_signal.c +++ /dev/null @@ -1,267 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)ns_main.c 4.55 (Berkeley) 7/1/91"; -static const char rcsid[] = "$Id: ns_signal.c,v 8.13 2000/07/11 07:10:12 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1989, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* Import. */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#ifdef SVR4 /* XXX */ -# include <sys/sockio.h> -#else -# include <sys/mbuf.h> -#endif - -#include <netinet/in.h> -#include <net/route.h> -#include <net/if.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <grp.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <netdb.h> -#include <pwd.h> -#include <resolv.h> -#include <string.h> -#include <syslog.h> -#include <time.h> -#include <unistd.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> -#include <isc/list.h> - -#include "port_after.h" -#include "named.h" - -/* Forward. */ - -static SIG_FN onhup(int); -static SIG_FN onintr(int); -static SIG_FN setdumpflg(int); -static SIG_FN setIncrDbgFlg(int); -static SIG_FN setNoDbgFlg(int); -static SIG_FN setQrylogFlg(int); -static SIG_FN setstatsflg(int); -static SIG_FN discard_pipe(int); -static SIG_FN setreapflg(int); - -/* Data. */ - -static struct { - int sig; - SIG_FN (*hand)(int); -} sighandlers[] = { -#ifdef DEBUG - { SIGUSR1, setIncrDbgFlg }, - { SIGUSR2, setNoDbgFlg }, -#endif -#if defined(SIGWINCH) && defined(QRYLOG) - { SIGWINCH, setQrylogFlg }, -#endif -#if defined(SIGXFSZ) - { SIGXFSZ, onhup }, /* Wierd DEC Hesiodism, harmless. */ -#endif - { SIGINT, setdumpflg }, - { SIGILL, setstatsflg }, - { SIGHUP, onhup }, - { SIGCHLD, setreapflg }, - { SIGPIPE, discard_pipe }, - { SIGTERM, onintr } -}; - -static sigset_t mask; -static int blocked = 0; - -/* Private. */ - -static SIG_FN -onhup(int sig) { - ns_need_unsafe(main_need_reload); -} - -static SIG_FN -onintr(int sig) { - ns_need_unsafe(main_need_exit); -} - -static SIG_FN -setdumpflg(int sig) { - ns_need_unsafe(main_need_dump); -} - -#ifdef DEBUG -static SIG_FN -setIncrDbgFlg(int sig) { - desired_debug++; - ns_need_unsafe(main_need_debug); -} - -static SIG_FN -setNoDbgFlg(int sig) { - desired_debug = 0; - ns_need_unsafe(main_need_debug); -} -#endif /*DEBUG*/ - -#if defined(QRYLOG) && defined(SIGWINCH) -static SIG_FN -setQrylogFlg(int sig) { - ns_need_unsafe(main_need_qrylog); -} -#endif /*QRYLOG && SIGWINCH*/ - -static SIG_FN -setstatsflg(int sig) { - ns_need_unsafe(main_need_statsdump); -} - -static SIG_FN -discard_pipe(int sig) { -#ifdef SIGPIPE_ONE_SHOT - int saved_errno = errno; - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sa.sa_mask = mask; - sa.sa_handler = discard_pipe; - if (sigaction(SIGPIPE, &sa, NULL) < 0) - ns_error(ns_log_os, "sigaction failed in discard_pipe: %s", - strerror(errno)); - errno = saved_errno; -#endif -} - -static SIG_FN -setreapflg(int sig) { - ns_need_unsafe(main_need_reap); -} - -/* Public. */ - -void -init_signals(void) { - int sh; - - /* The mask of all our handlers will block all our other handlers. */ - (void)sigemptyset(&mask); - for (sh = 0; sh < sizeof sighandlers / sizeof sighandlers[0]; sh++) - sigaddset(&mask, sighandlers[sh].sig); - - /* Install our signal handlers with that shared mask. */ - for (sh = 0; sh < sizeof sighandlers / sizeof sighandlers[0]; sh++) { - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sa.sa_mask = mask; - sa.sa_handler = sighandlers[sh].hand; - if (sigaction(sighandlers[sh].sig, &sa, NULL) < 0) - ns_error(ns_log_os, - "sigaction failed in set_signal_handler(%d): %s", - sighandlers[sh].sig, strerror(errno)); - } - /* Unblock all signals that we expect to handle. */ - if (sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) - ns_panic(ns_log_os, 1, "sigblock failed: %s", strerror(errno)); -} - -void -block_signals(void) { - INSIST(!blocked); - if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) - ns_panic(ns_log_os, 1, "sigblock failed: %s", strerror(errno)); - blocked = 1; -} - -void -unblock_signals(void) { - INSIST(blocked); - if (sigprocmask(SIG_UNBLOCK, &mask, NULL) < 0) - ns_panic(ns_log_os, 1, "sigblock failed: %s", strerror(errno)); - blocked = 0; -} diff --git a/contrib/bind/bin/named/ns_sort.c b/contrib/bind/bin/named/ns_sort.c deleted file mode 100644 index 3b3f31edffbbe..0000000000000 --- a/contrib/bind/bin/named/ns_sort.c +++ /dev/null @@ -1,410 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)ns_sort.c 4.10 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: ns_sort.c,v 8.6 2000/04/21 06:54:13 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Sorting should really be handled by the resolver, but: - * 1) There are too many brain dead resolvers out there that can't be replaced. - * 2) It would be a pain to individually configure all those resolvers anyway. - * - * Here's the scoop: - * - * To enable address sorting in responses, you need to supply the sortlist - * statement in the config file. The sortlist statement takes an - * address match list and interprets it even more specially than the - * topology statement does. - * - * Each top level statement in the sortlist must itself be an explicit - * address match list with one or two elements. The first element - * (which may be an IP address, an IP prefix, an ACL name or nested - * address match list) of each top level list is checked against the - * source address of the query until a match is found. - * - * Once the source address of the query has been matched, if the top level - * statement contains only one element, the actual primitive element that - * matched the source address is used to select the address in the response - * to move to the beginning of the response. If the statement is a list - * of two elements, then the second element is treated like the address - * match list in a topology statement. Each top level element is assigned - * a distance and the address in the response with the minimum distance is - * moved to the beginning of the response. - * - * In the following example, any queries received from any of the addresses - * of the host itself will get responses preferring addresses on any of - * the locally connected networks. Next most preferred are addresses on - * the 192.168.1/24 network, and after that either the 192.168.2/24 or - * 192.168.3/24 network with no preference shown between these two networks. - * Queries received from a host on the 192.168.1/24 network will prefer - * other addresses on that network to the 192.168.2/24 and 192.168.3/24 - * networks. Queries received from a host on the 192.168.4/24 or the - * 192.168.5/24 network will only prefer other addresses on their - * directly connected networks. - * - * sortlist { - * { - * localhost; - * { - * localnets; - * 192.168.1/24; - * { 192,168.2/24; 192.168.3/24; }; - * }; - * }; - * { - * 192.168.1/24; - * { - * 192.168.1/24; - * { 192.168.2/24; 192.168.3/24; }; - * }; - * }; - * { - * 192.168.2/24; - * { - * 192.168.2/24; - * { 192.168.1/24; 192.168.3/24; }; - * }; - * }; - * { - * 192.168.3/24; - * { - * 192.168.3/24; - * { 192.168.1/24; 192.168.2/24; }; - * }; - * }; - * { - * { 192.168.4/24; 192.168.5/24; }; - * }; - * }; - * - * - * The following example will give reasonable behaviour for the local host - * and hosts on directly connected networks. It is similar to the behavior - * of the address sort in BIND 4.9.x. Responses sent to queries from the - * local host will favor any of the directly connected networks. Responses - * sent to queries from any other hosts on a directly connected network will - * prefer addresses on that same network. Responses to other queries will - * not be sorted. - * - * sortlist { - * { localhost; localnets; }; - * { localnets; }; - * }; - * - * XXX - it wouldb e nice to have an ACL called "source" that matched the - * source address of a query so that a host could be configured to - * automatically prefer itself, and an ACL called "sourcenet", that - * would return the primitive IP match element that matched the source - * address so that you could do: - * { localnets; { sourcenet; { other stuff ...}; }; - * and automatically get similar behaviour to what you get with: - * { localnets; }; - * - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <syslog.h> -#include <resolv.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include "port_after.h" - -#include "named.h" - -static int sort_rr(u_char *cp, u_char *eom, int ancount, ip_match_list iml); - -static int ip_match_address_elt(ip_match_list, struct in_addr, - ip_match_element *); - -void -sort_response(u_char *cp, u_char *eom, int ancount, struct sockaddr_in *from) { - struct in_addr address; - struct ip_match_element imelement; - ip_match_element imetl, imematch, imeprimitive; - struct ip_match_list imlist; - ip_match_list iml; - int indirect, matched; - - if (server_options->sortlist == NULL) - return; - - if (from->sin_family != AF_INET) - return; - - address = from->sin_addr; - - for (imetl = server_options->sortlist->first; imetl != NULL; - imetl = imetl->next) { - if (imetl->type == ip_match_indirect) - imematch = imetl->u.indirect.list->first; - else - /* - * allow a bare pattern as a top level statement - * and treat it like {pattern;}; - */ - imematch = imetl; - - switch (imematch->type) { - case ip_match_pattern: - indirect = 0; - break; - case ip_match_indirect: - indirect = 1; - break; - case ip_match_localhost: - imematch->u.indirect.list = local_addresses; - indirect = 1; - break; - case ip_match_localnets: - imematch->u.indirect.list = local_networks; - indirect = 1; - break; - default: - panic("unexpected ime type in ip_match_address()", - NULL); - } - if (indirect) { - imeprimitive = NULL; - matched = ip_match_address_elt(imematch->u.indirect.list, - address, &imeprimitive); - if (matched >= 0) { - if (imematch->flags & IP_MATCH_NEGATE) - /* Don't sort */ - return; - } else - continue; - } else { - if (ina_onnet(address, imematch->u.direct.address, - imematch->u.direct.mask)) { - if (imematch->flags & IP_MATCH_NEGATE) - /* Don't sort */ - return; - else - imeprimitive = imematch; - } else - continue; - } - if (imetl != imematch && imematch->next != NULL) { - /* - * Not a bare pattern at the top level, but a two - * element list - */ - switch (imematch->next->type) { - case ip_match_pattern: - case ip_match_localhost: - case ip_match_localnets: - imelement = *(imematch->next); - imelement.next = NULL; - iml = &imlist; - iml->first = iml->last = &imelement; - break; - case ip_match_indirect: - iml = imematch->next->u.indirect.list; - break; - default: - panic("unexpected ime type in ip_match_address()", - NULL); - } - } else if (imeprimitive) { - imelement = *imeprimitive; - imelement.next = NULL; - iml = &imlist; - iml->first = iml->last = &imelement; - } else { - /* Don't sort because we'd just use "any" */ - return; - } - sort_rr(cp, eom, ancount, iml); - break; - } - - return; -} - -static int -sort_rr(u_char *cp, u_char *eom, int ancount, ip_match_list iml) { - int type, class, dlen, n, c, distance, closest; - struct in_addr inaddr; - u_char *rr1 = NULL, *rrbest, *cpstart; - - rr1 = NULL; - cpstart = cp; - for (c = ancount; c > 0; --c) { - n = dn_skipname(cp, eom); - if (n < 0) - return (1); /* bogus, stop processing */ - cp += n; - if (cp + QFIXEDSZ > eom) - return (1); - GETSHORT(type, cp); - GETSHORT(class, cp); - cp += INT32SZ; - GETSHORT(dlen, cp); - if (dlen > eom - cp) - return (1); /* bogus, stop processing */ - switch (type) { - case T_A: - switch (class) { - case C_IN: - case C_HS: - memcpy((char *)&inaddr, cp, INADDRSZ); - /* Find the address with the minimum distance */ - if (rr1 == NULL) { - rr1 = cp; - rrbest = cp; - closest = distance_of_address(iml, inaddr); - } else { - distance = distance_of_address(iml, inaddr); - if (distance < closest) { - rrbest = cp; - closest = distance; - } - } - break; - } - break; - } - cp += dlen; - } - if (rr1 != rrbest && rr1 != NULL) { - memcpy((char *)&inaddr, rrbest, INADDRSZ); - memcpy(rrbest, rr1, INADDRSZ); - memcpy(rr1, (char *)&inaddr, INADDRSZ); - } - return (0); -} - -/* - * Just like ip_match_address(), but also returns a pointer to the primitive - * element that matched. - */ - -static int -ip_match_address_elt(ip_match_list iml, struct in_addr address, - ip_match_element *imep) { - ip_match_element ime; - int ret; - int indirect; - - INSIST(iml != NULL); - for (ime = iml->first; ime != NULL; ime = ime->next) { - switch (ime->type) { - case ip_match_pattern: - indirect = 0; - break; - case ip_match_indirect: - indirect = 1; - break; - case ip_match_localhost: - ime->u.indirect.list = local_addresses; - indirect = 1; - break; - case ip_match_localnets: - ime->u.indirect.list = local_networks; - indirect = 1; - break; - default: - panic("unexpected ime type in ip_match_address()", - NULL); - } - if (indirect) { - ret = ip_match_address_elt(ime->u.indirect.list, - address, imep); - if (ret >= 0) { - if (ime->flags & IP_MATCH_NEGATE) - ret = (ret) ? 0 : 1; - return (ret); - } - } else { - if (ina_onnet(address, ime->u.direct.address, - ime->u.direct.mask)) { - *imep = ime; - if (ime->flags & IP_MATCH_NEGATE) - return (0); - else - return (1); - } - } - } - return (-1); -} diff --git a/contrib/bind/bin/named/ns_stats.c b/contrib/bind/bin/named/ns_stats.c deleted file mode 100644 index f04790b1e0f70..0000000000000 --- a/contrib/bind/bin/named/ns_stats.c +++ /dev/null @@ -1,402 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char sccsid[] = "@(#)ns_stats.c 4.10 (Berkeley) 6/27/90"; -static const char rcsid[] = "$Id: ns_stats.c,v 8.30 2000/04/23 02:18:59 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> -#include <isc/tree.h> - -#include "port_after.h" - -#ifdef HAVE_GETRUSAGE /* XXX */ -#include <sys/time.h> -#include <sys/resource.h> -#endif - -#include "named.h" - -static u_long typestats[T_ANY+1]; -static void nameserStats(FILE *); - -void -ns_stats() { - time_t timenow = time(NULL); - FILE *f; - int i; - - ns_notice(ns_log_statistics, "dumping nameserver stats"); - - if (!(f = fopen(server_options->stats_filename, "a"))) { - ns_notice(ns_log_statistics, "cannot open stat file, \"%s\"", - server_options->stats_filename); - return; - } - (void) fchown(fileno(f), user_id, group_id); - - fprintf(f, "+++ Statistics Dump +++ (%ld) %s", - (long)timenow, checked_ctime(&timenow)); - fprintf(f, "%ld\ttime since boot (secs)\n", - (long)(timenow - boottime)); - fprintf(f, "%ld\ttime since reset (secs)\n", - (long)(timenow - resettime)); - - /* query type statistics */ - fprintf(f, "%lu\tUnknown query types\n", (u_long)typestats[0]); - for (i = 1; i < T_ANY+1; i++) - fprintf(f, "%lu\t%s queries\n", typestats[i], p_type(i)); - - /* name server statistics */ - nameserStats(f); - - fprintf(f, "--- Statistics Dump --- (%ld) %s", - (long)timenow, checked_ctime(&timenow)); - (void) my_fclose(f); - - /* Now do the memory statistics file */ - if (!(f = fopen(server_options->memstats_filename, "a"))) { - ns_notice(ns_log_statistics, "cannot open memstat file, \"%s\"", - server_options->memstats_filename); - return; - } - (void) fchown(fileno(f), user_id, group_id); - - fprintf(f, "+++ Memory Statistics Dump +++ (%ld) %s", - (long)timenow, checked_ctime(&timenow)); - - fprintf(f, "%ld\ttime since boot (secs)\n", - (long)(timenow - boottime)); - fprintf(f, "%ld\ttime since reset (secs)\n", - (long)(timenow - resettime)); - - fprintf(f, "++ Memory Statistics ++\n"); - memstats(f); - fprintf(f, "-- Memory Statistics --\n"); - - fprintf(f, "--- Memory Statistics Dump --- (%ld) %s", - (long)timenow, checked_ctime(&timenow)); - (void) my_fclose(f); - - ns_notice(ns_log_statistics, "done dumping nameserver stats"); -} - -void -qtypeIncr(qtype) - int qtype; -{ - if (qtype < T_A || qtype > T_ANY) - qtype = 0; /* bad type */ - typestats[qtype]++; -} - -static tree *nameserTree; -static int nameserInit; - -static FILE *nameserStatsFile; -static const char *statNames[nssLast] = { - "RR", /* sent us an answer */ - "RNXD", /* sent us a negative response */ - "RFwdR", /* sent us a response we had to fwd */ - "RDupR", /* sent us an extra answer */ - "RFail", /* sent us a SERVFAIL */ - "RFErr", /* sent us a FORMERR */ - "RErr", /* sent us some other error */ - "RAXFR", /* sent us an AXFR */ - "RLame", /* sent us a lame delegation */ - "ROpts", /* sent us some IP options */ - "SSysQ", /* sent them a sysquery */ - "SAns", /* sent them an answer */ - "SFwdQ", /* fwdd a query to them */ - "SDupQ", /* sent them a retry */ - "SErr", /* sent failed (in sendto) */ - "RQ", /* sent us a query */ - "RIQ", /* sent us an inverse query */ - "RFwdQ", /* sent us a query we had to fwd */ - "RDupQ", /* sent us a retry */ - "RTCP", /* sent us a query using TCP */ - "SFwdR", /* fwdd a response to them */ - "SFail", /* sent them a SERVFAIL */ - "SFErr", /* sent them a FORMERR */ - "SNaAns", /* sent them a non autoritative answer */ - "SNXD", /* sent them a negative response */ - "RUQ", /* sent us an unapproved query */ - "RURQ", /* sent us an unapproved recursive query */ - "RUXFR", /* sent us an unapproved AXFR or IXFR */ - "RUUpd", /* sent us an unapproved update */ - }; - -/* - * Note that addresses in network byte order always have the high byte first. - * XXX - this is horribly IPv4 dependent, but it's performance critical. - */ -static int -nameserCompar(const tree_t t1, const tree_t t2) { - u_char *p1 = (u_char *)t1, *p2 = (u_char *)t2; - int i; - - for (i = INADDRSZ; i > 0; i--) { - u_char c1 = *p1++, c2 = *p2++; - - if (c1 < c2) - return (-1); - if (c1 > c2) - return (1); - } - return (0); -} - -struct nameser * -nameserFind(addr, flags) - struct in_addr addr; - int flags; -{ - struct nameser dummy; - struct nameser *ns; - - if (!nameserInit) { - tree_init(&nameserTree); - nameserInit++; - } - - dummy.addr = addr; - ns = (struct nameser *)tree_srch(&nameserTree, nameserCompar, - (tree_t)&dummy); - if (ns == NULL && (flags & NS_F_INSERT) != 0) { - ns = (struct nameser *)memget(sizeof(struct nameser)); - if (ns == NULL) { - nomem: if (!haveComplained((u_long)nameserFind, 0)) - ns_notice(ns_log_statistics, - "nameserFind: memget failed; %s", - strerror(errno)); - return (NULL); - } - memset(ns, 0, sizeof *ns); - ns->addr = addr; - if (!tree_add(&nameserTree, nameserCompar, (tree_t)ns, NULL)) { - int save = errno; - memput(ns, sizeof *ns); - errno = save; - goto nomem; - } - } - return (ns); -} - -static void -nameserStatsOut(f, stats) - FILE *f; - u_long stats[]; -{ - int i; - const char *pre = "\t"; - - for (i = 0; i < (int)nssLast; i++) { - fprintf(f, "%s%lu", pre, (u_long)stats[i]); - pre = ((i+1) % 5) ? " " : " "; - } - fputc('\n', f); -} - -static void -nameserStatsHdr(f) - FILE *f; -{ - int i; - const char *pre = "\t"; - - fprintf(f, "(Legend)\n"); - for (i = 0; i < (int)nssLast; i++) { - fprintf(f, "%s%s", pre, - statNames[i] ? statNames[i] : ""); - pre = ((i+1) % 5) ? "\t" : "\n\t"; - } - fputc('\n', f); -} - -static int -nameserStatsTravUAR(t) - tree_t t; -{ - struct nameser *ns = (struct nameser *)t; - - fprintf(nameserStatsFile, "[%s]\n", /* : rtt %u */ - inet_ntoa(ns->addr) /*, ns->rtt*/ ); - nameserStatsOut(nameserStatsFile, ns->stats); - return (1); -} - -static void -nameserStats(f) - FILE *f; -{ - nameserStatsFile = f; - fprintf(f, "++ Name Server Statistics ++\n"); - nameserStatsHdr(f); - fprintf(f, "(Global)\n"); - nameserStatsOut(f, globalStats); - if (NS_OPTION_P(OPTION_HOSTSTATS)) - tree_trav(&nameserTree, nameserStatsTravUAR); - fprintf(f, "-- Name Server Statistics --\n"); - nameserStatsFile = NULL; -} - -void -ns_logstats(evContext ctx, void *uap, struct timespec due, - struct timespec inter) -{ - char buffer[1024]; - char buffer2[32], header[64]; - time_t timenow = time(NULL); - int i; -#ifdef HAVE_GETRUSAGE - struct rusage usage, childu; -#endif /*HAVE_GETRUSAGE*/ - -#ifdef HAVE_GETRUSAGE -# define tv_float(tv) ((tv).tv_sec + ((tv).tv_usec / 1000000.0)) - - getrusage(RUSAGE_SELF, &usage); - getrusage(RUSAGE_CHILDREN, &childu); - - sprintf(buffer, "CPU=%gu/%gs CHILDCPU=%gu/%gs", - tv_float(usage.ru_utime), tv_float(usage.ru_stime), - tv_float(childu.ru_utime), tv_float(childu.ru_stime)); - ns_info(ns_log_statistics, "USAGE %lu %lu %s", (u_long)timenow, - (u_long)boottime, buffer); -# undef tv_float -#endif /*HAVE_GETRUSAGE*/ - - sprintf(header, "NSTATS %lu %lu", (u_long)timenow, (u_long)boottime); - strcpy(buffer, header); - - for (i = 0; i < T_ANY+1; i++) { - if (typestats[i]) { - sprintf(buffer2, " %s=%lu", p_type(i), typestats[i]); - if (strlen(buffer) + strlen(buffer2) > - sizeof(buffer) - 1) { - ns_info(ns_log_statistics, buffer); - strcpy(buffer, header); - } - strcat(buffer, buffer2); - } - } - ns_info(ns_log_statistics, buffer); - - sprintf(header, "XSTATS %lu %lu", (u_long)timenow, (u_long)boottime); - strcpy(buffer, header); - for (i = 0; i < (int)nssLast; i++) { - sprintf(buffer2, " %s=%lu", - statNames[i]?statNames[i]:"?", (u_long)globalStats[i]); - if (strlen(buffer) + strlen(buffer2) > sizeof(buffer) - 1) { - ns_info(ns_log_statistics, buffer); - strcpy(buffer, header); - } - strcat(buffer, buffer2); - } - ns_info(ns_log_statistics, buffer); -} - -static void -nameserFree(void *uap) { - struct nameser *ns = uap; - - memput(ns, sizeof *ns); -} - -void -ns_freestats(void) { - if (nameserTree == NULL) - return; - tree_mung(&nameserTree, nameserFree); - nameserInit = 0; -} diff --git a/contrib/bind/bin/named/ns_udp.c b/contrib/bind/bin/named/ns_udp.c deleted file mode 100644 index 23f437714ac9a..0000000000000 --- a/contrib/bind/bin/named/ns_udp.c +++ /dev/null @@ -1,124 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_udp.c,v 8.9 2000/04/21 06:54:13 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <netdb.h> -#include <nlist.h> -#include <resolv.h> -#include <stdio.h> -#include <syslog.h> -#include <time.h> -#include <unistd.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include "port_after.h" - -#include "named.h" - -void -ns_udp() { -#if defined(CHECK_UDP_SUM) || defined(FIX_UDP_SUM) - struct nlist nl[2]; - int fd; - int sum; - u_long res, offset; - - nl[0].n_name = UDPSUM; - nl[1].n_name = 0; - - if (nlist(KSYMS, nl)) { - ns_debug(ns_log_default, 1, "ns_udp: nlist (%s,%s) failed", - KSYMS, UDPSUM); - return; - } - - ns_debug(ns_log_default, 1, "ns_udp: %s %d %lu (%ld)", - nl[0].n_name, nl[0].n_type, nl[0].n_value, nl[0].n_value); - - if (!nl[0].n_type) - return; - - if ((fd = open(KMEM, O_RDWR, 0)) < 0) { - ns_debug(ns_log_default, 1, "ns_udp: open %s failed: %s", KMEM, - strerror(errno)); - return; - } - - offset = nl[0].n_value; -#ifdef KMAP - offset &= ((~0UL)>>1); -#endif - - res = lseek(fd, offset, SEEK_SET); - if (res != offset) { - ns_debug(ns_log_default, 1, "ns_udp: lseek %lu failed %lu: %s", - offset, res, strerror(errno)); - goto cleanup; - } - - if (read(fd, &sum, sizeof(sum)) != sizeof(sum)) { - ns_debug(ns_log_default, 1, "ns_udp: read failed: %s", - strerror(errno)); - goto cleanup; - } - - ns_debug(ns_log_default, 1, "ns_udp: %d", sum); - if (sum == 0) { -#ifdef FIX_UDP_SUM - sum = 1; - lseek(fd, offset, SEEK_SET); - if (res != offset) { - ns_debug(ns_log_default, 1, - "ns_udp: lseek %lu failed %lu: %s", - offset, res, strerror(errno)); - goto cleanup; - } - if (write(fd, &sum, sizeof(sum)) != sizeof(sum)) { - ns_debug(ns_log_default, 1, "ns_udp: write failed: %s", - strerror(errno)); - goto cleanup; - } - ns_warning(ns_log_default, "ns_udp: check sums turned on"); -#else - ns_panic(ns_log_default, 0, - "ns_udp: checksums NOT turned on, exiting"); -#endif - } -cleanup: - close(fd); -#endif -} diff --git a/contrib/bind/bin/named/ns_update.c b/contrib/bind/bin/named/ns_update.c deleted file mode 100644 index da0c5a9109227..0000000000000 --- a/contrib/bind/bin/named/ns_update.c +++ /dev/null @@ -1,3039 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_update.c,v 8.81 2000/07/11 09:25:14 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1999 by Check Point Software Technologies, Inc. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Check Point Software Technologies Incorporated not be used - * in advertising or publicity pertaining to distribution of the document - * or software without specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND CHECK POINT SOFTWARE TECHNOLOGIES - * INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL CHECK POINT SOFTWARE TECHNOLOGIES INCORPRATED - * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Based on the Dynamic DNS reference implementation by Viraj Bais - * <viraj_bais@ccm.fm.intel.com> - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/uio.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <resolv.h> -#include <res_update.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <syslog.h> -#include <time.h> -#include <unistd.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" - -static ns_updque curupd; - -#define WRITEABLE_MASK (S_IWUSR | S_IWGRP | S_IWOTH) - -/* XXXRTH almost all funcs. in here should be static! - map rdata_dump to db_to_textual - map rdata_expand to wire_to_db - make a textual_to_db and use it in merge_logs? - replace all this "map" stuff with the new routines (from 4.9.5 I think) - */ - -/* from ns_req.c */ - -static struct map m_opcode[] = { - { "nxdomain", NXDOMAIN }, - { "yxdomain", YXDOMAIN }, - { "nxrrset", NXRRSET }, - { "yxrrset", YXRRSET }, - { "delete", DELETE }, - { "add", ADD }, -}; -#define M_OPCODE_CNT (sizeof(m_opcode) / sizeof(struct map)) - -/* XXXRTH workaround map difficulties */ -#define M_CLASS_CNT m_class_cnt -#define M_TYPE_CNT m_type_cnt - -static char *opcodes[] = { - "delete", - "add", - "", - "nxdomain", - "", - "", - "yxdomain", - "yxrrset", - "nxrrset", - "", - "", -}; - - -/* from db_load.c */ - -static struct map m_section[] = { - { "zone", S_ZONE }, - { "prereq", S_PREREQ }, - { "update", S_UPDATE }, - { "reserved", S_ADDT }, -}; -#define M_SECTION_CNT (sizeof(m_section) / sizeof(struct map)) - -/* Forward. */ - -static int rdata_expand(const u_char *, const u_char *, const u_char *, - u_int, size_t, u_char *, size_t); - - -static FILE * -open_transaction_log(struct zoneinfo *zp) { - FILE *fp = fopen(zp->z_updatelog, "a+"); - - if (fp == NULL) { - ns_error(ns_log_update, "can't open %s: %s", zp->z_updatelog, - strerror(errno)); - return (NULL); - } - (void) fchown(fileno(fp), user_id, group_id); - if (fseek(fp, 0L, SEEK_END) != 0) { - ns_error(ns_log_update, "can't fseek(%s, 0, SEEK_END)", - zp->z_updatelog); - fclose(fp); - return (NULL); - } - if (ftell(fp) == 0L) { - fprintf(fp, "%s", LogSignature); - zp->z_serial_ixfr_start = get_serial(zp); - } - else - zp->z_serial_ixfr_start = 0; - return (fp); -} - -static FILE * -open_ixfr_log(struct zoneinfo *zp) { - FILE *fp = fopen(zp->z_ixfr_base, "a+"); - - if (fp == NULL) { - ns_error(ns_log_update, "can't open %s: %s", zp->z_ixfr_base, - strerror(errno)); - return (NULL); - } - (void) fchown(fileno(fp), user_id, group_id); - if (fseek(fp, 0L, SEEK_END) != 0) { - ns_error(ns_log_update, "can't fseek(%s, 0, SEEK_END)", - zp->z_ixfr_base); - fclose(fp); - return (NULL); - } - if (ftell(fp) == 0L) { - fprintf(fp, "%s", LogSignature); - } - return (fp); -} - -static int -close_transaction_log(struct zoneinfo *zp, FILE *fp) { - if (fflush(fp) == EOF) { - ns_error(ns_log_update, "fflush() of %s failed: %s", - zp->z_updatelog, strerror(errno)); - return (-1); - } - if (fsync(fileno(fp)) < 0) { - ns_error(ns_log_update, "fsync() of %s failed: %s", - zp->z_updatelog, strerror(errno)); - return (-1); - } - if (fclose(fp) == EOF) { - ns_error(ns_log_update, "fclose() of %s failed: %s", - zp->z_updatelog, strerror(errno)); - return (-1); - } - return (0); -} - -static int -close_ixfr_log(struct zoneinfo *zp, FILE *fp) { - if (fflush(fp) == EOF) { - ns_error(ns_log_update, "fflush() of %s failed: %s", - zp->z_ixfr_base, strerror(errno)); - fclose(fp); - return (-1); - } - if (fsync(fileno(fp)) < 0) { - ns_error(ns_log_update, "fsync() of %s failed: %s", - zp->z_ixfr_base, strerror(errno)); - fclose(fp); - return (-1); - } - if (fclose(fp) == EOF) { - ns_error(ns_log_update, "fclose() of %s failed: %s", - zp->z_ixfr_base, strerror(errno)); - return (-1); - } - return (0); -} - -/* - * return true if 'db' had been added. - */ -static int -was_added(const ns_updque *updlist, struct databuf *dp) { - ns_updrec *rrecp; - - for (rrecp = HEAD(*updlist); rrecp != NULL; rrecp = NEXT(rrecp, r_link)) - if (rrecp->r_section == S_UPDATE && rrecp->r_dp == dp) - return (1); - return (0); -} - -/* - * return true if 'db' had been deleted. - */ -static int -was_deleted(const ns_updque *updlist, struct databuf *dp) { - ns_updrec *rrecp; - struct databuf *adp; - - - for (rrecp = HEAD(*updlist); rrecp != NULL; rrecp = NEXT(rrecp, r_link)) - if (rrecp->r_section == S_UPDATE && - rrecp->r_deldp != NULL) { - adp = rrecp->r_deldp; - do { - if (adp == dp) - return (1); - } while ((adp = adp->d_next) != NULL); - } - return (0); -} - -/* - * printupdatelog(srcaddr, updlist, hp, zp, old_serial) - * append an ascii form to the zone's transaction log file. - */ -static void -printupdatelog(struct sockaddr_in srcaddr, - const ns_updque *updlist, - HEADER *hp, - struct zoneinfo *zp, - u_int32_t old_serial) -{ - struct databuf *dp; - struct map *mp; - ns_updrec *rrecp; - int opcode; - char time[25]; - FILE *fp, *ifp; - - if (EMPTY(*updlist)) - return; - - fp = open_transaction_log(zp); - if (fp == NULL) - return; - - if (zp->z_maintain_ixfr_base == 1) { - ifp = open_ixfr_log(zp); - if (ifp == NULL) { - (void) close_transaction_log(zp, fp); - return; - } - } - else - ifp = NULL; - - sprintf(time, "at %lu", (u_long)tt.tv_sec); - fprintf(fp, "[DYNAMIC_UPDATE] id %u from %s %s (named pid %ld):\n", - ntohs(hp->id), sin_ntoa(srcaddr), time, (long)getpid()); - if (ifp) - fprintf(ifp, - "[DYNAMIC_UPDATE] id %u from %s %s (named pid %ld):\n", - ntohs(hp->id), sin_ntoa(srcaddr), time, - (long)getpid()); - for (rrecp = HEAD(*updlist); rrecp != NULL; rrecp = NEXT(rrecp, r_link)) { - INSIST(zp == &zones[rrecp->r_zone]); - switch (rrecp->r_section) { - case S_ZONE: - fprintf(fp, "zone:\torigin %s class %s serial %u\n", - zp->z_origin, p_class(zp->z_class), - old_serial); - if (ifp) - fprintf(ifp, - "zone:\torigin %s class %s serial %u\n", - zp->z_origin, p_class(zp->z_class), - old_serial); - break; - case S_PREREQ: - opcode = rrecp->r_opcode; - fprintf(fp, "prereq:\t{%s} %s. %s ", - opcodes[opcode], rrecp->r_dname, - p_class(zp->z_class)); - if (opcode == NXRRSET || opcode == YXRRSET) { - fprintf(fp, "%s ", p_type(rrecp->r_type)); - if ((dp = rrecp->r_dp) && dp->d_size > 0) { - dp->d_class = zp->z_class; - (void) rdata_dump(dp, fp); - } - } - fprintf(fp, "\n"); - break; - case S_UPDATE: - opcode = rrecp->r_opcode; - /* - * Translate all deletes into explict actions by - * looking at what was actually deleted from the - * zone for the ixfr log. - */ - dp = rrecp->r_deldp; - while (dp != NULL) { - if (dp->d_rcode == 0 && - !was_added(updlist, dp)) { - if (ifp) { - fprintf(ifp, - "update:\t{%s} %s. %u %s %s ", - "delete", - rrecp->r_dname, - dp->d_ttl, - p_class(dp->d_class), - p_type(dp->d_type)); - (void) rdata_dump(dp, ifp); - fprintf(ifp, "\n"); - } - } - dp = dp->d_next; - } - /* - * Only successful adds should be recorded. - * Don't add changes that are undone later. - * SOA additions performed later. - */ - if (opcode == ADD && (dp = rrecp->r_dp) != NULL && - dp->d_type != T_SOA && - (dp->d_mark & D_MARK_ADDED) != 0 && - !was_deleted(updlist, dp)) { - if (ifp) { - fprintf(ifp, "update:\t{%s} %s. ", - opcodes[opcode], rrecp->r_dname); - fprintf(ifp, "%u ", rrecp->r_ttl); - fprintf(ifp, "%s ", p_class(zp->z_class)); - fprintf(ifp, "%s ", p_type(rrecp->r_type)); - (void) rdata_dump(dp, ifp); - fprintf(ifp, "\n"); - } - } - /* Update log. */ - fprintf(fp, "update:\t{%s} %s. ", - opcodes[opcode], rrecp->r_dname); - if (opcode == ADD) - fprintf(fp, "%u ", rrecp->r_ttl); - fprintf(fp, "%s ", p_class(zp->z_class)); - if (rrecp->r_type != T_ANY) - fprintf(fp, "%s ", p_type(rrecp->r_type)); - if ((dp = rrecp->r_dp) && dp->d_size > 0) { - dp->d_class = zp->z_class; - (void) rdata_dump(dp, fp); - } - fprintf(fp, "\n"); - break; - case S_ADDT: - break; - default: - ns_panic(ns_log_update, 1, - "printupdatelog - impossible condition"); - /*NOTREACHED*/ - } - } - /* - * SOA additions must be last in this update as they - * (or [INCR_SERIAL]) terminate an IXFR chunk. Only the last SOA - * addition will be emitted for any dynamic update regardless - * of the number of SOA changes in the update. - */ - for (rrecp = HEAD(*updlist); rrecp != NULL; rrecp = NEXT(rrecp, r_link)) { - INSIST(zp == &zones[rrecp->r_zone]); - switch (rrecp->r_section) { - case S_UPDATE: - opcode = rrecp->r_opcode; - if (opcode == ADD && (dp = rrecp->r_dp) != NULL && - dp->d_type == T_SOA && - (dp->d_mark & D_MARK_ADDED) != 0 && - !was_deleted(updlist, dp)) { - if (ifp) { - fprintf(ifp, "update:\t{%s} %s. ", - opcodes[opcode], rrecp->r_dname); - fprintf(ifp, "%u ", rrecp->r_ttl); - fprintf(ifp, "%s ", p_class(zp->z_class)); - fprintf(ifp, "%s ", p_type(rrecp->r_type)); - (void) rdata_dump(dp, ifp); - fprintf(ifp, "\n[END_DELTA]\n"); - } - } - break; - default: - break; - } - } - fprintf(fp, "\n"); - (void) close_transaction_log(zp, fp); - if (ifp) - (void) close_ixfr_log(zp, ifp); -} - -static void -cancel_soa_update(struct zoneinfo *zp) { - ns_debug(ns_log_update, 3, "cancel_soa_update for %s", zp->z_origin); - zp->z_flags &= ~Z_NEED_SOAUPDATE; - zp->z_soaincrtime = 0; - zp->z_updatecnt = 0; -} - -/* - * Figure out when a SOA serial number update should happen. - * Returns non-zero if the caller should call sched_zone_maint(zp). - */ -int -schedule_soa_update(struct zoneinfo *zp, int numupdated) { - (void) gettime(&tt); - - zp->z_flags |= Z_NEED_SOAUPDATE; - - /* - * Only z_deferupdcnt updates are allowed before we force - * a serial update. - */ - zp->z_updatecnt += numupdated; - if (zp->z_updatecnt >= zp->z_deferupdcnt) { - if (zp->z_soaincrtime > tt.tv_sec) { - zp->z_soaincrtime = tt.tv_sec; - return (1); - } - } - - if (zp->z_soaincrintvl > 0) { - /* We want automatic updates in this zone. */ - if (zp->z_soaincrtime > 0) { - /* Already scheduled. */ - ns_debug(ns_log_update, 3, - "schedule_soa_update('%s'): already scheduled", - zp->z_origin); - return (0); - } else { - /* First update since the soa was last incremented. */ - zp->z_updatecnt = numupdated; - zp->z_soaincrtime = tt.tv_sec + zp->z_soaincrintvl; - /* - * Never schedule soaincrtime to occur after - * dumptime. - */ - if (zp->z_soaincrtime > zp->z_dumptime) - zp->z_soaincrtime = zp->z_dumptime; - ns_debug(ns_log_update, 3, - "schedule_soa_update('%s'): scheduled for %lu", - zp->z_origin, (u_long)zp->z_soaincrtime); - return (1); - } - } - return (0); -} - -/* - * Figure out when a zone dump should happen. - * Returns non-zero if the caller should call sched_zone_maint(zp). - */ -int -schedule_dump(struct zoneinfo *zp) { - time_t half; - - (void) gettime(&tt); - - zp->z_flags |= Z_NEED_DUMP; - - if (zp->z_dumpintvl > 0) { - /* We want automatic dumping in this zone. */ - if (zp->z_dumptime > 0) { - /* Already scheduled. */ - ns_debug(ns_log_update, 3, - "schedule_dump('%s'): already scheduled", - zp->z_origin); - return (0); - } else { - /* - * Set new dump time for dynamic zone. Use a random - * number in the last half of the dump limit; we want - * it to be substantially correct while still - * preventing dump synchronization among various - * dynamic zones. - */ - half = (zp->z_dumpintvl + 1) / 2; - zp->z_dumptime = tt.tv_sec + half + (rand() % half); - /* - * Never schedule soaincrtime to occur after - * dumptime. - */ - if (zp->z_soaincrtime > zp->z_dumptime) - zp->z_soaincrtime = zp->z_dumptime; - ns_debug(ns_log_update, 3, - "schedule_dump('%s'): scheduled for %lu", - zp->z_origin, (u_long)zp->z_dumptime); - return (1); - } - } - return (0); -} - -/* - * int - * process_prereq(rec, rcodep) - * Process one prerequisite. - * returns: - * >0 prerequisite was satisfied. - * =0 prerequisite was not satisfied, or an error occurred. - * side effects: - * sets *rcodep if an error occurs or prerequisite isn't satisfied. - */ -static int -process_prereq(ns_updrec *ur, int *rcodep, u_int16_t zclass) { - const char *dname = ur->r_dname; - u_int16_t class = ur->r_class; - u_int16_t type = ur->r_type; - u_int32_t ttl = ur->r_ttl; - struct databuf *rdp = ur->r_dp; - const char *fname; - struct hashbuf *htp; - struct namebuf *np; - struct databuf *dp; - - /* - * An element in the list might have already been - * processed if it is in the same RRset as a previous - * RRset Exists (value dependent) prerequisite. - */ - if (rdp && (rdp->d_mark & D_MARK_FOUND) != 0) { - /* Already processed. */ - return (1); - } - if (ttl != 0) { - ns_debug(ns_log_update, 1, - "process_prereq: ttl!=0 in prereq section"); - *rcodep = FORMERR; - return (0); - } - htp = hashtab; - np = nlookup(dname, &htp, &fname, 0); - /* - * Matching by wildcard not allowed here. - * We need to post check for a wildcard match. - */ - if (fname != dname || - (np != NULL && ns_wildcard(NAME(*np)) && - (dname[0] != '*' || (dname[1] != '.' && dname[1] != '\0')))) - np = NULL; - - if (class == C_ANY) { - if (rdp->d_size) { - ns_debug(ns_log_update, 1, - "process_prereq: empty rdata required in prereq section with class=ANY"); - *rcodep = FORMERR; - return (0); - } - if (type == T_ANY) { - /* Name is in use. */ - ur->r_opcode = YXDOMAIN; - if (np == NULL || np->n_data == NULL) { - /* - * Name does not exist or is - * an empty nonterminal. - */ - ns_debug(ns_log_update, 1, - "process_prereq: %s not in use", - dname); - *rcodep = NXDOMAIN; - return (0); - } - } else { - /* RRset exists (value independent). */ - int found = 0; - - ur->r_opcode = YXRRSET; - if (np != NULL) - for (dp = np->n_data; - dp && !found; - dp = dp->d_next) - if (match(dp, class, type) && - dp->d_type == type) - found = 1; - if (!found) { - ns_debug(ns_log_update, 1, - "process_prereq: RRset (%s,%s,%s) does not exist", - dname, p_type(type), p_class(zclass)); - *rcodep = NXRRSET; - return (0); - } - } - } else if (class == C_NONE) { - if (rdp->d_size) { - ns_debug(ns_log_update, 1, - "process_prereq: empty rdata required in prereq section with class=NONE"); - *rcodep = FORMERR; - return (0); - } - if (type == T_ANY) { - /* Name is not in use. */ - ur->r_opcode = NXDOMAIN; - if (np != NULL && np->n_data != NULL) { - /* - * Name exists and is not an - * empty nonterminal. - */ - ns_debug(ns_log_update, 1, - "process_prereq: %s exists", - dname); - *rcodep = YXDOMAIN; - return (0); - } - } else { - /* RRset does not exist. */ - int found = 0; - - ur->r_opcode = NXRRSET; - class = zclass; - if (np != NULL) - for (dp = np->n_data; - dp && !found; - dp = dp->d_next) - if (match(dp, class, type)) - found = 1; - if (found) { - ns_debug(ns_log_update, 1, - "process_prereq: RRset (%s,%s) exists", - dname, p_type(type)); - *rcodep = YXRRSET; - return (0); - } - } - } else if (class == zclass) { - /* - * RRset exists (value dependent). - * - * Check for RRset equality also. - */ - ns_updrec *tmp; - - ur->r_opcode = YXRRSET; - if (!rdp) { - ns_debug(ns_log_update, 1, - "process_prereq: nonempty rdata required in prereq section with class=%s", - p_class(class)); - *rcodep = FORMERR; - return (0); - } - if (np == NULL || fname != dname) { - *rcodep = NXRRSET; - return (0); - } - for (dp = np->n_data; dp; dp = dp->d_next) { - if (match(dp, class, type) && dp->d_type == type) { - int found = 0; - - for (tmp = ur; - tmp != NULL && !found; - tmp = NEXT(tmp, r_link)) { - if (tmp->r_section != S_PREREQ) - break; - if (!db_cmp(dp, tmp->r_dp)) { - tmp->r_dp->d_mark |= - D_MARK_FOUND; - found = 1; - } - } - if (!found) { - *rcodep = NXRRSET; - return (0); - } - } - } - for (tmp = ur; tmp != NULL; tmp = NEXT(tmp, r_link)) - if (tmp->r_section == S_PREREQ && - ns_samename(dname, tmp->r_dname) == 1 && - tmp->r_class == class && - tmp->r_type == type && - (ur->r_dp->d_mark & D_MARK_FOUND) == 0) { - *rcodep = NXRRSET; - return (0); - } else { - tmp->r_opcode = YXRRSET; - } - } else { - ns_debug(ns_log_update, 1, - "process_prereq: incorrect class %s", - p_class(class)); - *rcodep = FORMERR; - return (0); - } - /* Through the gauntlet, and out. */ - return (1); -} - -static int -prescan_nameok(ns_updrec *ur, int *rcodep, u_int16_t zclass, - struct zoneinfo *zp) { - const char *dname = ur->r_dname; - const char *owner = ur->r_dname; - u_int16_t class = ur->r_class; - u_int16_t type = ur->r_type; - char *cp = (char *)ur->r_dp->d_data; - enum context context; - - int ret = 1; - - /* We don't care about deletes */ - if (ur->r_class != zclass) - return (1); - - context = ns_ownercontext(type, primary_trans); - if (!ns_nameok(NULL, owner, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - - switch (type) { - case ns_t_soa: - context = hostname_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - cp += strlen(cp) + 1; - context = mailname_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_rp: - context = mailname_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - cp += strlen(cp) + 1; - context = domain_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_minfo: - context = mailname_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - cp += strlen(cp) + 1; - context = mailname_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_ns: - context = hostname_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_cname: - case ns_t_mb: - case ns_t_mg: - case ns_t_mr: - context = domain_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_ptr: - context = ns_ptrcontext(owner); - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_naptr: - /* - * Order (2) - * Preference (2) - * Flags (1) - */ - cp += 5; - /* Service (txt) */ - cp += strlen(cp) + 1; - /* Pattern (txt) */ - cp += strlen(cp) + 1; - context = domain_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_srv: - cp += 4; - /* FALLTHROUGH */ - case ns_t_mx: - case ns_t_afsdb: - case ns_t_rt: - case ns_t_kx: - cp += 2; - context = hostname_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_px: - cp += 2; - context = domain_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - cp += strlen(cp) + 1; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_sig: - /* - * Type covered (2) - * Alg (1) * - * Labels (1) - * ttl (4) - * expires (4) - * signed (4) - * footprint (2) - */ - cp += 18; - context = domain_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - case ns_t_nxt: - context = domain_ctx; - if (!ns_nameok(NULL, cp, class, zp, primary_trans, context, owner, - inaddr_any)) - goto refused; - break; - default: - break; - } - return (1); - refused: - *rcodep = REFUSED; - return (0); -} - -/* - * int - * prescan_update(ur, rcodep) - * Process one prerequisite. - * returns: - * >0 update looks OK (format wise; who knows if it will succeed?) - * =0 update has something wrong with it. - * side effects: - * sets *rcodep if an error occurs or prerequisite isn't satisfied. - */ -static int -prescan_update(ns_updrec *ur, int *rcodep, u_int16_t zclass) { - const char *dname = ur->r_dname; - u_int16_t class = ur->r_class; - u_int16_t type = ur->r_type; - u_int32_t ttl = ur->r_ttl; - struct databuf *rdp = ur->r_dp; - const char *fname; - struct hashbuf *htp; - struct namebuf *np; - - if (class == zclass) { - if (!ns_t_rr_p(type)) { - ns_debug(ns_log_update, 1, - "prescan_update: invalid type (%s)", - p_type(type)); - *rcodep = FORMERR; - return (0); - } - if (ttl > MAXIMUM_TTL) { - ns_debug(ns_log_update, 1, - "prescan_update: invalid ttl (%u)", ttl); - *rcodep = FORMERR; - return (0); - } - } else if (class == C_ANY) { - if (ttl != 0 || rdp->d_size || - (!ns_t_rr_p(type) && type != T_ANY)) - { - ns_debug(ns_log_update, 1, - "prescan_update: formerr(#2)"); - *rcodep = FORMERR; - return (0); - } - } else if (class == C_NONE) { - if (ttl != 0 || !ns_t_rr_p(type)) { - ns_debug(ns_log_update, 1, - "prescan_update: formerr(#3) %d %s", - ttl, p_type(type)); - *rcodep = FORMERR; - return (0); - } - } else { - ns_debug(ns_log_update, 1, - "prescan_update: invalid class (%s)", - p_class(class)); - *rcodep = FORMERR; - return (0); - } - /* No format errors found. */ - return (1); -} - -/* - * int - * process_updates(updlist, rcodep, from) - * Process prerequisites and apply updates from the list to the database. - * returns: - * number of successful updates, 0 if none were successful. - * side effects: - * *rcodep gets the transaction return code. - * can schedule maintainance for zone dumps and soa.serial# increments. - */ -static int -process_updates(const ns_updque *updlist, int *rcodep, - struct sockaddr_in from) -{ - int i, j, n, dbflags, matches, zonenum; - int numupdated = 0, soaupdated = 0, schedmaint = 0; - u_int16_t zclass; - ns_updrec *ur; - const char *fname; - struct databuf *dp, *savedp; - struct zoneinfo *zp; - int zonelist[MAXDNAME]; - - *rcodep = SERVFAIL; - if (EMPTY(*updlist)) - return (0); - ur = HEAD(*updlist); - if (ur->r_section == S_ZONE) { - zclass = ur->r_class; - zonenum = ur->r_zone; - zp = &zones[zonenum]; - } else { - ns_debug(ns_log_update, 1, - "process_updates: missing zone record"); - return (0); - } - - /* Process prereq records and prescan update records. */ - for (ur = HEAD(*updlist); ur != NULL; ur = NEXT(ur, r_link)) { - const char * dname = ur->r_dname; - u_int16_t class = ur->r_class; - u_int16_t type = ur->r_type; - u_int32_t ttl = ur->r_ttl; - struct databuf *rdp = ur->r_dp; - u_int section = ur->r_section; - - ns_debug(ns_log_update, 3, -"process_update: record section=%s, dname=%s, \ -class=%s, type=%s, ttl=%d, dp=0x%0x", - p_section(section, ns_o_update), dname, - p_class(class), p_type(type), ttl, rdp); - - matches = findzone(dname, zclass, MAXDNAME, - zonelist, MAXDNAME); - ur->r_zone = 0; - for (j = 0; j < matches && !ur->r_zone; j++) - if (zonelist[j] == zonenum) - ur->r_zone = zonelist[j]; - if (!ur->r_zone || - (section != S_ADDT && type == T_SOA && - ns_samename(dname, zp->z_origin) != 1)) { - ns_debug(ns_log_update, 1, - "process_updates: record does not belong to the zone %s", - zones[zonenum].z_origin); - *rcodep = NOTZONE; - return (0); - } - - switch (section) { - case S_ZONE: - break; - case S_PREREQ: - if (!process_prereq(ur, rcodep, zclass)) - return (0); /* *rcodep has been set. */ - ns_debug(ns_log_update, 3, "prerequisite satisfied"); - break; - case S_UPDATE: - if (!prescan_update(ur, rcodep, zclass)) - return (0); /* *rcodep has been set. */ - if (!prescan_nameok(ur, rcodep, zclass, zp)) - return (0); /* *rcodep has been set. */ - ns_debug(ns_log_update, 3, "update prescan succeeded"); - break; - case S_ADDT: - break; - default: - ns_panic(ns_log_update, 1, - "process_updates: impossible section"); - /* NOTREACHED */ - } - } - - /* Now process the records in update section. */ - for (ur = HEAD(*updlist); ur != NULL; ur = NEXT(ur, r_link)) { - const char * dname = ur->r_dname; - u_int16_t class = ur->r_class; - - if (ur->r_section != S_UPDATE) - continue; - dbflags = 0; - savedp = NULL; - dp = ur->r_dp; - if (class == zp->z_class) { - /* ADD databuf dp to hash table */ - /* - * Handling of various SOA/WKS/CNAME scenarios - * is done in db_update(). - */ - ur->r_opcode = ADD; - dbflags |= DB_NODATA | DB_REPLACE; - n = db_update(dname, dp, dp, &savedp, - dbflags, hashtab, from); - if (!((n == OK) || - ((zp->z_xferpid == XFER_ISIXFR) && (n == DATAEXISTS)))) { - ns_debug(ns_log_update, 3, - "process_updates: failed to add databuf (%d)", - n); - } else { - ns_debug(ns_log_update, 3, - "process_updates: added databuf 0x%0x", - dp); - dp->d_mark = D_MARK_ADDED; - numupdated++; - if (dp->d_type == T_SOA) - soaupdated = 1; - } - } else if (class == C_ANY || class == C_NONE) { - /* - * DELETE databuf's matching dp from the hash table. - * - * handling of various SOA/NS scenarios done - * in db_update(). - */ - ur->r_opcode = DELETE; - /* - * we know we're deleting now, and db_update won't - * match with class==C_NONE, so we use the zone's - * class. - */ - if (class == C_NONE) - ur->r_dp->d_class = zp->z_class; - dbflags |= DB_DELETE; - n = db_update(dname, dp, NULL, &savedp, - dbflags, hashtab, from); - if (!((n == OK) || - ((zp->z_xferpid == XFER_ISIXFR) && (n == NODATA)))) { - ns_debug(ns_log_update, 3, - "process_updates: delete failed"); - } else { - ns_debug(ns_log_update, 3, - "process_updates: delete succeeded"); - numupdated++; - } - } - /* - * Even an addition could have caused some deletions like - * replacing old SOA or CNAME or WKS record or records of - * lower cred/clev. - * - * We need to save the deleted databuf's in case we wish to - * abort this update transaction and roll back all updates - * applied from this packet. - */ - ur->r_deldp = savedp; - } - - /* - * If we got here, things are OK, so set rcodep to indicate so. - */ - *rcodep = NOERROR; - - if (!numupdated) - return (0); - - /* - * schedule maintenance for dumps and SOA.serial# increment - * (this also sets Z_NEED_DUMP and Z_NEED_SOAUPDATE appropriately) - */ - schedmaint = 0; - if (schedule_dump(zp)) - schedmaint = 1; - if (soaupdated) { - /* - * SOA updated by this update transaction, so - * we need to set the zone serial number, stop any - * automatic updates that may be pending, and send out - * a NOTIFY message. - */ - zp->z_serial = get_serial_unchecked(zp); - cancel_soa_update(zp); - schedmaint = 1; -#ifdef BIND_NOTIFY - if (!loading) - ns_notify(zp->z_origin, zp->z_class, ns_t_soa); -#endif - } else { - if (schedule_soa_update(zp, numupdated)) - schedmaint = 1; - } - if (schedmaint) - sched_zone_maint(zp); - return (numupdated); -} - -static enum req_action -req_update_private(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, - struct qstream *qsp, int dfd, struct sockaddr_in from, - struct tsig_record *in_tsig) -{ - char dnbuf[MAXDNAME], *dname; - u_int zocount, prcount, upcount, adcount, class, type, dlen; - u_int32_t ttl; - int i, n, cnt, found, matches, zonenum, numupdated = 0; - int rcode = NOERROR; - u_int c, section; - u_char rdata[MAXDATA]; - struct qinfo *qp; - struct databuf *dp, *nsp[NSMAX]; - struct databuf **nspp = &nsp[0]; - struct zoneinfo *zp; - ns_updrec *rrecp; - int zonelist[MAXDNAME]; - int should_use_tcp; - u_int32_t old_serial; - int unapproved_ip = 0; - int tsig_len; - DST_KEY *in_key = (in_tsig != NULL) ? in_tsig->key : NULL; - - nsp[0] = NULL; - - zocount = ntohs(hp->qdcount); - prcount = ntohs(hp->ancount); - upcount = ntohs(hp->nscount); - adcount = ntohs(hp->arcount); - - /* Process zone section. */ - ns_debug(ns_log_update, 3, "req_update: section ZONE, count %d", - zocount); - if ((n = dn_expand(msg, eom, cp, dnbuf, sizeof(dnbuf))) < 0) { - ns_debug(ns_log_update, 1, "req_update: expand name failed"); - hp->rcode = FORMERR; - return (Finish); - } - dname = dnbuf; - cp += n; - if (cp + 2 * INT16SZ > eom) { - ns_debug(ns_log_update, 1, "req_update: too short"); - hp->rcode = FORMERR; - return (Finish); - } - GETSHORT(type, cp); - GETSHORT(class, cp); - if (zocount != 1 || type != T_SOA) { - ns_debug(ns_log_update, 1, - "req_update: incorrect count or type for zone section: %d", - zocount); - hp->rcode = FORMERR; - return (Finish); - } - - matches = findzone(dname, class, 0, zonelist, MAXDNAME); - if (matches == 1) { - zonenum = zonelist[0]; - zp = &zones[zonenum]; - if (zp->z_class != (int)class || - (zp->z_type != z_master && zp->z_type != z_slave)) - matches = 0; - } - if (matches != 1) { - ns_debug(ns_log_update, 1, - "req_update: non-authoritative server for %s", - dname); - hp->rcode = NOTAUTH; - return (Finish); - } - - /* - * Begin Access Control Point - */ - - if (!ip_addr_or_key_allowed(zp->z_update_acl, from.sin_addr, in_key)) { - ns_notice(ns_log_security, "denied update from %s for %s", - sin_ntoa(from), *dname ? dname : "."); - nameserIncr(from.sin_addr, nssRcvdUUpd); - return (Refuse); - } - - /* - * End Access Control Point - */ - - /* we should be authoritative */ - if (!(zp->z_flags & Z_AUTH)) { - ns_debug(ns_log_update, 1, - "req_update: zone %s: Z_AUTH not set", - dname); - hp->rcode = NOTAUTH; - return (Finish); - } - - if (zp->z_type == Z_SECONDARY) { - /* - * XXX The code below is broken. - * Until fixed, we just return NOTIMPL. - */ -#if 1 - hp->rcode = ns_r_notimpl; - return (Finish); -#else - /* We are a slave for this zone, forward it to the master. */ - for (cnt = 0; cnt < zp->z_addrcnt; cnt++) - *nspp++ = savedata(zp->z_class, T_A, USE_MINIMUM, - (u_char *)&zp->z_addr[cnt].s_addr, - INT32SZ); - *nspp = NULL; - /* - * If the request came in over TCP, forward it over TCP - */ - should_use_tcp = (qsp != NULL); - if (in_tsig != NULL) { - tsig_len = ns_skiprr(eom, eom + TSIG_BUF_SIZE, - ns_s_ar, 1); - eom += tsig_len; - } - n = ns_forw(nsp, msg, eom-msg, from, qsp, dfd, &qp, - dname, class, type, NULL, should_use_tcp, NULL); - if (in_tsig != NULL) - eom -= tsig_len; - free_nsp(nsp); - switch (n) { - case FW_OK: - case FW_DUP: - return (Return); - case FW_NOSERVER: - /* should not happen */ - case FW_SERVFAIL: - hp->rcode = SERVFAIL; - return (Finish); - } -#endif - } - /* - * We are the primary master server for this zone, - * proceed further and process update packet - */ - if (!(zp->z_flags & Z_DYNAMIC)) { - ns_debug(ns_log_update, 1, - "req_update: dynamic flag not set for zone %s", - dname); - return (Refuse); - } - old_serial = get_serial(zp); - ns_debug(ns_log_update, 3, - "req_update: update request for zone %s, class %s", - zp->z_origin, p_class(class)); - rrecp = res_mkupdrec(S_ZONE, dname, class, type, 0); - rrecp->r_zone = zonenum; - - APPEND(curupd, rrecp, r_link); - - /* - * Parse the prerequisite and update sections for format errors. - */ - for (i = 0; (u_int)i < prcount + upcount; i++) { - if ((n = dn_expand(msg, eom, cp, dnbuf, sizeof(dnbuf))) < 0) { - ns_debug(ns_log_update, 1, - "req_update: expand name failed"); - hp->rcode = FORMERR; - return (Finish); - } - dname = dnbuf; - cp += n; - if (cp + RRFIXEDSZ > eom) { - ns_debug(ns_log_update, 1, - "req_update: overrun in answer"); - hp->rcode = FORMERR; - return (Finish); - } - GETSHORT(type, cp); - GETSHORT(class, cp); - if (class > CLASS_MAX) { - ns_debug(ns_log_update, 1, - "req_update: bad class"); - hp->rcode = FORMERR; - return (Finish); - } - GETLONG(ttl, cp); - GETSHORT(dlen, cp); - n = 0; - dp = NULL; - if (dlen > 0) { - if (cp + dlen > eom) { - ns_debug(ns_log_update, 1, - "req_update: bad dlen"); - hp->rcode = FORMERR; - return (Finish); - } - n = rdata_expand(msg, eom, cp, type, dlen, - rdata, sizeof rdata); - if (n == 0 || n > MAXDATA) { - ns_debug(ns_log_update, 1, - "req_update: failed to expand record"); - hp->rcode = FORMERR; - return (Finish); - } - cp += dlen; - } - section = ((u_int)i < prcount) ? S_PREREQ : S_UPDATE; - rrecp = res_mkupdrec(section, dname, class, type, ttl); - dp = savedata(class, type, ttl, rdata, n); - dp->d_zone = zonenum; - dp->d_cred = DB_C_ZONE; - dp->d_secure = DB_S_INSECURE; /* should be UNCHECKED */ - dp->d_clev = nlabels(zp->z_origin); - /* XXX - also record in dp->d_ns, which host this came from */ - rrecp->r_dp = dp; - /* Append the current record to the end of list of records. */ - APPEND(curupd, rrecp, r_link); - if (cp > eom) { - ns_info(ns_log_update, - "Malformed response from %s (overrun)", - inet_ntoa(from.sin_addr)); - hp->rcode = FORMERR; - return (Finish); - } - } - - /* Now process all parsed records in the prereq and update sections. */ - numupdated = process_updates(&curupd, &rcode, from); - hp->rcode = rcode; - if (numupdated <= 0) { - if (rcode != NOERROR) - ns_error(ns_log_update, - "error processing update packet (%s) id %d from %s", - p_rcode(rcode), ntohs(hp->id), sin_ntoa(from)); - return (Finish); - } - - /* - * Stop any outbound zone transfers. - * (Eventlib is synchronous for this.) - */ - ns_stopxfrs(zp); - - /* Make a log of the update. */ - (void) printupdatelog(from, &curupd, hp, zp, old_serial); - - return (Finish); -} - -void -free_rrecp(ns_updque *updlist, int rcode, struct sockaddr_in from) { - ns_updrec *rrecp, *first_rrecp, *next_rrecp; - struct databuf *dp, *tmpdp; - char *dname, *msg; - - if (rcode == NOERROR) { - first_rrecp = HEAD(*updlist); - msg = "free_rrecp: update transaction succeeded, cleaning up"; - } else { - first_rrecp = TAIL(*updlist); - msg = "free_rrecp: update transaction aborted, rolling back"; - } - ns_debug(ns_log_update, 1, msg); - for (rrecp = first_rrecp; rrecp != NULL; rrecp = next_rrecp) { - if (rcode == NOERROR) - next_rrecp = NEXT(rrecp, r_link); - else - next_rrecp = PREV(rrecp, r_link); - if (rrecp->r_section != S_UPDATE) { - if (rrecp->r_dp) - db_freedata(rrecp->r_dp); - res_freeupdrec(rrecp); - continue; - } - dname = rrecp->r_dname; - dp = rrecp->r_dp; - if ((dp->d_mark & D_MARK_ADDED) != 0) { - if (rcode == NOERROR) { - /* - * This databuf is now a part of hashtab, - * or has been deleted by a subsequent update. - * Either way, we must not free it. - */ - dp->d_mark &= ~D_MARK_ADDED; - } else { - /* Delete the databuf. */ - if (db_update(dname, dp, NULL, NULL, - DB_DELETE, hashtab, from) - != OK) { - ns_error(ns_log_update, - "free_rrecp: failed to delete databuf: dname=%s, type=%s", - dname, p_type(dp->d_type)); - } else { - ns_debug(ns_log_update, 3, - "free_rrecp: deleted databuf 0x%0x", - dp); - /* - * XXXRTH - * - * We used to db_freedata() here, - * but I removed it because 'dp' was - * part of a hashtab before we called - * db_update(), and since our delete - * has succeeded, it should have been - * freed. - */ - } - } - } else { - /* - * Databuf's matching this were deleted by this - * update, or were never executed (because we bailed - * out early). - */ - db_freedata(dp); - } - - /* Process deleted databuf's. */ - dp = rrecp->r_deldp; - while (dp != NULL) { - tmpdp = dp; - dp = dp->d_next; - if (rcode == NOERROR) { - if (tmpdp->d_rcnt) - ns_debug(ns_log_update, 1, - "free_rrecp: type = %d, rcnt = %d", - p_type(tmpdp->d_type), - tmpdp->d_rcnt); - else { - tmpdp->d_next = NULL; - db_freedata(tmpdp); - } - } else { - /* Add the databuf back. */ - tmpdp->d_mark &= ~D_MARK_DELETED; - if (db_update(dname, tmpdp, tmpdp, NULL, - DB_REPLACE, hashtab, from) != OK) { - ns_error(ns_log_update, - "free_rrecp: failed to add back databuf: dname=%s, type=%s", - dname, p_type(tmpdp->d_type)); - } else { - ns_debug(ns_log_update, 3, - "free_rrecp: added back databuf 0x%0x", - tmpdp); - } - } - } - res_freeupdrec(rrecp); - } - INIT_LIST(*updlist); -} - -enum req_action -req_update(HEADER *hp, u_char *cp, u_char *eom, u_char *msg, - struct qstream *qsp, int dfd, struct sockaddr_in from, - struct tsig_record *in_tsig) -{ - enum req_action ret; - - INIT_LIST(curupd); - ret = req_update_private(hp, cp, eom, msg, qsp, dfd, from, in_tsig); - free_rrecp(&curupd, ret == Refuse ? ns_r_refused : hp->rcode, from); - if (ret == Finish) { - hp->qdcount = hp->ancount = hp->nscount = hp->arcount = 0; - memset(msg + HFIXEDSZ, 0, (eom - msg) - HFIXEDSZ); - } - return (ret); -} - -/* - * expand rdata portion of a compressed resource record at cp into cp1 - * and return the length of the expanded rdata (length of the compressed - * rdata is "dlen"). - */ -static int -rdata_expand(const u_char *msg, const u_char *eom, const u_char *cp, - u_int type, size_t dlen, u_char *cp1, size_t size) -{ - const u_char *cpinit = cp; - const u_char *cp1init = cp1; - int n, i, n1; - - switch (type) { - case T_A: - case T_AAAA: - if ((type == T_A && dlen != INT32SZ) || - (type == T_AAAA && dlen != NS_IN6ADDRSZ)) - return (0); - /*FALLTHROUGH*/ - case T_WKS: - case T_HINFO: - case T_TXT: - case T_X25: - case T_ISDN: - case T_NSAP: - case T_LOC: - case T_KEY: - case ns_t_cert: - if (size < dlen) - return (0); - memcpy(cp1, cp, dlen); - return (dlen); - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - n = dn_expand(msg, eom, cp, (char *)cp1, size); - if (n < 0 || (u_int)n != dlen) - return (0); - return (strlen((char *)cp1) + 1); - case T_MINFO: - case T_SOA: - case T_RP: - /* Get two compressed domain names. */ - for (i = 0; i < 2; i++) { - n = dn_expand(msg, eom, cp, (char *)cp1, size); - if (n < 0) - return (0); - cp += n; - n = strlen((char *)cp1) + 1; - cp1 += n; - size -= n; - } - if (type == T_SOA) { - n = 5 * INT32SZ; - if (size < (size_t)n || cp + n > eom) - return(0); - size -= n; - memcpy(cp1, cp, n); - cp += n; - cp1 += n; - } - if (cp != cpinit + dlen) - return (0); - return (cp1 - cp1init); - case T_MX: - case T_AFSDB: - case T_RT: - case T_SRV: - /* Grab preference. */ - if (size < INT16SZ || cp + INT16SZ > eom) - return (0); - size -= INT16SZ; - memcpy(cp1, cp, INT16SZ); - cp += INT16SZ; - cp1 += INT16SZ; - - if (type == T_SRV) { - if (size < INT16SZ*2 || cp + INT16SZ*2 > eom) - return (0); - size -= INT16SZ*2; - /* Grab weight and port. */ - memcpy(cp1, cp, INT16SZ*2); - cp1 += INT16SZ*2; - cp += INT16SZ*2; - } - - /* Get name. */ - n = dn_expand(msg, eom, cp, (char *)cp1, size); - if (n < 0) - return (0); - cp += n; - n = strlen((char *)cp1) + 1; - cp1 += n; - if (cp != cpinit + dlen) - return (0); - return (cp1 - cp1init); - case T_PX: - /* Grab preference. */ - if (size < INT16SZ || cp + INT16SZ > eom) - return (0); - size -= INT16SZ; - memcpy(cp1, cp, INT16SZ); - cp += INT16SZ; - cp1 += INT16SZ; - /* Get MAP822 name. */ - n = dn_expand(msg, eom, cp, (char *)cp1, size); - if (n < 0) - return (0); - cp += n; - n = strlen((char *)cp1) + 1; - cp1 += n; - size -= n; - n = dn_expand(msg, eom, cp, (char *)cp1, size); - if (n < 0) - return (0); - cp += n; - n = strlen((char *)cp1) + 1; - cp1 += n; - if (cp != cpinit + dlen) - return (0); - return (cp1 - cp1init); - case T_SIG: - if (dlen < SIG_HDR_SIZE || size < dlen) - return (0); - memcpy(cp1, cp, SIG_HDR_SIZE); - size -= SIG_HDR_SIZE; - cp += SIG_HDR_SIZE; - cp1 += SIG_HDR_SIZE; - n = dn_expand(msg, eom, cp, (char *)cp1, size); - if (n < 0 || n + SIG_HDR_SIZE > dlen) - return (0); - cp += n; - n1 = dlen - n - SIG_HDR_SIZE; - n = strlen((char *)cp1) + 1; - cp1 += n; - if (size < n1) - return (0); - memcpy(cp1, cp, n1); - cp1 += n1; - return (cp1 - cp1init); - case T_NXT: - n = dn_expand(msg, eom, cp, (char *)cp1, size); - if (n < 0 || (u_int)n >= dlen) - return (0); - size -= n; - cp += n; - n1 = dlen - n; - n = strlen((char *)cp1) + 1; - cp1 += n; - /* - * The first bit of the first octet determines the format - * of the NXT record. A format for types >= 128 has not - * yet been defined, so if bit zero is set, we just copy - * what's there because we don't understand it. - */ - if ((*cp & 0x80) == 0) { - /* - * Bit zero is not set; this is an ordinary NXT - * record. The bitmap must be at least 4 octets - * because the NXT bit should be set. It should be - * less than or equal to 16 octets because this NXT - * format is only defined for types < 128. - */ - if (n1 < 4 || n1 > 16) - return (0); - } - if (n1 > size) - return (0); - memcpy(cp1, cp, n1); - cp1 += n1; - return (cp1 - cp1init); - default: - ns_debug(ns_log_update, 3, "unknown type %d", type); - return (0); - } -} - -/* - * Print out rdata portion of a resource record from a databuf into a file. - * - * XXX - similar code in db_dump() should be replaced by a call to this - * function. - */ -void -rdata_dump(struct databuf *dp, FILE *fp) { - u_int32_t n, addr; - u_char *cp, *end; - int i, j; - const char *proto; - u_char *savecp; - char temp_base64[NS_MD5RSA_MAX_BASE64]; - u_int16_t keyflags; - u_char *sigdata, *certdata; - - cp = (u_char *)dp->d_data; - switch (dp->d_type) { - case T_A: - switch (dp->d_class) { - case C_IN: - case C_HS: - GETLONG(n, cp); - n = htonl(n); - fputs(inet_ntoa(*(struct in_addr *)&n), fp); - break; - } - if (dp->d_nstime) - fprintf(fp, ";\tNT=%d", dp->d_nstime); - break; - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_PTR: - fprintf(fp, "%s.", cp); - break; - case T_NS: - cp = (u_char *)dp->d_data; - if (cp[0] == '\0') - fprintf(fp, ".\t"); - else - fprintf(fp, "%s.", cp); - break; - case T_HINFO: - case T_ISDN: - if ((n = *cp++) != '\0') { - fprintf(fp, "\"%.*s\"", (int)n, cp); - cp += n; - } else - fprintf(fp, "\"\""); - if ((n = *cp++) != '\0') - fprintf(fp, " \"%.*s\"", (int)n, cp); - else - fprintf(fp, " \"\""); - break; - case T_SOA: - fprintf(fp, "%s.", cp); - cp += strlen((char *)cp) + 1; - fprintf(fp, " %s. ( ", cp); -#if defined(RETURNSOA) && defined(NCACHE) - if (dp->d_rcode == NXDOMAIN) - fputs(";", fp); -#endif - cp += strlen((char *)cp) + 1; - GETLONG(n, cp); - fprintf(fp, "%u", n); - GETLONG(n, cp); - fprintf(fp, " %u", n); - GETLONG(n, cp); - fprintf(fp, " %u", n); - GETLONG(n, cp); - fprintf(fp, " %u", n); - GETLONG(n, cp); - fprintf(fp, " %u )", n); -#if defined(RETURNSOA) && defined(NCACHE) - if (dp->d_rcode == NXDOMAIN) - fprintf(fp, ";%s.;NXDOMAIN;\t-$", cp); -#endif - break; - case T_MX: - case T_AFSDB: - case T_RT: - GETSHORT(n, cp); - fprintf(fp, "%u", n); - fprintf(fp, " %s.", cp); - break; - case T_SRV: - GETSHORT(n, cp); /* priority */ - fprintf(fp, "%u ", n); - GETSHORT(n, cp); /* weight */ - fprintf(fp, "%u ", n); - GETSHORT(n, cp); /* port */ - fprintf(fp, "%u ", n); - fprintf(fp, " %s.", cp); - break; - case T_PX: - GETSHORT(n, cp); - fprintf(fp, "%u", n); - fprintf(fp, " %s.", cp); - cp += strlen((char *)cp) + 1; - fprintf(fp, " %s.", cp); - break; - case T_TXT: - case T_X25: - end = (u_char *)dp->d_data + dp->d_size; - (void) putc('"', fp); - while (cp < end) { - if ((n = *cp++) != '\0') { - for (j = n; j > 0 && cp < end; j--) - if ((*cp < ' ') || (*cp > '~')) { - fprintf(fp, "\\%03.3d", *cp++); - } else if (*cp == '\\' || *cp =='"') { - putc('\\', fp); - putc(*cp++, fp); - } else - (void) putc(*cp++, fp); - } - if (cp != end) - fputs("\" \"", fp); - } - /* XXXVIX need to keep the segmentation (see 4.9.5). */ - (void) fputs("\"", fp); - break; - case T_NSAP: - (void) fputs(inet_nsap_ntoa(dp->d_size, dp->d_data, NULL), fp); - break; - case T_LOC: - (void) fputs(loc_ntoa(dp->d_data, NULL), fp); - break; - case T_WKS: - GETLONG(addr, cp); - addr = htonl(addr); - fputs(inet_ntoa(*(struct in_addr *)&addr), fp); - proto = protocolname((u_char)*cp); - cp += sizeof(char); - fprintf(fp, "%s ", proto); - i = 0; - while(cp < (u_char *)dp->d_data + dp->d_size) { - j = *cp++; - do { - if (j & 0200) - fprintf(fp, " %s", - servicename(i, proto)); - j <<= 1; - } while (++i & 07); - } - break; - case T_MINFO: - case T_RP: - fprintf(fp, "%s.", cp); - cp += strlen((char *)cp) + 1; - fprintf(fp, " %s.", cp); - break; - case T_KEY: - savecp = cp; /* save the beginning */ - /*>>> Flags (unsigned_16) */ - NS_GET16(keyflags,cp); - fprintf(fp, "0x%04x ", keyflags); - /*>>> Protocol (8-bit decimal) */ - fprintf(fp, "%3u ", *cp++); - /*>>> Algorithm id (8-bit decimal) */ - fprintf(fp, "%3u ", *cp++); - - /*>>> Public-Key Data (multidigit BASE64) */ - /* containing ExponentLen, Exponent, and Modulus */ - i = b64_ntop(cp, dp->d_size - (cp - savecp), - temp_base64, sizeof temp_base64); - if (i < 0) - fprintf(fp, "; BAD BASE64"); - else - fprintf(fp, "%s", temp_base64); - break; - case T_SIG: - sigdata = cp; - /* RRtype (char *) */ - NS_GET16(n,cp); - fprintf(fp, "%s ", p_type(n)); - /* Algorithm id (8-bit decimal) */ - fprintf(fp, "%d ", *cp++); - /* Labels (8-bit decimal) (not saved in file) */ - /* XXXX FIXME -- check value and print err if bad */ - cp++; - /* OTTL (u_long) */ - NS_GET32(n, cp); - fprintf(fp, "%u ", n); - /* Texp (u_long) */ - NS_GET32(n, cp); - fprintf(fp, "%s ", p_secstodate (n)); - /* Tsig (u_long) */ - NS_GET32(n, cp); - fprintf(fp, "%s ", p_secstodate (n)); - /* Kfootprint (unsigned_16) */ - NS_GET16(n, cp); - fprintf(fp, "%u ", n); - /* Signer's Name (char *) */ - fprintf(fp, "%s ", cp); - cp += strlen((char *)cp) + 1; - /* Signature (base64 of any length) */ - i = b64_ntop(cp, dp->d_size - (cp - sigdata), - temp_base64, sizeof temp_base64); - if (i < 0) - fprintf(fp, "; BAD BASE64"); - else - fprintf(fp, "%s", temp_base64); - break; - - case T_NXT: - fprintf(fp, "%s.", cp); - n = strlen ((char *)cp) + 1; - cp += n; - i = 8 * (dp->d_size - n); /* How many bits? */ - for (n = 0; n < (u_int32_t)i; n++) { - if (NS_NXT_BIT_ISSET(n, cp)) - fprintf(fp," %s",__p_type(n)); - } - break; - case ns_t_cert: - certdata = cp; - NS_GET16(n,cp); - fprintf(fp, "%d ", n); /* cert type */ - - NS_GET16(n,cp); - fprintf(fp, "%d %d ", n, *cp++); /* tag & alg */ - - /* Certificate (base64 of any length) */ - i = b64_ntop(cp, dp->d_size - (cp - certdata), - temp_base64, sizeof(temp_base64)); - if (i < 0) - fprintf(fp, "; BAD BASE64"); - else - fprintf(fp, "%s", temp_base64); - break; - case ns_t_aaaa: { - char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - - (void) fputs(inet_ntop(AF_INET6, dp->d_data, t, sizeof t), fp); - break; - } - default: - fprintf(fp, "\t;?d_type=%d?", dp->d_type); - } -} - -/* - * Return the number of authoritative zones that "dname" could belong to by - * stripping up to "depth" labels from dname. Up to the first "maxzones" - * authoritative zone numbers will be stored in "zonelist", ordered - * deepest match first. - */ -int -findzone(const char *dname, int class, int depth, int *zonelist, int maxzones){ - char *tmpdname; - char tmpdnamebuf[MAXDNAME]; - char *zonename, *cp; - int tmpdnamelen, zonenamelen, zonenum, i, j, c; - int matches = 0; - int escaped, found, done; - - ns_debug(ns_log_update, 4, "findzone(dname=%s, class=%d, depth=%d, \ -zonelist=0x%x, maxzones=%d)", - dname, class, depth, zonelist, maxzones); -#ifdef DEBUG - if (debug >= 5) { - ns_debug(ns_log_update, 5, "zone dump:"); - for (zonenum = 1; zonenum < nzones; zonenum++) - printzoneinfo(zonenum, ns_log_update, 5); - } -#endif - - strcpy(tmpdnamebuf, dname); - tmpdname = tmpdnamebuf; - /* - * The code to handle trailing dots and escapes is adapted - * from ns_samedomain(). - */ - tmpdnamelen = strlen(tmpdname); - /* - * Ignore a trailing label separator (i.e. an unescaped dot) - * in 'tmpdname'. - */ - if (tmpdnamelen && tmpdname[tmpdnamelen-1] == '.') { - escaped = 0; - /* note this loop doesn't get executed if tmpdnamelen==1 */ - for (j = tmpdnamelen - 2; j >= 0; j--) - if (tmpdname[j] == '\\') { - if (escaped) - escaped = 0; - else - escaped = 1; - } else { - break; - } - if (!escaped) { - tmpdnamelen--; - tmpdname[tmpdnamelen] = '\0'; - } - } - - for (done = i = 0; i <= depth && !done; i++) { - for (zonenum = 1; zonenum < nzones; zonenum++) { - if (zones[zonenum].z_type == z_nil) - continue; - if (zones[zonenum].z_class != class) - continue; - zonename = zones[zonenum].z_origin; - zonenamelen = strlen(zonename); - /* - * Ignore a trailing label separator - * (i.e. an unescaped dot) in 'zonename'. - */ - if (zonenamelen && zonename[zonenamelen-1] == '.') { - escaped = 0; - for (j = zonenamelen - 2; j >= 0; j--) - if (zonename[j] == '\\') { - if (escaped) - escaped = 0; - else - escaped = 1; - } else { - break; - } - if (!escaped) - zonenamelen--; - } - - if (tmpdnamelen != zonenamelen) - continue; - ns_debug(ns_log_update, 5, - "about to strncasecmp('%s', '%s', %d)", - tmpdname, zonename, tmpdnamelen); - /* XXXRTH I'm doing a special test for zonenamelen == 0 - because I worry that some implementations of - strncasecmp might not handle comparisions where - n==0 correctly */ - if (zonenamelen == 0 || - !strncasecmp(tmpdname, zonename, tmpdnamelen)) { - ns_debug(ns_log_update, 5, "match"); - zonelist[matches++] = zonenum; - if (matches == maxzones) { - /* XXX should signal error */ - return (matches); - } - } - } - - /* - * Strip off the first label if we're not already at - * the root label. - */ - if (*tmpdname != '\0') { - for (escaped = found = 0; - (c = *tmpdname) && !found; - tmpdname++) { - if (!escaped && (c == '.')) - /* - * Note the loop increment will - * make tmpdname point past the '.' - * before the '!found' test causes - * us to exit the loop. - */ - found = 1; - - if (escaped) - escaped = 0; - else if (c == '\\') - escaped = 1; - } - } else - done = 1; - - tmpdnamelen = strlen(tmpdname); - } - ns_debug(ns_log_update, 4, - "findzone: returning %d match(es)", matches); - return (matches); -} - -/* - * reapply lost updates from log file for the zone to the zone - * - * returns -1 on error, 0 on success, 1 if dump reload needed - */ -int -merge_logs(struct zoneinfo *zp, char *logname) { - char origin[MAXDNAME], data[MAXDATA], dnbuf[MAXDNAME], sclass[3]; - char buf[BUFSIZ], buf2[100]; - FILE *fp; - u_int32_t serial, ttl, old_serial, new_serial; - char *dname, *cp, *cp1; - int type, class; - int i, c, section, opcode, matches, zonenum, err, multiline; - int nonempty_lineno = -1, prev_pktdone = 0, cont = 0, inside_next = 0; - int id, rcode = NOERROR; - u_int32_t n; - struct map *mp; - ns_updrec *rrecp; - struct databuf *dp; - struct in_addr ina; - int zonelist[MAXDNAME]; - struct stat st; - u_char *serialp; - struct sockaddr_in empty_from; - int datasize; - unsigned long l; - - empty_from.sin_family = AF_INET; - empty_from.sin_addr.s_addr = htonl(INADDR_ANY); - empty_from.sin_port = htons(0); - - /* XXX - much of this stuff is similar to that in nsupdate.c - * getword_str() was used in nsupdate.c for reasons described there - * getword() is used here just to be consistent with db_load() - */ - - ns_debug(ns_log_update, 3, "merge_logs(%s)", logname); - - /* If there is no log file, just return. */ - if (stat(logname, &st) < 0) { - if (errno != ENOENT) - ns_error(ns_log_update, - "unexpected stat(%s) failure: %s", - logname, strerror(errno)); - return (-1); - } - fp = fopen(logname, "r"); - if (fp == NULL) { - ns_error(ns_log_update, "fopen(%s) failed: %s", - logname, strerror(errno)); - return (-1); - } - - /* - * See if we really have a log file -- it might be a zone dump - * that was in the process of being movefiled, or it might - * be garbage! - */ - - if (fgets(buf, sizeof(buf), fp)==NULL) { - ns_error(ns_log_update, "fgets() from %s failed: %s", - logname, strerror(errno)); - fclose(fp); - return (-1); - } - if (strcmp(buf, DumpSignature) == 0) { - /* It's a dump; finish movefile that was interrupted. */ - ns_info(ns_log_update, - "completing interrupted dump movefile for %s", - zp->z_source); - fclose(fp); - if (movefile(logname, zp->z_source) < 0) { - ns_error(ns_log_update, "movefile(%s,%s) failed: %s :1", - logname, zp->z_source, - strerror(errno)); - fclose(fp); - return (-1); - } - /* Finally, tell caller to reload zone. */ - return (1); - } - if (strcmp(buf, LogSignature) != 0) { - /* Not a dump and not a log; complain and then bail out. */ - ns_error(ns_log_update, "invalid log file %s", - logname); - fclose(fp); - return (-1); - } - - ns_debug(ns_log_update, 3, "merging logs for %s from %s", - zp->z_origin, logname); - lineno = 1; - INIT_LIST(curupd); - for (;;) { - err = 0; - if (!getword(buf, sizeof buf, fp, 0)) { - if (lineno == (nonempty_lineno + 1) && !(feof(fp))) { - /* - * End of a nonempty line inside an update - * packet or not inside an update packet. - */ - continue; - } - /* - * Empty line or EOF. - * - * Marks completion of current update packet. - */ - inside_next = 0; - prev_pktdone = 1; - cont = 1; - } else { - nonempty_lineno = lineno; - } - - if (!strcasecmp(buf, "[DYNAMIC_UPDATE]") || - !strcasecmp(buf, "[IXFR_UPDATE]")) { - err = 0; - rcode = NOERROR; - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || !sscanf((char *)cp, "id %d", &id)) - id = -1; - inside_next = 1; - prev_pktdone = 1; - cont = 1; - } else if (!strcasecmp(buf, "[INCR_SERIAL]")) { - /* XXXRTH not enough error checking here */ - cp = fgets(buf, sizeof buf, fp); - if (cp != NULL) - lineno++; - if (cp == NULL || - !sscanf((char *)cp, "from %u to %u", - &old_serial, &new_serial)) { - ns_error(ns_log_update, - "incr_serial problem with %s", - logname); - } else { - serial = get_serial(zp); - if (serial != old_serial) { - ns_error(ns_log_update, - "serial number mismatch (log=%u, zone=%u) in %s", old_serial, - serial, logname); - } else { - set_serial(zp, new_serial); - /* - * The zone has changed; make sure - * a dump is scheduled. - */ - (void)schedule_dump(zp); - sched_zone_maint(zp); - ns_info(ns_log_update, - "set serial to %u (log file %s)", - new_serial, logname); - } - } - prev_pktdone = 1; - cont = 1; - } else if (!strcasecmp(buf, "[END_DELTA]")) { - prev_pktdone = 1; - cont = 1; - } - if (prev_pktdone) { - if (!EMPTY(curupd)) { - n = process_updates(&curupd, &rcode, - empty_from); - if (n > 0) - ns_info(ns_log_update, - "successfully merged update id %d from log file %s", - id, logname); - else { - ns_error(ns_log_update, - "error merging update id %d from log file %s", - id, logname); - return(-1); - } - free_rrecp(&curupd, rcode, empty_from); - } - prev_pktdone = 0; - if (feof(fp)) - break; - } - if (cont) { - cont = 0; - continue; - } - if (!inside_next) - continue; - /* - * inside the same update packet, - * continue accumulating records. - */ - section = -1; - n = strlen(buf); - if (buf[n-1] == ':') - buf[--n] = '\0'; - for (mp = m_section; mp < m_section+M_SECTION_CNT; mp++) - if (!strcasecmp(buf, mp->token)) { - section = mp->val; - break; - } - ttl = 0; - type = -1; - class = zp->z_class; - n = 0; - data[0] = '\0'; - switch (section) { - case S_ZONE: - cp = fgets(buf, sizeof buf, fp); - if (!cp) - *buf = '\0'; - n = sscanf(cp, "origin %s class %s serial %ul", - origin, sclass, &serial); - if (n != 3 || ns_samename(origin, zp->z_origin) != 1) - err++; - if (cp) - lineno++; - if (!err && serial != zp->z_serial) { - ns_error(ns_log_update, - "serial number mismatch in update id %d (log=%u, zone=%u) in %s", - id, serial, zp->z_serial, - logname); - inside_next = 0; - err++; - } - if (!err && inside_next) { - int success; - - dname = origin; - type = T_SOA; - class = sym_ston(__p_class_syms, sclass, - &success); - if (!success) { - err++; - break; - } - matches = findzone(dname, class, 0, - zonelist, MAXDNAME); - if (matches) - zonenum = zonelist[0]; - else - err++; - } - break; - case S_PREREQ: - case S_UPDATE: - /* Operation code. */ - if (!getword(buf, sizeof buf, fp, 0)) { - err++; - break; - } - opcode = -1; - if (buf[0] == '{') { - n = strlen(buf); - for (i = 0; (u_int32_t)i < n; i++) - buf[i] = buf[i+1]; - if (buf[n-2] == '}') - buf[n-2] = '\0'; - } - for (mp = m_opcode; mp < m_opcode+M_OPCODE_CNT; mp++) - if (!strcasecmp(buf, mp->token)) { - opcode = mp->val; - break; - } - if (opcode == -1) { - err++; - break; - } - /* Owner's domain name. */ - if (!getword((char *)dnbuf, sizeof dnbuf, fp, 0)) { - err++; - break; - } - n = strlen((char *)dnbuf) - 1; - if (dnbuf[n] == '.') - dnbuf[n] = '\0'; - dname = dnbuf; - ttl = 0; - type = -1; - class = zp->z_class; - n = 0; - data[0] = '\0'; - (void) getword(buf, sizeof buf, fp, 1); - if (isdigit(buf[0])) { /* ttl */ - if (ns_parse_ttl(buf, &l) < 0) { - err++; - break; - } - ttl = l; - (void) getword(buf, sizeof buf, fp, 1); - } - - /* possibly class */ - if (buf[0] != '\0') { - int success; - int maybe_class; - - maybe_class = sym_ston(__p_class_syms, - buf, - &success); - if (success) { - class = maybe_class; - (void) getword(buf, - sizeof buf, - fp, 1); - } - } - /* possibly type */ - if (buf[0] != '\0') { - int success; - int maybe_type; - - maybe_type = sym_ston(__p_type_syms, - buf, - &success); - - if (success) { - type = maybe_type; - (void) getword(buf, - sizeof buf, - fp, 1); - } - } - if (buf[0] != '\0') /* possibly rdata */ - /* - * Convert the ascii data 'buf' to the proper - * format based on the type and pack into - * 'data'. - * - * XXX - same as in db_load(), - * consolidation needed - */ - switch (type) { - case T_A: - if (!inet_aton(buf, &ina)) { - err++; - break; - } - n = ntohl(ina.s_addr); - cp = data; - PUTLONG(n, cp); - n = INT32SZ; - break; - case T_HINFO: - case T_ISDN: - n = strlen(buf); - data[0] = n; - memcpy(data+1, buf, n); - n++; - if (!getword(buf, sizeof buf, - fp, 0)) { - i = 0; - } else { - endline(fp); - i = strlen(buf); - } - data[n] = i; - memcpy(data+n+1, buf, i); - break; - case T_SOA: - case T_MINFO: - case T_RP: - (void) strcpy(data, buf); - cp = data + strlen(data) -1; - *(cp++) = 0; /* ditch dot */ - if (!getword((char *)cp, - sizeof data - (cp - data), - fp, 1)) { - err++; - break; - } - cp += strlen((char *)cp) -1; - *(cp++) = 0; /* ditch dot */ - if (type != T_SOA) { - n = cp - data; - break; - } - else - n = cp - data; - if (class != zp->z_class || - ns_samename(dname, zp->z_origin) != 1) { - err++; - break; - } - c = getnonblank(fp, logname); - if (c == '(') { - multiline = 1; - } else { - multiline = 0; - ungetc(c, fp); - } - n = getnum(fp, logname, GETNUM_SERIAL); - if (getnum_error) { - err++; - break; - } - PUTLONG(n, cp); - for (i = 0; i < 4; i++) { - if (getttl(fp, logname, lineno, - &n, &multiline) <= 0) - { - err++; - break; - } - PUTLONG(n, cp); - } - if (multiline && - (getnonblank(fp, logname) - != ')')) { - err++; - break; - } - n = cp - data; - endline(fp); - break; - case T_WKS: - if (!inet_aton(buf, &ina)) { - err++; - break; - } - n = ntohl(ina.s_addr); - cp = data; - PUTLONG(n, cp); - *cp = (char)getprotocol(fp, - logname - ); - n = INT32SZ + sizeof(char); - n = getservices((int)n, data, - fp, logname); - break; - case T_NS: - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_PTR: - (void) strcpy(data, buf); - if (makename(data, origin, - sizeof(data)) == -1) { - err++; - break; - } - n = strlen(data) + 1; - break; - case T_MX: - case T_AFSDB: - case T_RT: - n = 0; - cp = buf; - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - /* catch bad values */ - cp = data; - PUTSHORT((u_int16_t)n, cp); - if (!getword(buf, sizeof(buf), - fp, 1)) { - err++; - break; - } - (void) strcpy((char *)cp, buf); - if (makename((char *)cp, origin, - sizeof(data) - (cp-data)) - == -1) { - err++; - break; - } - /* advance pointer to end of data */ - cp += strlen((char *)cp) +1; - /* now save length */ - n = (cp - data); - break; - case T_PX: - n = 0; - data[0] = '\0'; - cp = buf; - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - cp = data; - PUTSHORT((u_int16_t)n, cp); - for (i = 0; i < 2; i++) { - if (!getword(buf, - sizeof(buf), - fp, 0)) { - err++; - break; - } - (void) strcpy((char *)cp, - buf); - cp += strlen((char *)cp) + 1; - } - n = cp - data; - break; - case T_TXT: - case T_X25: - i = strlen(buf); - cp = data; - datasize = sizeof data; - cp1 = buf; - while (i > MAXCHARSTRING) { - if (datasize <= MAXCHARSTRING){ - ns_error(ns_log_update, - "record too big"); - fclose(fp); - return (-1); - } - datasize -= MAXCHARSTRING; - *cp++ = (char)MAXCHARSTRING; - memcpy(cp, cp1, MAXCHARSTRING); - cp += MAXCHARSTRING; - cp1 += MAXCHARSTRING; - i -= MAXCHARSTRING; - } - if (datasize < i + 1) { - ns_error(ns_log_update, - "record too big"); - fclose(fp); - return (-1); - } - *cp++ = i; - memcpy(cp, cp1, i); - cp += i; - n = cp - data; - endline(fp); - /* XXXVIX: segmented texts 4.9.5 */ - break; - case T_NSAP: - n = inet_nsap_addr(buf, - (u_char *)data, - sizeof data); - endline(fp); - break; - case T_LOC: - cp = buf + (n = strlen(buf)); - *cp = ' '; - cp++; - while ((i = getc(fp), *cp = i, - i != EOF) - && *cp != '\n' - && (n < MAXDATA)) { - cp++; - n++; - } - if (*cp == '\n') - ungetc(*cp, fp); - *cp = '\0'; - n = loc_aton(buf, (u_char *)data); - if (n == 0) { - err++; - break; - } - endline(fp); - break; - case ns_t_sig: - case ns_t_key: - case ns_t_nxt: - case ns_t_cert: - { - char * errmsg = NULL; - int s; - - s = parse_sec_rdata(buf, sizeof(buf), - 1, - (u_char *)data, - sizeof(data), - fp, zp, dnbuf, - ttl, type, - domain_ctx, - primary_trans, - &errmsg); - if (s < 0) { - err++; - break; - } - break; - } - default: - err++; - } - if (section == S_PREREQ) { - ttl = 0; - if (opcode == NXDOMAIN) { - class = C_NONE; - type = T_ANY; - n = 0; - } else if (opcode == YXDOMAIN) { - class = C_ANY; - type = T_ANY; - n = 0; - } else if (opcode == NXRRSET) { - class = C_NONE; - n = 0; - } else if (opcode == YXRRSET) { - if (n == 0) - class = C_ANY; - } - } else { /* section == S_UPDATE */ - if (opcode == DELETE) { - ttl = 0; - if (n == 0) { - class = C_ANY; - if (type == -1) - type = T_ANY; - /* WTF? C_NONE or C_ANY _must_ be the case if - * we really are to delete this. If - * C_NONE is used, according to process_updates(), - * the class is gotten from the zone's class. - * This still isn't perfect, but it will at least - * work. - * - * Question: What is so special about the class - * of the update while we are deleting?? - */ - } else /* if (zp->z_xferpid != XFER_ISIXFR) */ { - class = C_NONE; - } - } - } - break; - case S_ADDT: - default: - ns_debug(ns_log_update, 1, - "cannot interpret section: %d", section); - inside_next = 0; - err++; - } - if (err) { - inside_next = 0; - ns_debug(ns_log_update, 1, - "merge of update id %d failed due to error at line %d", - id, lineno); - free_rrecp(&curupd, FORMERR, empty_from); - continue; - } - rrecp = res_mkupdrec(section, dname, class, type, ttl); - if (section != S_ZONE) { - dp = savedata(class, type, ttl, (u_char *)data, n); - dp->d_zone = zonenum; - dp->d_cred = DB_C_ZONE; - dp->d_clev = nlabels(zp->z_origin); - dp->d_secure = DB_S_INSECURE; /* should be UNCHECKED */ - rrecp->r_dp = dp; - } else { - rrecp->r_zone = zonenum; - } - APPEND(curupd, rrecp, r_link); - } /* for (;;) */ - - fclose(fp); - return (0); -} - - -/* - * Create a disk database to back up zones - */ -int -zonedump(struct zoneinfo *zp, int mode) { - FILE *fp; - const char *fname; - struct hashbuf *htp; - char *op; - struct stat st; - char tmp_name[MAXPATHLEN]; - int escaped; - char c; - - /* - * We must check to see if Z_NEED_SOAUPDATE is set, and if so - * we must do it. This won't be the case normally - * (when called from ns_maint()), but it is possible if we're - * exiting named. - */ - - if (zp->z_flags & Z_NEED_SOAUPDATE) { - u_int32_t serial, old_serial; - - old_serial = get_serial(zp); - serial = old_serial + 1; - if (serial == 0) - serial = 1; - set_serial(zp, serial); - } - - /* Only dump zone if there is a cache specified */ - if (zp->z_source && *(zp->z_source)) { - ns_debug(ns_log_update, 1, "zonedump(%s)", zp->z_source); - - if (strlen(zp->z_source)+strlen(DumpSuffix) >= MAXPATHLEN) { - ns_error(ns_log_update, - "filename %s too long in zonedump", - zp->z_source); - /* - * This problem won't ever get better, so we - * clear the "need dump" flag. - */ - zp->z_flags &= ~Z_NEED_DUMP; - return (-1); - } - (void)sprintf(tmp_name, "%s%s", zp->z_source, DumpSuffix); - if ((fp = write_open(tmp_name)) == NULL) { - ns_error(ns_log_update, "fopen() of %s failed: %s", - tmp_name, strerror(errno)); - return (-1); - } - fprintf(fp, "%s", DumpSignature); - op = zp->z_origin; - escaped = 0; - while (*op && (((c = *op++) != '.') || escaped)) - escaped = (c == '\\') && !escaped; - gettime(&tt); - htp = hashtab; - if (nlookup(zp->z_origin, &htp, &fname, 0) != NULL) { - if (db_dump(htp, fp, zp-zones, op) != OK) { - ns_error(ns_log_update, - "error dumping zone file %s", - zp->z_source); - (void)fclose(fp); - return (-1); - } - } - if (fflush(fp) == EOF) { - ns_error(ns_log_update, "fflush() of %s failed: %s", - tmp_name, strerror(errno)); - fclose(fp); - return (-1); - } - if (fsync(fileno(fp)) < 0) { - ns_error(ns_log_update, "fsync() of %s failed: %s", - tmp_name, strerror(errno)); - fclose(fp); - return (-1); - } - if (fclose(fp) == EOF) { - ns_error(ns_log_update, "fclose() of %s failed: %s", - tmp_name, strerror(errno)); - return (-1); - } - /* - * Try to make read only, so people will be less likely to - * edit dynamic domains. - */ - if (stat(tmp_name, &st) < 0) { - ns_error(ns_log_update, - "stat(%s) failed, pressing on: %s", - tmp_name, strerror(errno)); - } else { - zp->z_ftime = st.st_mtime; - st.st_mode &= ~WRITEABLE_MASK; - if (chmod(tmp_name, st.st_mode) < 0) - ns_error(ns_log_update, - "chmod(%s,%o) failed, pressing on: %s", - tmp_name, st.st_mode, - strerror(errno)); - } - - if (mode == ISIXFR) { - if (movefile(tmp_name, zp->z_ixfr_tmp) < 0) { - ns_error(ns_log_update, "movefile(%s,%s) failed: %s :2", - tmp_name, zp->z_ixfr_tmp, strerror(errno)); - return (-1); - } - if (chmod(zp->z_source, 0644) < 0) - ns_error(ns_log_update, - "chmod(%s,%o) failed, pressing on: %s", - zp->z_source, st.st_mode, - strerror(errno)); - if (movefile(zp->z_ixfr_tmp, zp->z_source) < 0) { - ns_error(ns_log_update, "movefile(%s,%s) failed: %s :3", - zp->z_ixfr_tmp, zp->z_source, - strerror(errno)); - return (-1); - } - st.st_mode &= ~WRITEABLE_MASK; - if (chmod(zp->z_source, st.st_mode) < 0) - ns_error(ns_log_update, - "chmod(%s,%o) failed, pressing on: %s", - zp->z_source, st.st_mode, - strerror(errno)); - } else if (mode == ISNOTIXFR) { - if (movefile(tmp_name, zp->z_updatelog) < 0) { - ns_error(ns_log_update, "movefile(%s,%s) failed: %s :4", - tmp_name, zp->z_updatelog, strerror(errno)); - return (-1); - } - if (movefile(zp->z_updatelog, zp->z_source) < 0) { - ns_error(ns_log_update, "movefile(%s,%s) failed: %s:5", - zp->z_updatelog, zp->z_source, - strerror(errno)); - return (-1); - } - } else { - if (movefile(tmp_name, zp->z_source) < 0) { - ns_error(ns_log_update, "movefile(%s,%s) failed: % s :6", tmp_name, zp->z_source, strerror(errno)); - return (-1); - } - } - } else - ns_debug(ns_log_update, 1, "zonedump: no zone to dump"); - - zp->z_flags &= ~Z_NEED_DUMP; - zp->z_dumptime = 0; - return (0); -} - -struct databuf * -findzonesoa(struct zoneinfo *zp) { - struct hashbuf *htp; - struct namebuf *np; - struct databuf *dp; - const char *fname; - - htp = hashtab; - np = nlookup(zp->z_origin, &htp, &fname, 0); - if (np == NULL || fname != zp->z_origin) - return (NULL); - foreach_rr(dp, np, T_SOA, zp->z_class, zp - zones) - return (dp); - return (NULL); -} - -u_char * -findsoaserial(u_char *data) { - char *cp = (char *)data; - - cp += strlen(cp) + 1; /* Nameserver. */ - cp += strlen(cp) + 1; /* Mailbox. */ - return ((u_char *)cp); -} - -u_int32_t -get_serial_unchecked(struct zoneinfo *zp) { - struct databuf *dp; - u_char *cp; - u_int32_t ret; - - dp = findzonesoa(zp); - if (!dp) - ns_panic(ns_log_update, 1, - "get_serial_unchecked(%s): can't locate zone SOA", - zp->z_origin); - cp = findsoaserial(dp->d_data); - GETLONG(ret, cp); - return (ret); -} - -u_int32_t -get_serial(struct zoneinfo *zp) { - u_int32_t ret; - - ret = get_serial_unchecked(zp); - if (ret != zp->z_serial) - ns_panic(ns_log_update, 1, - "get_serial(%s): db and zone serial numbers differ", - zp->z_origin); - return (ret); -} - -void -set_serial(struct zoneinfo *zp, u_int32_t serial) { - struct databuf *dp; - u_char *cp; - - dp = findzonesoa(zp); - if (!dp) - ns_panic(ns_log_update, 1, - "set_serial(%s): can't locate zone SOA", - zp->z_origin); - cp = findsoaserial(dp->d_data); - PUTLONG(serial, cp); - zp->z_serial = serial; - zp->z_flags &= ~Z_NEED_SOAUPDATE; - zp->z_soaincrtime = 0; - zp->z_updatecnt = 0; -#ifdef BIND_NOTIFY - if (!loading) - ns_notify(zp->z_origin, zp->z_class, ns_t_soa); -#endif - /* - * Note: caller is responsible for scheduling a dump. - */ -} - -/* - * Increment serial number in zoneinfo structure and hash table SOA databuf - */ - -int -incr_serial(struct zoneinfo *zp) { - u_int32_t serial, old_serial; - FILE *fp, *ifp; - time_t t; - struct databuf *dp, *olddp; - unsigned char *cp; - - old_serial = get_serial(zp); - serial = old_serial + 1; - if (serial == 0) - serial = 1; - set_serial(zp, serial); - - (void) gettime(&tt); - t = (time_t)tt.tv_sec; - fp = open_transaction_log(zp); - if (fp == NULL) - return (-1); - fprintf(fp, "[INCR_SERIAL] from %u to %u %s\n", - old_serial, serial, checked_ctime(&t)); - if (close_transaction_log(zp, fp)<0) - return (-1); - if (zp->z_maintain_ixfr_base) { - ifp = open_ixfr_log(zp); - if (ifp == NULL) - return (-1); - dp = findzonesoa(zp); - if (dp) { - olddp = memget(DATASIZE(dp->d_size)); - if (olddp != NULL) { - memcpy(olddp, dp, DATASIZE(dp->d_size)); - cp = findsoaserial(olddp->d_data); - PUTLONG(old_serial, cp); - fprintf(ifp, "update: {delete} %s. %u %s %s ", - zp->z_origin, dp->d_ttl, - p_class(dp->d_class), - p_type(dp->d_type)); - (void) rdata_dump(olddp, ifp); - fprintf(ifp, "\n"); - memput(olddp, DATASIZE(dp->d_size)); - } - fprintf(ifp, "update: {add} %s. %u %s %s ", - zp->z_origin, dp->d_ttl, - p_class(dp->d_class), p_type(dp->d_type)); - (void) rdata_dump(dp, ifp); - fprintf(ifp, "\n"); - } - fprintf(ifp, "[END_DELTA]\n"); - if (close_ixfr_log(zp, ifp) < 0) - return (-1); - } - - /* - * This shouldn't happen, but we check to be sure. - */ - if (!(zp->z_flags & Z_NEED_DUMP)) { - ns_warning(ns_log_update, - "incr_serial: Z_NEED_DUMP not set for zone '%s'", - zp->z_origin); - (void)schedule_dump(zp); - } - - sched_zone_maint(zp); - - return (0); -} - -void -dynamic_about_to_exit(void) { - struct zoneinfo *zp; - - ns_debug(ns_log_update, 1, - "shutting down; dumping zones that need it"); - for (zp = zones; zp < &zones[nzones]; zp++) { - if ((zp->z_flags & Z_DYNAMIC) && - ((zp->z_flags & Z_NEED_SOAUPDATE) || - (zp->z_flags & Z_NEED_DUMP))) - (void)zonedump(zp, ISNOTIXFR); - } -} diff --git a/contrib/bind/bin/named/ns_xfr.c b/contrib/bind/bin/named/ns_xfr.c deleted file mode 100644 index f5cbdfa0abd09..0000000000000 --- a/contrib/bind/bin/named/ns_xfr.c +++ /dev/null @@ -1,860 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ns_xfr.c,v 8.62 2000/04/24 05:20:51 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <fcntl.h> -#include <resolv.h> -#include <res_update.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <time.h> -#include <unistd.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> -#include <isc/memcluster.h> - -#include <isc/dst.h> - -#include "port_after.h" - -#include "named.h" - -static struct qs_x_lev *sx_freelev(struct qs_x_lev *lev); - -static int sx_flush(struct qstream *qsp), - sx_addrr(struct qstream *qsp, - const char *dname, - struct databuf *dp), - sx_nsrrs(struct qstream *qsp), - sx_allrrs(struct qstream *qsp), - sx_pushlev(struct qstream *qsp, struct namebuf *np); -static struct databuf *db_next(struct databuf *dp); - -/* - * void - * ns_xfr(qsp, znp, zone, class, type, opcode, id, serial_ixfr, in_tsig) - * Initiate a concurrent (event driven) outgoing zone transfer. - */ -void -ns_xfr(struct qstream *qsp, struct namebuf *znp, - int zone, int class, int type, - int opcode, int id, u_int32_t serial_ixfr, struct tsig_record *in_tsig) -{ - server_info si; -#ifdef SO_SNDBUF - static const int sndbuf = XFER_BUFSIZE * 2; -#endif -#ifdef SO_SNDLOWAT - static const int sndlowat = XFER_BUFSIZE; -#endif - ns_deltalist *changes; - - switch (type) { - case ns_t_axfr: /*FALLTHROUGH*/ - case ns_t_ixfr: -#ifdef BIND_ZXFR - case ns_t_zxfr: -#endif - ns_info(ns_log_xfer_out, - "zone transfer (%s) of \"%s\" (%s) to %s", - p_type(type), zones[zone].z_origin, p_class(class), - sin_ntoa(qsp->s_from)); - break; - default: - ns_warning(ns_log_xfer_out, - "unsupported XFR (type %s) of \"%s\" (%s) to %s", - p_type(type), zones[zone].z_origin, p_class(class), - sin_ntoa(qsp->s_from)); - goto abort; - } - -#ifdef SO_SNDBUF - /* - * The default seems to be 4K, and we'd like it to have enough room - * to parallelize sending the pushed data with accumulating more - * write() data from us. - */ - (void) setsockopt(qsp->s_rfd, SOL_SOCKET, SO_SNDBUF, - (char *)&sndbuf, sizeof sndbuf); -#endif -#ifdef SO_SNDLOWAT - /* - * We don't want select() to show writability 'til we can write - * an XFER_BUFSIZE block of data. - */ - (void) setsockopt(qsp->s_rfd, SOL_SOCKET, SO_SNDLOWAT, - (char *)&sndlowat, sizeof sndlowat); -#endif - if (sq_openw(qsp, 64*1024) == -1) - goto abort; - memset(&qsp->xfr, 0, sizeof qsp->xfr); - qsp->xfr.top.axfr = znp; - qsp->xfr.zone = zone; - qsp->xfr.class = class; - if (qsp->flags & STREAM_AXFRIXFR) - type = ns_t_axfr; - qsp->xfr.type = type; - qsp->xfr.id = id; - qsp->xfr.opcode = opcode; - qsp->xfr.msg = memget(XFER_BUFSIZE); - if (!qsp->xfr.msg) - goto abort; - qsp->xfr.eom = qsp->xfr.msg + XFER_BUFSIZE; - qsp->xfr.cp = NULL; - qsp->xfr.state = s_x_firstsoa; - zones[zone].z_numxfrs++; - qsp->flags |= STREAM_AXFR; - -#ifdef BIND_ZXFR - if (type == ns_t_zxfr) { - enum { rd = 0, wr = 1 }; - int z[2]; - pid_t p; - - if (pipe(z) < 0) { - ns_error(ns_log_xfer_out, "pipe: %s", strerror(errno)); - goto abort; - } - p = vfork(); - if (p < 0) { - ns_error(ns_log_xfer_out, "vfork: %s", strerror(errno)); - goto abort; - } - if (p == 0) { - /* Child. */ - dup2(z[rd], STDIN_FILENO); - dup2(qsp->s_rfd, STDOUT_FILENO); - execlp("gzip", "gzip", NULL); - ns_error(ns_log_xfer_out, "execlp: %s", strerror(errno)); - _exit(1); - } - ns_info(ns_log_xfer_out, "zxfr gzip pid %lu", p); - /* Parent. */ - dup2(z[wr], qsp->s_rfd); - close(z[wr]); - close(z[rd]); - - /* When a ZXFR completes, there can be no more requests. */ - qsp->flags |= STREAM_DONE_CLOSE; - } -#endif - - si = find_server(qsp->s_from.sin_addr); - if (si != NULL && si->transfer_format != axfr_use_default) - qsp->xfr.transfer_format = si->transfer_format; - else - qsp->xfr.transfer_format = server_options->transfer_format; - if (in_tsig == NULL) - qsp->xfr.tsig_state = NULL; - else { - qsp->xfr.tsig_state = memget(sizeof(ns_tcp_tsig_state)); - ns_sign_tcp_init(in_tsig->key, in_tsig->sig, in_tsig->siglen, - qsp->xfr.tsig_state); - qsp->xfr.tsig_skip = 0; - } - - if (type == ns_t_ixfr) { - changes = ixfr_get_change_list(&zones[zone], serial_ixfr, - zones[zone].z_serial); - ixfr_log_maint(&zones[zone], 1); - if (changes != NULL) { - qsp->xfr.serial = serial_ixfr; - qsp->xfr.top.ixfr = changes; - } - else { - qsp->xfr.top.ixfr = NULL; - goto abort; - } - } else { - if (sx_pushlev(qsp, znp) < 0) { - abort: - (void) shutdown(qsp->s_rfd, 2); - sq_remove(qsp); - return; - } - } - if (type != ns_t_ixfr) { - ns_debug(ns_log_default, 3, "sq_writeh sx_sendsoa (%s)", - zones[zone].z_origin); - (void) sq_writeh(qsp, sx_sendsoa); - } else { - ns_debug(ns_log_default, 3, "sq_writeh sx_send_ixfr (%s)", - zones[zone].z_origin); - (void) sq_writeh(qsp, sx_send_ixfr); - } -} - -/* - * void - * ns_stopxfrs(zp) - * Stop (abort, reset) all transfers of the zone specified by 'zp'. - */ -void -ns_stopxfrs(struct zoneinfo *zp) { - struct qstream *this, *next; - u_int zone = (u_int)(zp - zones); - - ns_debug(ns_log_default, 3, "ns_stopxfrs (%s)", zp->z_origin); - - for (this = streamq; this; this = next) { - next = this->s_next; - if (this->xfr.zone == zone) { - (void) shutdown(this->s_rfd, 2); - sq_remove(this); - } - } - INSIST(zp->z_numxfrs == 0); -} - -/* - * void - * ns_freexfr(qsp) - * Free all xfr-related dynamic data associated with qsp. - */ -void -ns_freexfr(struct qstream *qsp) { - ns_delta *dp; - ns_updrec *rp; - - if (qsp->xfr.msg != NULL) { - memput(qsp->xfr.msg, XFER_BUFSIZE); - qsp->xfr.msg = NULL; - } - if (qsp->xfr.type == ns_t_ixfr && qsp->xfr.top.ixfr != NULL) { - while ((dp = HEAD(*qsp->xfr.top.ixfr)) != NULL) { - UNLINK(*qsp->xfr.top.ixfr, dp, d_link); - while ((rp = HEAD(dp->d_changes)) != NULL) { - UNLINK(dp->d_changes, rp, r_link); - if (rp->r_dp != NULL) - db_freedata(rp->r_dp); - rp->r_dp = NULL; - res_freeupdrec(rp); - } - memput(dp, sizeof *dp); - } - memput(qsp->xfr.top.ixfr, sizeof *qsp->xfr.top.ixfr); - qsp->xfr.top.ixfr = NULL; - } - while (qsp->xfr.lev) - qsp->xfr.lev = sx_freelev(qsp->xfr.lev); - zones[qsp->xfr.zone].z_numxfrs--; - qsp->flags &= ~(STREAM_AXFR | STREAM_AXFRIXFR); -} - -/* - * u_char * - * sx_newmsg(msg) - * init the header of a message, reset the compression pointers, and - * reset the write pointer to the first byte following the header. - */ -void -sx_newmsg(struct qstream *qsp) { - HEADER *hp = (HEADER *)qsp->xfr.msg; - - memset(hp, 0, HFIXEDSZ); - hp->id = htons(qsp->xfr.id); - hp->opcode = qsp->xfr.opcode; - hp->qr = 1; - hp->rcode = NOERROR; - - qsp->xfr.ptrs[0] = qsp->xfr.msg; - qsp->xfr.ptrs[1] = NULL; - - qsp->xfr.cp = qsp->xfr.msg + HFIXEDSZ; - - qsp->xfr.eom = qsp->xfr.msg + XFER_BUFSIZE; - - if (qsp->xfr.tsig_state != NULL) - qsp->xfr.eom -= TSIG_BUF_SIZE; -} - -/* - * int - * sx_flush(qsp) - * flush the intermediate buffer out to the stream IO system. - * return: - * passed through from sq_write(). - */ -static int -sx_flush(struct qstream *qsp) { - int ret; - -#ifdef DEBUG - if (debug >= 10) - res_pquery(&res, qsp->xfr.msg, qsp->xfr.cp - qsp->xfr.msg, - log_get_stream(packet_channel)); -#endif - if (qsp->xfr.tsig_state != NULL && qsp->xfr.tsig_skip == 0) { - int msglen = qsp->xfr.cp - qsp->xfr.msg; - - ns_sign_tcp(qsp->xfr.msg, &msglen, qsp->xfr.eom - qsp->xfr.msg, - NOERROR, qsp->xfr.tsig_state, - qsp->xfr.state == s_x_done); - - if (qsp->xfr.state == s_x_done) { - memput(qsp->xfr.tsig_state, sizeof(ns_tcp_tsig_state)); - qsp->xfr.tsig_state = NULL; - } - qsp->xfr.cp = qsp->xfr.msg + msglen; - - } - ret = sq_write(qsp, qsp->xfr.msg, qsp->xfr.cp - qsp->xfr.msg); - if (ret >= 0) { - qsp->xfr.cp = NULL; - qsp->xfr.tsig_skip = 0; - } - else - qsp->xfr.tsig_skip = 1; - return (ret); -} - -/* - * int - * sx_addrr(qsp, name, dp) - * add name/dp's RR to the current assembly message. if it won't fit, - * write current message out, renew the message, and then RR *must* fit. - * return: - * -1 = the sx_flush() failed so we could not queue the full message. - * 0 = one way or another, everything is fine. - * side effects: - * on success, the ANCOUNT is incremented and the pointers are advanced. - */ -static int -sx_addrr(struct qstream *qsp, const char *dname, struct databuf *dp) { - HEADER *hp = (HEADER *)qsp->xfr.msg; - u_char **edp = qsp->xfr.ptrs + sizeof qsp->xfr.ptrs / sizeof(u_char*); - int n, type; - - if (qsp->xfr.cp != NULL) { - if (qsp->xfr.transfer_format == axfr_one_answer && - sx_flush(qsp) < 0) - return (-1); - } - if (qsp->xfr.cp == NULL) - sx_newmsg(qsp); - - /* - * Add question to first answer. - */ - if (qsp->xfr.state == s_x_firstsoa && dp->d_type == T_SOA) { - n = dn_comp(dname, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, - qsp->xfr.ptrs, edp); - if (n > 0 && (qsp->xfr.cp + n + INT16SZ * 2) <= qsp->xfr.eom) { - qsp->xfr.cp += n; - if (qsp->xfr.type == ns_t_zxfr) - type = ns_t_axfr; - else if ((qsp->flags & STREAM_AXFRIXFR) != 0) - type = ns_t_ixfr; - else - type = qsp->xfr.type; - PUTSHORT((u_int16_t) type, qsp->xfr.cp); - PUTSHORT((u_int16_t) qsp->xfr.class, qsp->xfr.cp); - hp->qdcount = htons(ntohs(hp->qdcount) + 1); - } - } - - n = make_rr(dname, dp, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, - 0, qsp->xfr.ptrs, edp, 0); - if (n < 0) { - if (sx_flush(qsp) < 0) - return (-1); - if (qsp->xfr.cp == NULL) - sx_newmsg(qsp); - n = make_rr(dname, dp, qsp->xfr.cp, qsp->xfr.eom - qsp->xfr.cp, - 0, qsp->xfr.ptrs, edp, 0); - INSIST(n >= 0); - } - hp->ancount = htons(ntohs(hp->ancount) + 1); - qsp->xfr.cp += n; - return (0); -} - -/* - * int - * sx_soarr(qsp) - * add the SOA RR's at the current level's top np to the assembly message. - * return: - * 0 = success - * -1 = write buffer full, cannot continue at this time - * side effects: - * if progress was made, header and pointers will be advanced. - */ -int -sx_soarr(struct qstream *qsp) { - struct databuf *dp; - int added_soa = 0; - - foreach_rr(dp, qsp->xfr.top.axfr, T_SOA, qsp->xfr.class, - qsp->xfr.zone) { - if (sx_addrr(qsp, zones[qsp->xfr.zone].z_origin, dp) < 0) { - /* RR wouldn't fit. Bail out. */ - return (-1); - } - added_soa = 1; - break; - } - if (added_soa == 0) - ns_panic(ns_log_xfer_out, 1, "no SOA at zone top"); - if (qsp->xfr.state == s_x_firstsoa) { - foreach_rr(dp, qsp->xfr.top.axfr, T_SIG, qsp->xfr.class, - qsp->xfr.zone) - { - if (SIG_COVERS(dp) != T_SOA) - continue; - if (sx_addrr(qsp, zones[qsp->xfr.zone].z_origin, dp) < - 0) - { - /* RR wouldn't fit. Bail out. */ - return (-1); - } - } - } - return (0); -} - -/* - * int - * sx_nsrrs(qsp) - * add the NS RR's at the current level's current np to the assembly msg. - * This function also adds the SIG(NS), KEY, SIG(KEY), NXT, SIG(NXT), - * since these records are also part of the delegation (see DNSSEC). - * return: - * >1 = number of NS RRs added, note that there may be more - * 0 = success, there are no more NS RRs at this level - * -1 = write buffer full, cannot continue at this time - * side effects: - * if progress was made, header and pointers will be advanced. - * note: - * this is meant for AXFR, which includes glue as part of the answer - * sections. this is different from and incompatible with the additional - * data of a referral response. - */ -static int -sx_nsrrs(struct qstream *qsp) { - struct databuf *dp, *tdp, *gdp; - struct namebuf *gnp, *tnp, *top; - struct hashbuf *htp; - const char *fname; - int class; - - class = qsp->xfr.class; - top = qsp->xfr.top.axfr; - for ((void)NULL; - (dp = qsp->xfr.lev->dp) != NULL; - qsp->xfr.lev->dp = db_next(dp)) { - if (dp->d_class != class && class != C_ANY) - continue; - if (dp->d_rcode) - continue; - /* - * It might not be in the same zone, if we are authoritative - * for both parent and child, but it does have to be a zone. - * - * XXX: this is sort of a bug, since it means we merge the - * @ NS RRset into our parent's zone. But that is what - * db_load() does, so for now we have no choice. - */ - if (dp->d_zone == DB_Z_CACHE) - continue; - - if (dp->d_type != T_NS && dp->d_type != T_KEY && - dp->d_type != T_NXT && dp->d_type != T_SIG) - continue; - if (dp->d_type == T_SIG && ((SIG_COVERS(dp) != T_NS) && - (SIG_COVERS(dp) != T_KEY) && (SIG_COVERS(dp) != T_NXT))) - continue; - if (!(qsp->xfr.lev->flags & SXL_GLUING)) { - if (sx_addrr(qsp, qsp->xfr.lev->dname, dp) < 0) { - /* RR wouldn't fit. Bail out. */ - return (-1); - } - if (dp->d_type != T_NS) /* no glue processing */ - continue; - /* Remember we have found a zone cut */ - if (qsp->xfr.top.axfr != qsp->xfr.lev->np) - qsp->xfr.lev->flags |= SXL_ZONECUT; - } - - /* - * Glue the sub domains together by sending the address - * records for the sub domain name servers along if necessary. - * Glue is necessary if the server is in any zone delegated - * from the current (top) zone. Such a delegated zone might - * or might not be that referred to by the NS record now - * being handled. - */ - htp = hashtab; - gnp = nlookup((char *)dp->d_data, &htp, &fname, 0); - if (gnp == NULL || fname != (char *)dp->d_data) - continue; - for (tnp = gnp; - tnp != NULL && tnp != top; - tnp = tnp->n_parent) - (void)NULL; - if (tnp == NULL && NAME(*top)[0] != '\0') - continue; /* name server is not below top domain */ - for (tnp = gnp; - tnp != NULL && tnp != top; - tnp = tnp->n_parent) { - foreach_rr(tdp, tnp, T_NS, class, DB_Z_CACHE) - break; - /* If we found a zone cut, we're outta here. */ - if (tdp != NULL) - break; - } - /* If name server is not in a delegated zone, skip it. */ - if (tnp == top || (tnp == NULL && NAME(*top)[0] == '\0')) - continue; - /* Now we know glue records are needed. Send them. */ - qsp->xfr.lev->flags |= SXL_GLUING; - foreach_rr(gdp, gnp, T_A, class, DB_Z_CACHE) - if (sx_addrr(qsp, fname, gdp) < 0) { - /* - * Rats. We already sent the NS RR, too. - * Note that SXL_GLUING is being left on. - */ - return (-1); - } - /* for IPv6 glue AAAA record transfer */ - /* patched by yasuhiro@nic.ad.jp, 1999/5/23 */ - foreach_rr(gdp, gnp, T_AAAA, class, DB_Z_CACHE) - if (sx_addrr(qsp, fname, gdp) < 0) { - /* - * Rats. We already sent the NS RR, too. - * Note that SXL_GLUING is being left on. - */ - return (-1); - } - foreach_rr(gdp, gnp, ns_t_a6, class, DB_Z_CACHE) - if (sx_addrr(qsp, fname, gdp) < 0) { - /* - * Rats. We already sent the NS RR, too. - * Note that SXL_GLUING is being left on. - */ - return (-1); - } - qsp->xfr.lev->flags &= ~SXL_GLUING; - } - return (0); -} - -/* - * int - * sx_allrrs(qsp) - * add the non-(SOA,NS) RR's at the current level's current np, - * to the assembly message - * do not add the DNSSEC types KEY and NXT as the delegation check - * wrote these types out. - * return: - * >0 = number of RR's added, note that there may be more - * 0 = success, there are no more RRs at this level - * -1 = write buffer full, cannot continue at this time - * side effects: - * if progress was made, header and pointers will be advanced. - * note: - * this is meant for AXFR, which includes glue as part of the answer - * sections. this is different from and incompatible with the additional - * data of a referral response. - */ -static int -sx_allrrs(struct qstream *qsp) { - struct databuf *dp; - struct namebuf *top; - int rrcount, class; - u_int zone; - - class = qsp->xfr.class; - top = qsp->xfr.top.axfr; - zone = qsp->xfr.zone; - rrcount = 0; - for ((void)NULL; - (dp = qsp->xfr.lev->dp) != NULL; - qsp->xfr.lev->dp = db_next(dp)) { - if (dp->d_class != class && class != C_ANY) - continue; - if (dp->d_rcode) - continue; - if (dp->d_zone != zone || stale(dp)) - continue; - if (dp->d_type == T_SOA || dp->d_type == T_NS || - dp->d_type == T_NXT || dp->d_type == T_KEY) - continue; - if (dp->d_type == T_SIG && - (SIG_COVERS(dp) == T_SOA || SIG_COVERS(dp) == T_NS || - SIG_COVERS(dp) == T_KEY || SIG_COVERS(dp) == T_NXT)) - continue; - INSIST(!(qsp->xfr.lev->flags & SXL_GLUING)); - - if (sx_addrr(qsp, qsp->xfr.lev->dname, dp) < 0) { - /* RR wouldn't fit. Bail out. */ - return (-1); - } - rrcount++; - } - return (rrcount); -} - -/* - * void - * sx_sendlev(qsp) - * send all the RRs at the current level (really a domain name), and - * do a decomposed recursion to get all subdomains up to and including - * but not exceeding bottom zone cuts. - * side effects: - * advances qsp->xfr pointers. changes qsp->xfr.lev quite often. - * causes messages to be sent to a remote TCP client. changes the - * qsp->xfr.state at the end of the topmost level. changes the - * qsp->xfr.lev->state several times per domain name. - */ -void -sx_sendlev(struct qstream *qsp) { - struct qs_x_lev *lev; - - again: - lev = qsp->xfr.lev; - switch (lev->state) { - case sxl_ns: { - while (lev->dp) { - /* Was the child zone reloaded under us? */ - if ((lev->dp->d_flags & DB_F_ACTIVE) == 0) { - (void) shutdown(qsp->s_rfd, 2); - sq_remove(qsp); - return; - } - /* If we can't pack this one in, come back later. */ - if (sx_nsrrs(qsp) < 0) - return; - } - /* No more DP's for the NS RR pass on this NP. */ - if (lev->flags & SXL_ZONECUT) { - /* Zone cut, so go directly to end of level. */ - break; - } - /* No NS RR's, so it's safe to send other types. */ - lev->state = sxl_all; - lev->dp = lev->np->n_data; - if (lev->dp) - DRCNTINC(lev->dp); - goto again; - } - case sxl_all: { - while (lev->dp) { - /* Was a record updated under us? */ - if ((lev->dp->d_flags & DB_F_ACTIVE) == 0) { - (void) shutdown(qsp->s_rfd, 2); - sq_remove(qsp); - return; - } - /* If we can't pack this one in, come back later. */ - if (sx_allrrs(qsp) < 0) - return; - } - /* No more non-NS DP's for this NP, do subdomains. */ - lev->state = sxl_sub; - goto again; - } - case sxl_sub: { - struct namebuf *np; - - /* Get next in-use hash chain if we're not following one. */ - while (lev->nnp == NULL) { - /* If no, or no more subdomains, end of level. */ - if (lev->npp == NULL || lev->npp == lev->npe) - break; - lev->nnp = *lev->npp++; - } - /* If we encountered the end of the level, we're outta here. */ - if ((np = lev->nnp) == NULL) - break; - /* Next time, we'll do the following NP, or the next chain. */ - lev->nnp = np->n_next; - /* Skip our own NP if it appears as a subdom (as in root). */ - if (np != lev->np) - sx_pushlev(qsp, np); - goto again; - } - default: - abort(); - } - - /* End of level. Pop it off the stack. */ - - if ((qsp->xfr.lev = sx_freelev(lev)) == NULL) { - /* End of topmost level. */ - qsp->xfr.state = s_x_lastsoa; - sq_writeh(qsp, sx_sendsoa); - return; - } - goto again; -} - -/* - * void - * sx_sendsoa(qsp) - * send either the first or last SOA needed for an AXFR. - * side effects: - * changes qsp->xfr.state. adds RR to output buffer. - */ -void -sx_sendsoa(struct qstream *qsp) { - HEADER * hp = (HEADER *) qsp->xfr.msg; - - if (sx_soarr(qsp) == -1) - return; /* No state change, come back here later. */ - - hp->aa = 1; - - switch (qsp->xfr.state) { - case s_x_firstsoa: { - /* Next thing to do is send the zone. */ - qsp->xfr.state = s_x_zone; - sq_writeh(qsp, sx_sendlev); - break; - } - case s_x_lastsoa: { - /* Next thing to do is go back and wait for another query. */ - qsp->xfr.state = s_x_done; - (void)sx_flush(qsp); - sq_writeh(qsp, sq_flushw); - break; - } - default: { - ns_panic(ns_log_xfer_out, 1, - "unexpected state %d in sx_sendsoa", qsp->xfr.state); - } - } -} - -/* int - * sx_pushlev(qsp, np) - * manage the decomposed recursion. set up for a new level (domain). - * returns: - * 0 = success - * -1 = failure (check errno) - */ -static int -sx_pushlev(struct qstream *qsp, struct namebuf *np) { - struct qs_x_lev *new = memget(sizeof *new); - struct hashbuf *htp; - - if (!new) { - errno = ENOMEM; - return (-1); - } - memset(new, 0, sizeof *new); - new->state = sxl_ns; - new->np = np; - new->dp = np->n_data; - if (new->dp) - DRCNTINC(new->dp); - getname(np, new->dname, sizeof new->dname); - /* - * We find the subdomains by looking in the hash table for this - * domain, but the root domain needs special treatment, because - * of the following wart in the database design: - * - * The top level hash table (pointed to by the global `hashtab' - * variable) contains pointers to the namebuf's for the root as - * well as for the top-level domains below the root, in contrast - * to the usual situation where a hash table contains entries - * for domains at the same level. The n_hash member of the - * namebuf for the root domain is NULL instead of pointing to a - * hashbuf for the top-level domains. The n_parent members of - * the namebufs for the top-level domains are NULL instead of - * pointing to the namebuf for the root. - * - * We work around the wart as follows: - * - * If we are not dealing with the root zone then we just set - * htp = np->n_hash, pointing to the hash table for the current - * domain, and we walk through the hash table as usual, - * processing the namebufs for all the subdomains. - * - * If we are dealing with the root zone, then we set - * htp = hashtab, pointing to the global hash table (because - * there is no hash table associated with the root domain's - * namebuf. While we walk this hash table, we take care not to - * recursively process the entry for the root namebuf. - * - * (apb@und nov1990) - */ - htp = ((new->dname[0] == '\0') ? hashtab : np->n_hash); - if (htp) { - new->npp = htp->h_tab; - new->npe = htp->h_tab + htp->h_size; - } else { - new->npp = NULL; - new->npe = NULL; - } - new->nnp = NULL; - new->next = qsp->xfr.lev; - qsp->xfr.lev = new; - return (0); -} - -/* - * qs_x_lev * - * sx_freelev(lev) - * free the memory occupied by a level descriptor - * return: - * pointer to "next" level descriptor - */ -static struct qs_x_lev * -sx_freelev(struct qs_x_lev *lev) { - struct qs_x_lev *next = lev->next; - - if (lev->dp) { - DRCNTDEC(lev->dp); - if (lev->dp->d_rcnt == 0) - db_freedata(lev->dp); - } - memput(lev, sizeof *lev); - return (next); -} - -static struct databuf * -db_next(struct databuf *dp) { - struct databuf *next = dp->d_next; - - DRCNTDEC(dp); - if (dp->d_rcnt == 0) - db_freedata(dp); - - if (next) - DRCNTINC(next); - - return (next); -} - diff --git a/contrib/bind/bin/named/pathnames.c b/contrib/bind/bin/named/pathnames.c deleted file mode 100644 index 2ba2415daa7a8..0000000000000 --- a/contrib/bind/bin/named/pathnames.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1996 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * $Id: pathnames.c,v 8.5 1997/05/21 19:52:28 halley Exp $ - */ - -#include "port_before.h" - -#include <sys/types.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> - -#include <stdio.h> -#include <string.h> -#include <time.h> - -#include <isc/eventlib.h> -#include <isc/logging.h> - -#include "port_after.h" - -#include "named.h" - -int -main(int argc, char *argv[], char *envp[]) { - char *arg; - - argc--, argv++; - while (argc-- && (arg = *argv++) != NULL) - if (!strcasecmp("_PATH_XFER", arg)) - puts(_PATH_XFER); - else if (!strcasecmp("_PATH_PIDFILE", arg)) - puts(_PATH_PIDFILE); - else if (!strcasecmp("_PATH_NAMED", arg)) - puts(_PATH_NAMED); - else - exit(1); - exit(0); -} diff --git a/contrib/bind/bin/named/pathtemplate.h b/contrib/bind/bin/named/pathtemplate.h deleted file mode 100644 index 301171367cde0..0000000000000 --- a/contrib/bind/bin/named/pathtemplate.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * $Id: pathtemplate.h,v 8.6 2000/04/21 06:54:15 vixie Exp $ - */ - -/* - * Copyright (c) 1996-2000 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include <paths.h> - -#ifndef _PATH_CONF -#define _PATH_CONF "%DESTETC%/named.conf" -#endif - -#ifndef _PATH_DEBUG -#define _PATH_DEBUG "named.run" -#endif - -#ifndef _PATH_DUMPFILE -#define _PATH_DUMPFILE "named_dump.db" -#endif - -#ifndef _PATH_NAMED -#define _PATH_NAMED "%DESTSBIN%/named" -#endif - -#ifndef _PATH_PIDFILE -#define _PATH_PIDFILE "%DESTRUN%/named.pid" -#endif - -#ifndef _PATH_NDCSOCK -#ifdef NEED_SECURE_DIRECTORY -#define _PATH_NDCSOCK "%DESTRUN%/ndc.d/ndc" -#else -#define _PATH_NDCSOCK "%DESTRUN%/ndc" -#endif -#endif - -#ifndef _PATH_STATS -#define _PATH_STATS "named.stats" -#endif - -#ifndef _PATH_MEMSTATS -#define _PATH_MEMSTATS "named.memstats" -#endif - -#ifndef _PATH_TMPXFER -#define _PATH_TMPXFER "xfer.ddt.XXXXXX" -#endif - -#ifndef _PATH_XFER -#define _PATH_XFER "%DESTEXEC%/named-xfer" -#endif - -#ifndef _PATH_XFERTRACE -#define _PATH_XFERTRACE "xfer.trace" -#endif - -#ifndef _PATH_XFERDDT -#define _PATH_XFERDDT "xfer.ddt" -#endif - -#ifndef _PATH_DEVNULL -#define _PATH_DEVNULL "/dev/null" -#endif diff --git a/contrib/bind/bin/named/test/127.0.0.zone b/contrib/bind/bin/named/test/127.0.0.zone deleted file mode 100644 index b9b7bf5e0df42..0000000000000 --- a/contrib/bind/bin/named/test/127.0.0.zone +++ /dev/null @@ -1,11 +0,0 @@ -$ORIGIN 0.0.127.in-addr.arpa. - -@ 1D IN SOA localhost. root.localhost. ( - 42 ; serial (d. adams) - 3H ; refresh - 15M ; retry - 1W ; expiry - 1D ) ; minimum - - 1D IN NS localhost. -1 1D IN PTR localhost. diff --git a/contrib/bind/bin/named/test/localhost.zone b/contrib/bind/bin/named/test/localhost.zone deleted file mode 100644 index ad5e68e863bf4..0000000000000 --- a/contrib/bind/bin/named/test/localhost.zone +++ /dev/null @@ -1,10 +0,0 @@ -$ORIGIN localhost. -@ 1D IN SOA @ root ( - 42 ; serial (d. adams) - 3H ; refresh - 15M ; retry - 1W ; expiry - 1D ) ; minimum - - 1D IN NS @ - 1D IN A 127.0.0.1 diff --git a/contrib/bind/bin/named/test/named.conf b/contrib/bind/bin/named/test/named.conf deleted file mode 100644 index 0e43eac1afb86..0000000000000 --- a/contrib/bind/bin/named/test/named.conf +++ /dev/null @@ -1,45 +0,0 @@ -// This is a configuration file for named (from BIND 8.1 or later). -// It would normally be installed as /etc/named.conf. - -options { -// directory "/var/named"; - check-names master warn; /* default. */ - datasize 20M; - deallocate-on-exit yes; - listen-on { 10.0.0.53; }; -}; - -zone "localhost" IN { - type master; - file "localhost.zone"; - check-names fail; - allow-update { none; }; - allow-transfer { any; }; -}; - -zone "0.0.127.in-addr.arpa" IN { - type master; - file "127.0.0.zone"; - check-names fail; - allow-update { none; }; - allow-transfer { any; }; -}; - -zone "." IN { - type hint; - file "root.hint"; -}; - -logging { - channel xfer-log { - file "/var/tmp/bind-xfer.log" versions unlimited size 10m; - print-category yes; - print-severity yes; - print-time yes; - severity info; - }; - category xfer-in { xfer-log; }; - category xfer-out { xfer-log; }; - category notify { xfer-log; }; - category load { xfer-log; }; -}; diff --git a/contrib/bind/bin/named/test/root.hint b/contrib/bind/bin/named/test/root.hint deleted file mode 100644 index 0b8f372f24506..0000000000000 --- a/contrib/bind/bin/named/test/root.hint +++ /dev/null @@ -1,37 +0,0 @@ - -; <<>> DiG 2.2 <<>> @192.5.5.241 -; (1 server found) -;; res options: init recurs defnam dnsrch -;; got answer: -;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10 -;; flags: qr aa rd; QUERY: 1, ANSWER: 9, AUTHORITY: 0, ADDITIONAL: 9 -;; QUERY SECTION: -;; ., type = NS, class = IN - -;; ANSWER SECTION: -. 6D IN NS C.ROOT-SERVERS.NET. -. 6D IN NS D.ROOT-SERVERS.NET. -. 6D IN NS E.ROOT-SERVERS.NET. -. 6D IN NS I.ROOT-SERVERS.NET. -. 6D IN NS F.ROOT-SERVERS.NET. -. 6D IN NS G.ROOT-SERVERS.NET. -. 6D IN NS A.ROOT-SERVERS.NET. -. 6D IN NS H.ROOT-SERVERS.NET. -. 6D IN NS B.ROOT-SERVERS.NET. - -;; ADDITIONAL SECTION: -C.ROOT-SERVERS.NET. 5w6d16h IN A 192.33.4.12 -D.ROOT-SERVERS.NET. 5w6d16h IN A 128.8.10.90 -E.ROOT-SERVERS.NET. 5w6d16h IN A 192.203.230.10 -I.ROOT-SERVERS.NET. 5w6d16h IN A 192.36.148.17 -F.ROOT-SERVERS.NET. 5w6d16h IN A 192.5.5.241 -G.ROOT-SERVERS.NET. 5w6d16h IN A 192.112.36.4 -A.ROOT-SERVERS.NET. 5w6d16h IN A 198.41.0.4 -H.ROOT-SERVERS.NET. 5w6d16h IN A 128.63.2.53 -B.ROOT-SERVERS.NET. 5w6d16h IN A 128.9.0.107 - -;; Total query time: 8 msec -;; FROM: wisdom.home.vix.com to SERVER: 192.5.5.241 -;; WHEN: Fri Nov 22 00:08:05 1996 -;; MSG SIZE sent: 17 rcvd: 312 - diff --git a/contrib/bind/bin/named/version.c b/contrib/bind/bin/named/version.c deleted file mode 100644 index 31820f5194d9d..0000000000000 --- a/contrib/bind/bin/named/version.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * @(#)Version.c 4.9 (Berkeley) 7/21/90 - * $Id: version.c,v 8.3 1999/01/02 06:05:14 vixie Exp $ - */ - -#ifndef lint -char sccsid[] = "@(#)named %VERSION% %WHEN% %WHOANDWHERE%"; -char rcsid[] = "$Id: version.c,v 8.3 1999/01/02 06:05:14 vixie Exp $"; -#endif /* not lint */ - -char Version[] = "named %VERSION% %WHEN%\n\t%WHOANDWHERE%"; -char ShortVersion[] = "%VERSION%"; - -#ifdef COMMENT - -SCCS/s.Version.c: - -D 4.8.3 90/06/27 17:05:21 bloom 37 35 00031/00028/00079 -Version distributed with 4.3 Reno tape (June 1990) - -D 4.8.2 89/09/18 13:57:11 bloom 35 34 00020/00014/00087 -Interim fixes release - -D 4.8.1 89/02/08 17:12:15 karels 34 33 00026/00017/00075 -branch for 4.8.1 - -D 4.8 88/07/09 14:27:00 karels 33 28 00043/00031/00049 -4.8 is here! - -D 4.7 87/11/20 13:15:52 karels 25 24 00000/00000/00062 -4.7.3 beta - -D 4.6 87/07/21 12:15:52 karels 25 24 00000/00000/00062 -4.6 declared stillborn - -D 4.5 87/02/10 12:33:25 kjd 24 18 00000/00000/00062 -February 1987, Network Release. Child (bind) grows up, parent (kevin) leaves home. - -D 4.4 86/10/01 10:06:26 kjd 18 12 00020/00017/00042 -October 1, 1986 Network Distribution - -D 4.3 86/06/04 12:12:18 kjd 12 7 00015/00028/00044 -Version distributed with 4.3BSD - -D 4.2 86/04/30 20:57:16 kjd 7 1 00056/00000/00016 -Network distribution Freeze and one more version until 4.3BSD - -D 1.1 86/04/30 19:30:00 kjd 1 0 00016/00000/00000 -date and time created 86/04/30 19:30:00 by kjd - -code versions: - -Makefile - Makefile 4.14 (Berkeley) 2/28/88 -db.h - db.h 4.13 (Berkeley) 2/17/88 -db_dump.c - db_dump.c 4.20 (Berkeley) 2/17/88 -db_load.c - db_load.c 4.26 (Berkeley) 2/28/88 -db_lookup.c - db_lookup.c 4.14 (Berkeley) 2/17/88 -db_reload.c - db_reload.c 4.15 (Berkeley) 2/28/88 -db_save.c - db_save.c 4.13 (Berkeley) 2/17/88 -db_update.c - db_update.c 4.16 (Berkeley) 2/28/88 -ns_forw.c - ns_forw.c 4.26 (Berkeley) 3/28/88 -ns_init.c - ns_init.c 4.23 (Berkeley) 2/28/88 -ns_main.c - Copyright (c) 1986 Regents of the University of California.\n\ - ns_main.c 4.30 (Berkeley) 3/7/88 -ns_maint.c - ns_maint.c 4.23 (Berkeley) 2/28/88 -ns_req.c - ns_req.c 4.32 (Berkeley) 3/31/88 -ns_resp.c - ns_resp.c 4.50 (Berkeley) 4/7/88 -ns_sort.c - ns_sort.c 4.3 (Berkeley) 2/17/88 -ns_stats.c - ns_stats.c 4.3 (Berkeley) 2/17/88 -newvers.sh - newvers.sh 4.4 (Berkeley) 3/28/88 - -#endif /* COMMENT */ diff --git a/contrib/bind/bin/ndc/Makefile b/contrib/bind/bin/ndc/Makefile deleted file mode 100644 index 332e3d6610b7d..0000000000000 --- a/contrib/bind/bin/ndc/Makefile +++ /dev/null @@ -1,96 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 1.16 2000/07/11 06:41:34 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -AR= ar cru -INSTALL= install -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin -PS=ps - -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} ${DEFS} - -PROG= ndc -SRCS= ${PROG}.c -OBJS= ${PROG}.${O} -HDRS= pathnames.h - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${HDRS} ${OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} ${LIBBIND} ${SYSLIBS} - -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -pathnames.h: ${TOP}/.settings Makefile ../named/pathtemplate.h - rm -f pathnames.h - sed -e "s|%DESTSBIN%|${DESTSBIN}|" \ - -e "s|%DESTEXEC%|${DESTEXEC}|" \ - -e "s|%DESTETC%|${DESTETC}|" \ - -e "s|%DESTRUN%|${DESTRUN}|" \ - < ../named/pathtemplate.h > pathnames.h - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - rm -f pathnames.h - -depend: ${SRCS} pathnames.h - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${SRCS} - -${DESTDIR}${DESTSBIN}: - mkdir -p ${DESTDIR}${DESTSBIN} - -install: ${DESTDIR}${DESTSBIN} ${PROG}${EXE} - ${INSTALL} ${INSTALL_EXEC} ${STRIP} -c -m 755 ${PROG}${EXE} ${DESTDIR}${DESTSBIN}/${PROG}${EXE} - -links: FRC - @set -e; ln -s SRC/*.[ch] . - -tags: FRC - ctags ${SRCS} *.h - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/ndc/ndc.c b/contrib/bind/bin/ndc/ndc.c deleted file mode 100644 index 7235586ea9568..0000000000000 --- a/contrib/bind/bin/ndc/ndc.c +++ /dev/null @@ -1,709 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ndc.c,v 1.14 2000/02/04 08:28:32 vixie Exp $"; -#endif /* not lint */ - -/* - * Portions Copyright (c) 1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> - -#include <isc/eventlib.h> -#include <isc/ctl.h> - -#include "port_after.h" -#include "pathnames.h" - -typedef union { - struct sockaddr_in in; -#ifndef NO_SOCKADDR_UN - struct sockaddr_un un; -#endif -} sockaddr_t; - -typedef void (*closure)(void *, const char *, int); - -static const char * program = "amnesia"; -static enum { e_channel, e_signals } mode = e_channel; -static char * channel = _PATH_NDCSOCK; -static const char helpfmt[] = "\t%-16s\t%s\n"; -static const char * pidfile = _PATH_PIDFILE; -static sockaddr_t client, server; -static int quiet = 0, tracing = 0, silent = 0, client_set = 0; -static int debug = 0, errors = 0, doneflag, exitflag; -static int logger_show = 1; -static evContext ev; -static char cmd[1000]; -static const char * named_path = _PATH_NAMED; - -static int slashcmd(void); -static void slashhelp(void); -static int builtincmd(void); -static void command(void); -static int running(int, pid_t *); -static void command_channel(void); -static void channel_loop(char *, int, closure, void *); -static void getpid_closure(void *, const char *, int); -static void banner(struct ctl_cctx *, void *, const char *, u_int); -static void done(struct ctl_cctx *, void *, const char *, u_int); -static void logger(enum ctl_severity, const char *fmt, ...); -static void command_signals(void); -static void stop_named(pid_t); -static void start_named(const char *, int); -static int fgetpid(const char *, pid_t *); -static int get_sockaddr(char *, sockaddr_t *); -static size_t impute_addrlen(const struct sockaddr *); -static void vtrace(const char *, va_list); -static void trace(const char *, ...); -static void result(const char *, ...); -static void fatal(const char *, ...); -static void verror(const char *, va_list); -static void error(const char *, ...); - -static void -usage(const char *fmt, ...) { - va_list args; - - va_start(args, fmt); - fprintf(stderr, "%s: usage error: ", program); - vfprintf(stderr, fmt, args); - fputc('\n', stderr); - va_end(args); - fatal("usage: %s \ -[-l localsock] [-c channel] [-p pidfile] [-n namedpath] \ -[-dqst] [command [args]]\n\ -", - program); -} - -/* Public. */ - -int -main(int argc, char *argv[], char *envp[]) { - char *p; - int ch; - - if ((program = strrchr(argv[0], '/')) != NULL) - program++; - else - program = argv[0]; - while ((ch = getopt(argc, argv, "c:p:l:n:dqst")) != -1) { - switch (ch) { - case 'c': - channel = optarg; - mode = e_channel; - break; - case 'p': - pidfile = optarg; - mode = e_signals; - break; - case 'l': - if (!get_sockaddr(optarg, &client)) - usage("bad local socket (%s)", optarg); - client_set++; - break; - case 'n': - named_path = optarg; - break; - case 'd': - tracing++; - debug++; - break; - case 'q': - quiet++; - break; - case 's': - silent++; - break; - case 't': - tracing++; - break; - default: - usage("unrecognized command option (%c)", ch); - /* NOTREACHED */ - } - } - if (mode != e_channel && client_set) - usage("the -l flag is only valid for control channels"); - if (mode == e_channel) { - if (!get_sockaddr(channel, &server)) - usage("bad channel name (%s)", channel); - if (evCreate(&ev) < 0) - fatal("evCreate - %s", strerror(errno)); - } - *(p = cmd) = '\0'; - for (argc -= optind, argv += optind; - argc > 0; - argc--, argv++) { - size_t t = strlen(*argv); - - if ((p - cmd) + t + 2 > sizeof cmd) - usage("command too long"); - strcpy(p, *argv); - p += t; - if (argv[1] != NULL) - *p++ = ' '; - *p = '\0'; - } - if (cmd[0] != '\0') { - command(); - } else { - if (!quiet) - result("Type help -or- /h if you need help."); - for (exitflag = 0; !exitflag; (void)NULL) { - if (!quiet) { - printf("%s> ", program); - fflush(stdout); - } - if (!fgets(cmd, sizeof cmd, stdin)) { - if (!quiet) - result("EOF"); - exitflag++; - continue; - } - if (cmd[strlen(cmd) - 1] == '\n') - cmd[strlen(cmd) - 1] = '\0'; - if (cmd[0] == '\0') - continue; - if (slashcmd()) - continue; - command(); - } - } - if (mode == e_channel) - evDestroy(ev); - exit(errors != 0); -} - -/* Private. */ - -static int -slashcmd(void) { - if (strncasecmp(cmd, "/help", strlen(cmd)) == 0) - slashhelp(); - else if (strncasecmp(cmd, "/exit", strlen(cmd)) == 0) - exitflag++; - else if (strncasecmp(cmd, "/trace", strlen(cmd)) == 0) - result("tracing now %s", - (tracing = !tracing) ? "on" : "off"); - else if (strncasecmp(cmd, "/debug", strlen(cmd)) == 0) - result("debugging now %s", - (debug = !debug) ? "on" : "off"); - else if (strncasecmp(cmd, "/quiet", strlen(cmd)) == 0) - result("%s is now %s", program, - (quiet = !quiet) ? "quiet" : "noisy"); - else if (strncasecmp(cmd, "/silent", strlen(cmd)) == 0) - result("%s is now %s", program, - (silent = !silent) - ? "silent" : "gregarious"); - else - return (0); - return (1); -} - -static void -slashhelp(void) { - printf(helpfmt, "/h(elp)", "this text"); - printf(helpfmt, "/e(xit)", "leave this program"); - printf(helpfmt, "/t(race)", - "toggle tracing (protocol and system events)"); - printf(helpfmt, "/d(ebug)", - "toggle debugging (internal program events)"); - printf(helpfmt, "/q(uiet)", - "toggle quietude (prompts and results)"); - printf(helpfmt, "/s(ilent)", - "toggle silence (suppresses nonfatal errors)"); -} - -static int -builtincmd(void) { - static const char spaces[] = " \t"; - char *rest, *syscmd; - pid_t pid; - int save_quiet = quiet; - int len; - - quiet = 1; - - len = strcspn(cmd, spaces); - rest = cmd + len; - if (*rest != '\0') { - rest++; - rest += strspn(rest, spaces); - } - syscmd = malloc(strlen(named_path) + sizeof " " + strlen(rest)); - if (syscmd == NULL) - fatal("malloc() failed - %s", strerror(errno)); - strcpy(syscmd, named_path); - if (*rest != '\0') { - strcat(syscmd, " "); - strcat(syscmd, rest); - } - if (strncasecmp(cmd, "start", len) == 0) { - if (running(debug, &pid)) - error("name server already running? (pid %ld)", - (long)pid); - else - start_named(syscmd, save_quiet); - quiet = save_quiet; - free(syscmd); - return (1); - } else if (strncasecmp(cmd, "restart", len) == 0) { - if (!running(debug, &pid)) - error("name server was not running (warning only)"); - else - stop_named(pid); - start_named(syscmd, save_quiet); - quiet = save_quiet; - free(syscmd); - return (1); - } - quiet = save_quiet; - free(syscmd); - return (0); -} - -static void -builtinhelp(void) { - printf(helpfmt, "start", "start the server"); - printf(helpfmt, "restart", "stop server if any, start a new one"); -} - -static void -command(void) { - if (builtincmd()) - return; - switch (mode) { - case e_channel: - command_channel(); - break; - case e_signals: - command_signals(); - break; - default: - abort(); - } -} - -static int -running(int show, pid_t *pidp) { - pid_t pid; - - switch (mode) { - case e_channel: - pid = 0; - channel_loop("getpid", show, getpid_closure, &pid); - if (pid != 0) { - if (tracing) - result("pid %ld is running", (long)pid); - *pidp = pid; - return (1); - } - break; - case e_signals: - if (fgetpid(pidfile, pidp)) { - if (tracing) - result("pid %ld is running", (long)pid); - return (1); - } - break; - default: - abort(); - } - if (show) - error("pid not valid or server not running"); - return (0); -} - -static void -getpid_closure(void *uap, const char *text, int flags) { - pid_t *pidp = uap; - const char *cp; - - flags = flags; - if ((cp = strchr(text, '<')) != NULL) { - long l = 0; - char ch; - - while ((ch = *++cp) != '\0' && ch != '>' && isdigit(ch)) - l *= 10, l += (ch - '0'); - if (ch == '>') { - *pidp = (pid_t)l; - return; - } - } - error("response does not contain pid (%s)", text); -} - -static void -command_channel(void) { - int helping = (strcasecmp(cmd, "help") == 0); - int save_quiet = quiet; - - if (helping) - quiet = 0; - channel_loop(cmd, !quiet, NULL, NULL); - quiet = save_quiet; -} - -struct args { - const char *cmd; - closure cl; - void *ua; -}; - -static void -channel_loop(char *cmdtext, int show, closure cl, void *ua) { - struct ctl_cctx *ctl; - struct sockaddr *client_addr; - struct args a; - evEvent e; - int save_logger_show = logger_show; - - if (!client_set) - client_addr = NULL; - else - client_addr = (struct sockaddr *)&client; - a.cmd = cmdtext; - a.cl = cl; - a.ua = ua; - logger_show = show; - ctl = ctl_client(ev, client_addr, impute_addrlen(client_addr), - (struct sockaddr *)&server, - impute_addrlen((struct sockaddr *)&server), - banner, &a, 15, logger); - if (ctl == NULL) { - if (show) - error("cannot connect to command channel (%s)", - channel); - } else { - doneflag = 0; - while (evGetNext(ev, &e, EV_WAIT) == 0) - if (evDispatch(ev, e) < 0 || doneflag) - break; - ctl_endclient(ctl); - } - logger_show = save_logger_show; -} - -static void -banner(struct ctl_cctx *ctl, void *uap, const char *msg, u_int flags) { - struct args *a = uap; - - if (msg == NULL) { - trace("EOF"); - doneflag = 1; - return; - } - trace("%s", msg); - if ((flags & CTL_MORE) != 0) - return; - if (ctl_command(ctl, a->cmd, strlen(a->cmd), done, a) < 0) { - error("ctl_command failed - %s", strerror(errno)); - doneflag = 1; - } -} - -static void -done(struct ctl_cctx *ctl, void *uap, const char *msg, u_int flags) { - struct args *a = uap; - - if (msg == NULL) { - trace("EOF"); - doneflag = 1; - return; - } - if (!tracing && !quiet && strlen(msg) > 4) - result("%s", msg + 4); - trace("%s", msg); - if (a->cl) - (a->cl)(a->ua, msg, flags); - if ((flags & CTL_MORE) == 0) - doneflag = 1; -} - -static void -logger(enum ctl_severity ctlsev, const char *format, ...) { - va_list args; - - va_start(args, format); - switch (ctlsev) { - case ctl_debug: - /* FALLTHROUGH */ - case ctl_warning: - if (debug) - vtrace(format, args); - break; - case ctl_error: - if (logger_show) - verror(format, args); - break; - default: - abort(); - } - va_end(args); -} - -static struct cmdsig { - const char * cmd; - int sig; - const char * help; -} cmdsigs[] = { - { "dumpdb", SIGINT, "dump cache database to a file" }, - { "reload", SIGHUP, "reload configuration file" }, - { "stats", SIGILL, "dump statistics to a file" }, - { "trace", SIGUSR1, "increment trace level" }, - { "notrace", SIGUSR2, "turn off tracing" }, -#ifdef SIGWINCH - { "querylog", SIGWINCH, "toggle query logging" }, - { "qrylog", SIGWINCH, "alias for querylog" }, -#endif - { NULL, 0 } -}; - -static void -command_signals(void) { - struct cmdsig *cmdsig; - pid_t pid; - int sig; - - if (strcasecmp(cmd, "help") == 0) { - printf(helpfmt, "help", "this output"); - printf(helpfmt, "status", "check for running server"); - printf(helpfmt, "stop", "stop the server"); - builtinhelp(); - for (cmdsig = cmdsigs; cmdsig->cmd != NULL; cmdsig++) - printf(helpfmt, cmdsig->cmd, cmdsig->help); - } else if (strcasecmp(cmd, "status") == 0) { - if (!fgetpid(pidfile, &pid)) - error("pid not valid or server not running"); - else - result("pid %ld is running", (long)pid); - } else if (strcasecmp(cmd, "stop") == 0) { - if (!fgetpid(pidfile, &pid)) - error("name server not running"); - else - stop_named(pid); - } else { - for (cmdsig = cmdsigs; cmdsig->cmd != NULL; cmdsig++) - if (strcasecmp(cmd, cmdsig->cmd) == 0) - break; - if (cmdsig->cmd == NULL) - error("unrecognized command (%s)", cmd); - else if (!fgetpid(pidfile, &pid)) - error("can't get pid (%s)", pidfile); - else if (kill(pid, cmdsig->sig) < 0) - error("kill() failed - %s", strerror(errno)); - else - trace("pid %ld sig %d OK", (long)pid, cmdsig->sig); - } -} - -static void -stop_named(pid_t pid) { - int n; - - trace("stopping named (pid %ld)", (long)pid); - switch (mode) { - case e_signals: - if (kill(pid, SIGTERM) < 0) { - error("kill(%ld, SIGTERM) failed - %s", - (long)pid, strerror(errno)); - return; - } - trace("SIGTERM ok, waiting for death"); - break; - case e_channel: - channel_loop("stop", tracing, NULL, NULL); - break; - default: - abort(); - } - for (n = 0; n < 10; n++) { - if (kill(pid, 0) != 0) { - trace("named (pid %ld) is dead", (long)pid); - return; - } - sleep(1); - } - error("named (pid %ld) didn't die", (long)pid); -} - -static void -start_named(const char *syscmd, int local_quiet) { - pid_t pid; - - if (system(syscmd) != 0) - error("could not start new name server (%s)", syscmd); - else { - sleep(3); - if (!running(0, &pid)) - error("name server has not started (yet?)"); - else if (!local_quiet) - result("new pid is %ld", (long)pid); - } -} - -static int -fgetpid(const char *f, pid_t *pid) { - FILE *fp; - int try; - long t; - - for (try = 0; try < 5; try++) { - trace("pidfile is \"%s\" (try #%d)", pidfile, try + 1); - if ((fp = fopen(pidfile, "r")) == NULL) - trace("pid file (%s) unavailable - %s", - pidfile, strerror(errno)); - else if (fscanf(fp, "%ld\n", &t) != 1) - trace("pid file (%s) format is bad", pidfile); - else if (*pid = (pid_t)t, fclose(fp), kill(*pid, 0) < 0) - trace("pid file (%s) contains unusable pid (%d) - %s", - pidfile, *pid, strerror(errno)); - else { - trace("pid is %ld", (long)*pid); - return (1); - } - sleep(1); - } - trace("pid not found"); - return (0); -} - -static int -get_sockaddr(char *name, sockaddr_t *addr) { - char *slash; - -#ifndef NO_SOCKADDR_UN - if (name[0] == '/') { - memset(&addr->un, '\0', sizeof addr->un); - addr->un.sun_family = AF_UNIX; - strncpy(addr->un.sun_path, name, sizeof addr->un.sun_path - 1); - addr->un.sun_path[sizeof addr->un.sun_path - 1] = '\0'; - } else -#endif - if ((slash = strrchr(name, '/')) != NULL) { - char *ibuf = malloc(slash - name + 1); - if (!ibuf) - usage("no memory for IP address (%s)", name); - memcpy(ibuf, name, slash - name); - ibuf[slash - name] = '\0'; - memset(&addr->in, '\0', sizeof addr->in); - if (!inet_pton(AF_INET, ibuf, &addr->in.sin_addr)) - usage("bad ip address (%s)", name); - if ((addr->in.sin_port = htons(atoi(slash+1))) == 0) - usage("bad ip port (%s)", slash+1); - addr->in.sin_family = AF_INET; - free (ibuf); - } else { - return (0); - } - return (1); -} - -static size_t -impute_addrlen(const struct sockaddr *sa) { - if (sa == 0) - return (0); - switch (sa->sa_family) { - case AF_INET: - return (sizeof(struct sockaddr_in)); -#ifndef NO_SOCKADDR_UN - case AF_UNIX: - return (sizeof(struct sockaddr_un)); -#endif - default: - abort(); - } -} - -static void -vtrace(const char *fmt, va_list ap) { - if (tracing) { - fprintf(stdout, "%s: [", program); - vfprintf(stdout, fmt, ap); - fputs("]\n", stdout); - } -} - -static void -trace(const char *fmt, ...) { - va_list args; - - va_start(args, fmt); - vtrace(fmt, args); - va_end(args); -} - -static void -result(const char *fmt, ...) { - va_list args; - - va_start(args, fmt); - vfprintf(stdout, fmt, args); - fputc('\n', stdout); - va_end(args); -} - -static void -fatal(const char *fmt, ...) { - va_list args; - - va_start(args, fmt); - fprintf(stderr, "%s: fatal error: ", program); - vfprintf(stderr, fmt, args); - fputc('\n', stderr); - va_end(args); - exit(1); -} - -static void -verror(const char *fmt, va_list ap) { - fprintf(stderr, "%s: error: ", program); - vfprintf(stderr, fmt, ap); - fputc('\n', stderr); - errors++; -} - -static void -error(const char *fmt, ...) { - va_list args; - - va_start(args, fmt); - if (silent) - vtrace(fmt, args); - else - verror(fmt, args); - va_end(args); -} diff --git a/contrib/bind/bin/ndc/ndc.sh b/contrib/bind/bin/ndc/ndc.sh deleted file mode 100644 index a9b10182cc8d7..0000000000000 --- a/contrib/bind/bin/ndc/ndc.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/sh - -USAGE='echo \ - "usage: $0 \ - (status|dumpdb|reload|stats|trace|notrace|querylog|start|stop|restart) \ - ... \ - "; exit 1' - -PATH=/bin:/usr/bin:/usr/ucb:$PATH; export PATH -PIDFILE=%PIDFILE% - -if [ -f $PIDFILE ] -then - PID=`cat $PIDFILE` - PS=`%PS% $PID | tail -1 | grep $PID` - RUNNING=1 - [ `echo $PS | wc -w` -ne 0 ] || { - PS="named (pid $PID?) not running" - RUNNING=0 - } -else - PS="named (no pid file) not running" - RUNNING=0 -fi - -for ARG -do - case $ARG in - start|stop|restart) - ;; - *) - [ $RUNNING -eq 0 ] && { - echo $PS - exit 1 - } - esac - - case $ARG in - status) echo "$PS";; - dumpdb) kill -INT $PID && echo Dumping Database;; - reload) kill -HUP $PID && echo Reloading Database;; - stats) kill -ILL $PID && echo Dumping Statistics;; - trace) kill -USR1 $PID && echo Trace Level Incremented;; - notrace) kill -USR2 $PID && echo Tracing Cleared;; - querylog|qrylog) kill -WINCH $PID && echo Query Logging Toggled;; - start) - [ $RUNNING -eq 1 ] && { - echo "$0: start: named (pid $PID) already running" - continue - } - rm -f $PIDFILE - %NAMED% && { - sleep 5 - echo Name Server Started - } - ;; - stop) - [ $RUNNING -eq 0 ] && { - echo "$0: stop: named not running" - continue - } - kill $PID && { - sleep 5 - rm -f $PIDFILE - echo Name Server Stopped - } - ;; - restart) - [ $RUNNING -eq 1 ] && { - kill $PID && sleep 5 - } - rm -f $PIDFILE - %NAMED% && { - sleep 5 - echo Name Server Restarted - } - ;; - *) eval "$USAGE";; - esac -done -test -z "$ARG" && eval "$USAGE" - -exit 0 diff --git a/contrib/bind/bin/nslookup/Makefile b/contrib/bind/bin/nslookup/Makefile deleted file mode 100644 index 332b973abe64d..0000000000000 --- a/contrib/bind/bin/nslookup/Makefile +++ /dev/null @@ -1,97 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 8.25 2000/07/11 06:41:35 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -EXE= -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -LDFLAGS= -DEFS= -D_PATH_HELPFILE=\"${DESTDIR}${DESTHELP}/nslookup.help\" -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} ${DEFS} - -PROG= nslookup -CSRCS= main.c getinfo.c debug.c send.c skip.c list.c subr.c -SRCS= ${CSRCS} commands.l -OBJS= main.${O} getinfo.${O} debug.${O} send.${O} skip.${O} list.${O} \ - subr.${O} commands.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} \ - ${LIBBIND} ${SYSLIBS} - -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - rm -f commands.c - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - rm -f lex.yy.c lex.yy.o - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${DEFS} ${CSRCS} - -${DESTDIR}${DESTHELP}: - mkdir -p ${DESTDIR}${DESTHELP} - -${DESTDIR}${DESTBIN}: - mkdir -p ${DESTDIR}${DESTBIN} - -install: ${DESTDIR}${DESTBIN} ${DESTDIR}${DESTHELP} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTBIN}/${PROG}${EXE} - ${INSTALL} -c ${INSTALL_LIB} -m 444 nslookup.help ${DESTDIR}${DESTHELP}/ - -links: FRC - @set -e; ln -s SRC/*.[chl] SRC/nslookup.help . - -tags: FRC - ctags ${CSRCS} *.h - -commands.c: commands.l - ${LEX} -t $< > $@ || rm $@ - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/nslookup/commands.c b/contrib/bind/bin/nslookup/commands.c deleted file mode 100644 index fead60f3206ed..0000000000000 --- a/contrib/bind/bin/nslookup/commands.c +++ /dev/null @@ -1,2041 +0,0 @@ -/* A lexical scanner generated by flex */ - -/* Scanner skeleton version: - * /master/usr.bin/lex/skel.c,v 1.2 1996/05/30 12:31:07 bostic Exp - */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 - -#include <stdio.h> - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include <stdlib.h> -#include <unistd.h> - -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_PROTOS -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include <io.h> -#include <stdlib.h> -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#define YY_BUF_SIZE 16384 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern int yyleng; -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - - -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - }; - -static YY_BUFFER_STATE yy_current_buffer = 0; - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart YY_PROTO(( FILE *input_file )); - -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) - -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); - -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) - -typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -typedef int yy_state_type; -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 22 -#define YY_END_OF_BUFFER 23 -static yyconst short int yy_accept[171] = - { 0, - 0, 0, 23, 22, 21, 22, 22, 19, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 0, 20, 0, - 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 16, 0, 0, 14, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 0, 3, 0, 0, 13, 0, 9, 0, - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, - - 0, 0, 12, 0, 0, 0, 17, 0, 6, 0, - 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, - 0, 0, 0, 0, 9, 0, 0, 11, 0, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 8, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 5, 0, - 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 8, 0, 10, 0 - } ; - -static yyconst int yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 4, 1, 1, 5, 4, 6, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, - 6, 7, 8, 1, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 1, 9, 1, 1, 10, 1, 11, 4, 4, 12, - - 13, 14, 15, 16, 17, 4, 4, 18, 19, 20, - 21, 22, 4, 23, 24, 25, 4, 26, 27, 28, - 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst int yy_meta[29] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 - } ; - -static yyconst short int yy_base[203] = - { 0, - 504, 0, 497, 626, 626, 484, 28, 626, 56, 58, - 65, 52, 49, 47, 55, 57, 61, 477, 626, 0, - 626, 451, 79, 0, 62, 71, 63, 67, 73, 75, - 103, 626, 450, 94, 626, 90, 74, 96, 113, 95, - 94, 107, 141, 150, 100, 106, 105, 159, 108, 104, - 72, 128, 110, 168, 626, 175, 184, 137, 0, 144, - 160, 152, 193, 200, 153, 187, 185, 225, 195, 235, - 202, 626, 244, 626, 186, 204, 626, 215, 626, 254, - 218, 237, 245, 257, 626, 241, 273, 282, 291, 301, - 263, 0, 284, 265, 312, 322, 283, 277, 331, 626, - - 338, 268, 626, 347, 356, 275, 626, 365, 626, 375, - 466, 384, 393, 314, 402, 411, 626, 418, 333, 626, - 427, 436, 445, 448, 626, 455, 464, 626, 474, 483, - 493, 496, 626, 503, 512, 341, 0, 349, 626, 515, - 522, 525, 532, 535, 626, 542, 551, 358, 626, 560, - 377, 563, 570, 579, 386, 582, 626, 589, 598, 395, - 0, 607, 616, 413, 626, 420, 626, 429, 626, 626, - 460, 459, 458, 448, 441, 440, 439, 432, 423, 416, - 405, 398, 389, 380, 368, 361, 352, 336, 325, 306, - 294, 287, 267, 247, 240, 228, 209, 207, 198, 173, - - 162, 144 - } ; - -static yyconst short int yy_def[203] = - { 0, - 171, 170, 170, 170, 170, 172, 170, 170, 173, 172, - 173, 11, 11, 11, 11, 11, 11, 172, 170, 7, - 170, 11, 172, 11, 11, 11, 11, 11, 11, 11, - 174, 170, 11, 172, 170, 11, 11, 11, 11, 11, - 11, 11, 175, 176, 11, 11, 11, 177, 11, 11, - 11, 11, 11, 172, 170, 175, 176, 57, 57, 11, - 11, 11, 178, 172, 11, 11, 11, 179, 11, 180, - 172, 170, 174, 170, 11, 73, 170, 172, 170, 178, - 172, 172, 11, 73, 170, 11, 181, 182, 183, 180, - 90, 90, 11, 90, 184, 185, 11, 11, 172, 170, - - 181, 172, 170, 186, 187, 172, 170, 188, 170, 189, - 90, 190, 191, 11, 192, 172, 170, 186, 172, 170, - 193, 194, 189, 172, 170, 190, 195, 170, 191, 196, - 197, 172, 170, 193, 194, 135, 135, 172, 170, 172, - 198, 172, 199, 172, 170, 197, 200, 172, 170, 201, - 172, 172, 198, 202, 172, 172, 170, 199, 200, 159, - 159, 201, 202, 172, 170, 172, 170, 172, 170, 0, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - - 170, 170 - } ; - -static yyconst short int yy_nxt[655] = - { 0, - 6, 7, 8, 9, 6, 6, 6, 10, 9, 9, - 9, 9, 11, 12, 9, 13, 9, 14, 9, 9, - 9, 9, 15, 16, 9, 17, 9, 9, 18, 20, - 21, 22, 18, 18, 18, 23, 22, 22, 22, 22, - 24, 25, 22, 26, 22, 27, 22, 22, 22, 22, - 28, 29, 22, 30, 22, 22, 18, 31, 32, 34, - 35, 38, 18, 18, 18, 18, 31, 32, 37, 41, - 39, 18, 18, 18, 33, 40, 33, 42, 37, 33, - 34, 35, 33, 38, 33, 41, 39, 40, 33, 33, - 33, 42, 36, 46, 33, 34, 35, 67, 33, 33, - - 33, 33, 33, 18, 31, 32, 45, 18, 18, 44, - 18, 18, 18, 47, 48, 50, 51, 33, 52, 53, - 61, 33, 33, 33, 60, 49, 62, 33, 66, 68, - 65, 33, 33, 33, 33, 33, 69, 33, 71, 72, - 33, 18, 54, 55, 163, 73, 74, 18, 18, 18, - 18, 57, 19, 76, 77, 33, 59, 18, 18, 18, - 48, 32, 162, 64, 18, 44, 18, 18, 18, 54, - 55, 33, 75, 160, 70, 18, 54, 55, 83, 33, - 33, 18, 18, 18, 18, 57, 19, 33, 84, 85, - 18, 18, 18, 18, 78, 79, 89, 86, 158, 18, - - 18, 18, 19, 71, 72, 76, 77, 153, 93, 146, - 81, 81, 33, 33, 33, 81, 78, 79, 81, 95, - 19, 94, 33, 81, 82, 18, 68, 32, 143, 88, - 88, 44, 18, 18, 88, 18, 90, 19, 96, 19, - 141, 92, 18, 18, 18, 73, 74, 136, 18, 18, - 44, 18, 18, 18, 18, 78, 79, 97, 84, 85, - 18, 18, 18, 98, 106, 107, 110, 134, 33, 102, - 103, 111, 33, 18, 99, 100, 106, 107, 115, 18, - 18, 18, 18, 102, 103, 108, 109, 131, 18, 18, - 18, 18, 89, 32, 129, 105, 105, 44, 18, 18, - - 105, 18, 90, 19, 33, 114, 126, 18, 18, 18, - 33, 33, 18, 95, 19, 130, 18, 18, 18, 18, - 18, 18, 18, 96, 19, 123, 18, 18, 18, 18, - 18, 18, 99, 100, 119, 120, 121, 70, 18, 99, - 100, 33, 148, 149, 18, 18, 18, 18, 116, 117, - 138, 139, 105, 18, 18, 18, 18, 119, 120, 148, - 149, 118, 18, 18, 18, 18, 108, 109, 113, 18, - 18, 122, 18, 18, 18, 18, 110, 19, 150, 19, - 112, 18, 18, 18, 18, 124, 125, 154, 19, 104, - 18, 18, 18, 18, 127, 128, 164, 165, 88, 18, - - 18, 18, 18, 115, 32, 101, 18, 18, 44, 18, - 18, 18, 116, 117, 164, 165, 91, 70, 18, 116, - 117, 166, 167, 87, 18, 18, 18, 18, 132, 133, - 168, 169, 80, 18, 18, 18, 18, 135, 19, 63, - 58, 56, 137, 18, 18, 18, 138, 139, 43, 124, - 125, 18, 18, 18, 140, 18, 124, 125, 33, 18, - 4, 18, 18, 18, 18, 127, 128, 110, 18, 18, - 142, 18, 18, 18, 18, 127, 128, 33, 33, 19, - 18, 18, 18, 18, 130, 32, 19, 18, 18, 44, - 18, 18, 18, 18, 144, 145, 170, 132, 133, 18, - - 18, 18, 147, 18, 132, 133, 5, 170, 170, 18, - 18, 18, 18, 135, 19, 170, 150, 19, 18, 18, - 18, 151, 18, 152, 128, 170, 154, 19, 18, 18, - 18, 155, 18, 156, 157, 170, 144, 145, 18, 18, - 18, 70, 18, 144, 145, 170, 170, 170, 18, 18, - 18, 18, 159, 19, 170, 170, 170, 161, 18, 18, - 18, 150, 19, 170, 152, 128, 18, 18, 18, 142, - 18, 152, 128, 170, 170, 170, 18, 18, 18, 18, - 154, 19, 170, 156, 157, 18, 18, 18, 70, 18, - 156, 157, 170, 170, 170, 18, 18, 18, 18, 159, - - 19, 170, 170, 170, 18, 18, 18, 18, 166, 167, - 170, 170, 170, 18, 18, 18, 18, 168, 169, 170, - 170, 170, 18, 18, 18, 3, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170 - } ; - -static yyconst short int yy_chk[655] = - { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 9, 9, 9, 10, - 10, 13, 9, 9, 9, 11, 11, 11, 12, 16, - 14, 11, 11, 11, 14, 15, 13, 17, 25, 12, - 23, 23, 15, 26, 16, 29, 27, 28, 17, 25, - 27, 30, 11, 37, 28, 34, 34, 51, 26, 51, - - 29, 37, 30, 31, 31, 31, 36, 31, 31, 31, - 31, 31, 31, 38, 39, 40, 41, 36, 41, 42, - 46, 41, 40, 38, 45, 39, 47, 45, 50, 52, - 49, 50, 47, 46, 42, 49, 53, 53, 58, 58, - 39, 43, 43, 43, 202, 60, 60, 43, 43, 43, - 44, 44, 44, 62, 62, 52, 44, 44, 44, 48, - 48, 48, 201, 48, 48, 48, 48, 48, 48, 54, - 54, 60, 61, 200, 54, 56, 56, 56, 65, 62, - 65, 56, 56, 56, 57, 57, 57, 61, 66, 66, - 57, 57, 57, 63, 63, 63, 69, 67, 199, 63, - - 63, 63, 64, 71, 71, 76, 76, 198, 75, 197, - 64, 64, 67, 75, 66, 64, 78, 78, 64, 81, - 81, 78, 69, 64, 64, 68, 68, 68, 196, 68, - 68, 68, 68, 68, 68, 70, 70, 70, 82, 82, - 195, 70, 70, 70, 73, 73, 73, 194, 73, 73, - 73, 73, 73, 73, 80, 80, 80, 83, 84, 84, - 80, 80, 80, 86, 91, 91, 94, 193, 86, 102, - 102, 94, 83, 87, 87, 87, 106, 106, 98, 87, - 87, 87, 88, 88, 88, 93, 93, 192, 88, 88, - 88, 89, 89, 89, 191, 89, 89, 89, 89, 89, - - 89, 90, 90, 90, 98, 97, 190, 90, 90, 90, - 97, 93, 95, 95, 95, 114, 95, 95, 95, 95, - 95, 95, 96, 96, 96, 189, 96, 96, 96, 96, - 96, 96, 99, 99, 119, 119, 188, 99, 101, 101, - 101, 114, 136, 136, 101, 101, 101, 104, 104, 104, - 138, 138, 187, 104, 104, 104, 105, 105, 105, 148, - 148, 186, 105, 105, 105, 108, 108, 108, 185, 108, - 108, 108, 108, 108, 108, 110, 110, 110, 151, 151, - 184, 110, 110, 110, 112, 112, 112, 155, 155, 183, - 112, 112, 112, 113, 113, 113, 160, 160, 182, 113, - - 113, 113, 115, 115, 115, 181, 115, 115, 115, 115, - 115, 115, 116, 116, 164, 164, 180, 116, 118, 118, - 118, 166, 166, 179, 118, 118, 118, 121, 121, 121, - 168, 168, 178, 121, 121, 121, 122, 122, 122, 177, - 176, 175, 122, 122, 122, 123, 123, 123, 174, 124, - 124, 123, 123, 123, 124, 126, 126, 126, 173, 172, - 171, 126, 126, 126, 127, 127, 127, 111, 127, 127, - 127, 127, 127, 127, 129, 129, 129, 33, 22, 18, - 129, 129, 129, 130, 130, 130, 6, 130, 130, 130, - 130, 130, 130, 131, 131, 131, 3, 132, 132, 131, - - 131, 131, 132, 134, 134, 134, 1, 0, 0, 134, - 134, 134, 135, 135, 135, 0, 140, 140, 135, 135, - 135, 140, 141, 141, 141, 0, 142, 142, 141, 141, - 141, 142, 143, 143, 143, 0, 144, 144, 143, 143, - 143, 144, 146, 146, 146, 0, 0, 0, 146, 146, - 146, 147, 147, 147, 0, 0, 0, 147, 147, 147, - 150, 150, 150, 0, 152, 152, 150, 150, 150, 152, - 153, 153, 153, 0, 0, 0, 153, 153, 153, 154, - 154, 154, 0, 156, 156, 154, 154, 154, 156, 158, - 158, 158, 0, 0, 0, 158, 158, 158, 159, 159, - - 159, 0, 0, 0, 159, 159, 159, 162, 162, 162, - 0, 0, 0, 162, 162, 162, 163, 163, 163, 0, - 0, 0, 163, 163, 163, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "commands.l" -#define INITIAL 0 -#line 2 "commands.l" - -/* - * Copyright (c) 1985 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -static char sccsid[] = "@(#)commands.l 5.13 (Berkeley) 7/24/90"; -#endif /* not lint */ - -/* - ******************************************************************************* - * - * commands.l - * - * Andrew Cherenson CS298-26 Fall 1985 - * - * Lex input file for the nslookup program command interpreter. - * When a sequence is recognized, the associated action - * routine is called. The action routine may need to - * parse the string for additional information. - * - * Recognized commands: (identifiers are shown in uppercase) - * - * server NAME - set default server to NAME, using default server - * lserver NAME - set default server to NAME, using initial server - * finger [NAME] - finger the optional NAME - * exit - exit the program - * root - set default server to the root - * ls NAME - list the domain NAME - * view FILE - sorts and view the file with more - * set OPTION - set an option - * help - print help information - * ? - print help information - * NAME - print info about the host/domain NAME - * using default server. - * NAME1 NAME2 - as above, but use NAME2 as server - * - * - * yylex Results: - * 0 upon end-of-file. - * 1 after each command. - * - ******************************************************************************* - */ - -#include "port_before.h" -#include <sys/types.h> -#include "port_after.h" -#include "res.h" - -extern char rootServerName[]; -extern void PrintHelp(); -extern void ViewList(char *); - - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); -#else -extern int yywrap YY_PROTO(( void )); -#endif -#endif - -#ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput YY_PROTO(( void )); -#else -static int input YY_PROTO(( void )); -#endif -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif - -#else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 -#endif - -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include <stdlib.h> -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ - -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) -#endif - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ - yy_current_buffer->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION - -YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 110 "commands.l" - - - if ( yy_init ) - { - yy_init = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; - yy_current_state += YY_AT_BOL(); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 171 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 626 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - -do_action: /* This label is used only to access EOF actions. */ - - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; - -case 1: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 111 "commands.l" -{ - /* - * 0 == use current server to find - * the new one. - * 1 == use original server to find - * the new one. - */ - SetDefaultServer(yytext, 0); - return(1); - } - YY_BREAK -case 2: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 121 "commands.l" -{ - SetDefaultServer(yytext, 1); - return(1); - } - YY_BREAK -case 3: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 125 "commands.l" -{ - return(0); - } - YY_BREAK -case 4: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 128 "commands.l" -{ - SetDefaultServer(rootServerName, 1); - return(1); - } - YY_BREAK -case 5: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 132 "commands.l" -{ - /* - * 2nd arg. - * 0 == output to stdout - * 1 == output to file - */ - Finger(yytext, 1); - return(1); - } - YY_BREAK -case 6: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 141 "commands.l" -{ - Finger(yytext, 0); - return(1); - } - YY_BREAK -case 7: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 145 "commands.l" -{ - ViewList((char *)yytext); - return(1); - } - YY_BREAK -case 8: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 149 "commands.l" -{ - /* - * 2nd arg. - * 0 == output to stdout - * 1 == output to file - */ - ListHosts(yytext, 1); - return(1); - } - YY_BREAK -case 9: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 158 "commands.l" -{ - ListHosts(yytext, 0); - return(1); - } - YY_BREAK -case 10: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 162 "commands.l" -{ - /* - * 2nd arg. - * 0 == output to stdout - * 1 == output to file - */ - ListHostsByType(yytext, 1); - return(1); - } - YY_BREAK -case 11: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 171 "commands.l" -{ - ListHostsByType(yytext, 0); - return(1); - } - YY_BREAK -case 12: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 175 "commands.l" -{ - SetOption(yytext); - return(1); - } - YY_BREAK -case 13: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 179 "commands.l" -{ - PrintHelp(); - return(1); - } - YY_BREAK -case 14: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 183 "commands.l" -{ - extern void PrintHelp(); - - PrintHelp(); - return(1); - } - YY_BREAK -case 15: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 189 "commands.l" -{ - /* - * 0 == output to stdout - * 1 == output to file - */ - LookupHost(yytext, 1); - return(1); - } - YY_BREAK -case 16: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 197 "commands.l" -{ - LookupHost(yytext, 0); - return(1); - } - YY_BREAK -case 17: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 201 "commands.l" -{ - /* - * 0 == output to stdout - * 1 == output to file - */ - LookupHostWithServer(yytext, 1); - return(1); - } - YY_BREAK -case 18: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 209 "commands.l" -{ - LookupHostWithServer(yytext, 0); - return(1); - } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 213 "commands.l" -{ - return(1); - } - YY_BREAK -case 20: -YY_RULE_SETUP -#line 216 "commands.l" -{ - printf("Unrecognized command: %s", - yytext); - return(1); - } - YY_BREAK -case 21: -YY_RULE_SETUP -#line 221 "commands.l" -{ ; } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 222 "commands.l" -ECHO; - YY_BREAK -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ - - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; - - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; -#endif - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 171 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -#ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) -#else -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; -#endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 171 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 170); - - return yy_is_jam ? 0 : yy_current_state; - } - - -#ifndef YY_NO_UNPUT -#ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) -#else -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; -#endif - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ - - -#ifdef __cplusplus -static int yyinput() -#else -static int input() -#endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - { - yy_c_buf_p = yytext_ptr + offset; - return EOF; - } - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - - case EOB_ACT_LAST_MATCH: -#ifdef __cplusplus - YY_FATAL_ERROR( - "unexpected last match in yyinput()" ); -#else - YY_FATAL_ERROR( - "unexpected last match in input()" ); -#endif - } - } - } - - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - - yy_current_buffer->yy_at_bol = (c == '\n'); - - return c; - } - - -#ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) -#else -void yyrestart( input_file ) -FILE *input_file; -#endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -#ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -#else -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; -#endif - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -#ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) -#else -void yy_load_buffer_state() -#endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) -#else -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; -#endif - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; - } - - -#ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) -#else -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; -#endif - { - if ( ! b ) - return; - - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); - - yy_flex_free( (void *) b ); - } - - -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -extern int isatty YY_PROTO(( int )); -#endif -#endif - -#ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) -#else -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; -#endif - - - { - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - -#if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } - - -#ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) -#else -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; -#endif - - { - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } - - -#ifndef YY_NO_SCAN_BUFFER -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) -#else -YY_BUFFER_STATE yy_scan_buffer( base, size ) -char *base; -yy_size_t size; -#endif - { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; - } -#endif - - -#ifndef YY_NO_SCAN_STRING -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *str ) -#else -YY_BUFFER_STATE yy_scan_string( str ) -yyconst char *str; -#endif - { - int len; - for ( len = 0; str[len]; ++len ) - ; - - return yy_scan_bytes( str, len ); - } -#endif - - -#ifndef YY_NO_SCAN_BYTES -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) -#else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) -yyconst char *bytes; -int len; -#endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; - } -#endif - - -#ifndef YY_NO_PUSH_STATE -#ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) -#else -static void yy_push_state( new_state ) -int new_state; -#endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; - - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); - - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); - - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); - - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } - - yy_start_stack[yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); - } -#endif - - -#ifndef YY_NO_POP_STATE -static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif - - -#ifndef YY_NO_TOP_STATE -static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -#ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) -#else -static void yy_fatal_error( msg ) -char msg[]; -#endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - - - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) - - -/* Internal utility routines. */ - -#ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -#endif - -#ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; - } -#endif - - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { - return (void *) malloc( size ); - } - -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } - -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } - -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif -#line 222 "commands.l" - diff --git a/contrib/bind/bin/nslookup/commands.l b/contrib/bind/bin/nslookup/commands.l deleted file mode 100644 index 19cf06269ca47..0000000000000 --- a/contrib/bind/bin/nslookup/commands.l +++ /dev/null @@ -1,218 +0,0 @@ -%{ - -/* - * Copyright (c) 1985 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -static char sccsid[] = "@(#)commands.l 5.13 (Berkeley) 7/24/90"; -#endif /* not lint */ - -/* - ******************************************************************************* - * - * commands.l - * - * Andrew Cherenson CS298-26 Fall 1985 - * - * Lex input file for the nslookup program command interpreter. - * When a sequence is recognized, the associated action - * routine is called. The action routine may need to - * parse the string for additional information. - * - * Recognized commands: (identifiers are shown in uppercase) - * - * server NAME - set default server to NAME, using default server - * lserver NAME - set default server to NAME, using initial server - * finger [NAME] - finger the optional NAME - * exit - exit the program - * root - set default server to the root - * ls NAME - list the domain NAME - * view FILE - sorts and view the file with more - * set OPTION - set an option - * help - print help information - * ? - print help information - * NAME - print info about the host/domain NAME - * using default server. - * NAME1 NAME2 - as above, but use NAME2 as server - * - * - * yylex Results: - * 0 upon end-of-file. - * 1 after each command. - * - ******************************************************************************* - */ - -#include "port_before.h" -#include <sys/types.h> -#include "port_after.h" -#include "res.h" - -extern char rootServerName[]; -extern void PrintHelp(); -extern void ViewList(char *); - -%} -WS [ \t] -FLET [A-Za-z0-9.*\\_] -LET [A-Za-z0-9.*_] -NAME [A-Za-z0-9.*=_/-] -%% -^{WS}*server{WS}+{LET}{NAME}*{WS}*$ { - /* - * 0 == use current server to find - * the new one. - * 1 == use original server to find - * the new one. - */ - SetDefaultServer(yytext, 0); - return(1); - } -^{WS}*lserver{WS}+{LET}{NAME}*{WS}*$ { - SetDefaultServer(yytext, 1); - return(1); - } -^{WS}*exit{WS}*$ { - return(0); - } -^{WS}*root{WS}*$ { - SetDefaultServer(rootServerName, 1); - return(1); - } -^{WS}*finger({WS}+{LET}{NAME}*)?{WS}+>>?{WS}*{NAME}+{WS}*$ { - /* - * 2nd arg. - * 0 == output to stdout - * 1 == output to file - */ - Finger(yytext, 1); - return(1); - } -^{WS}*finger({WS}+{LET}{NAME}*)?{WS}*$ { - Finger(yytext, 0); - return(1); - } -^{WS}*ls{WS}+(("-a"|"-d"|"-h"|"-m"|"-s"){WS}+)?{LET}{NAME}*{WS}+>>?{WS}+{NAME}+{WS}*$ { - /* - * 2nd arg. - * 0 == output to stdout - * 1 == output to file - */ - ListHosts(yytext, 1); - return(1); - } -^{WS}*ls{WS}+(("-a"|"-d"|"-h"|"-m"|"-s"){WS}+)?{LET}{NAME}*{WS}*$ { - ListHosts(yytext, 0); - return(1); - } -^{WS}*ls{WS}+-t{WS}+({LET}{NAME}*{WS}+)?{LET}{NAME}*{WS}+>>?{WS}+{NAME}+{WS}*$ { - /* - * 2nd arg. - * 0 == output to stdout - * 1 == output to file - */ - ListHostsByType(yytext, 1); - return(1); - } -^{WS}*ls{WS}+-t{WS}+({LET}{NAME}*{WS}+)?{LET}{NAME}*{WS}*$ { - ListHostsByType(yytext, 0); - return(1); - } -^{WS}*set{WS}+{NAME}+{WS}*$ { - SetOption(yytext); - return(1); - } -^{WS}*help{WS}*$ { - PrintHelp(); - return(1); - } -^{WS}*"?"{WS}*$ { - extern void PrintHelp(); - - PrintHelp(); - return(1); - } -^{WS}*{FLET}{NAME}*{WS}+>>?{WS}*{NAME}+{WS}*$ { - /* - * 0 == output to stdout - * 1 == output to file - */ - LookupHost(yytext, 1); - return(1); - } -^{WS}*{FLET}{NAME}*{WS}*$ { - LookupHost(yytext, 0); - return(1); - } -^{WS}*{FLET}{NAME}*{WS}+{LET}{NAME}*{WS}+>>?{WS}*{NAME}+{WS}*$ { - /* - * 0 == output to stdout - * 1 == output to file - */ - LookupHostWithServer(yytext, 1); - return(1); - } -^{WS}*{FLET}{NAME}*{WS}+{LET}{NAME}*{WS}*$ { - LookupHostWithServer(yytext, 0); - return(1); - } -^{WS}*\n { - return(1); - } -^.*\n { - printf("Unrecognized command: %s", - yytext); - return(1); - } -\n { ; } -%% diff --git a/contrib/bind/bin/nslookup/debug.c b/contrib/bind/bin/nslookup/debug.c deleted file mode 100644 index a5f85e6b99745..0000000000000 --- a/contrib/bind/bin/nslookup/debug.c +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Copyright (c) 1985, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -static const char sccsid[] = "@(#)debug.c 5.26 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: debug.c,v 8.16 2000/07/11 05:59:32 vixie Exp $"; -#endif /* not lint */ - -/* - ******************************************************************************* - * - * debug.c -- - * - * Routines to print out packets received from a name server query. - * - * Modified version of 4.3BSD BIND res_debug.c 5.30 6/27/90 - * - ******************************************************************************* - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <netdb.h> -#include <resolv.h> -#include <stdio.h> - -#include "port_after.h" - -#include "res.h" - -/* - * Imported from res_debug.c - */ -extern char *_res_opcodes[]; - -/* - * Used to highlight the start of a record when printing it. - */ -#define INDENT " -> " - -/* - * Print the contents of a query. - * This is intended to be primarily a debugging routine. - */ - -void -Print_query(const u_char *msg, const u_char *eom, int printHeader) { - Fprint_query(msg, eom, printHeader, stdout); -} - -void -Fprint_query(const u_char *msg, const u_char *eom, int printHeader, FILE *file) -{ - const u_char *cp; - const HEADER *hp; - int n; - u_int class, type; - - /* - * Print header fields. - */ - hp = (HEADER *)msg; - cp = msg + HFIXEDSZ; - if (printHeader || (res.options & RES_DEBUG2)) { - fprintf(file," HEADER:\n"); - fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]); - fprintf(file,", id = %d", ntohs(hp->id)); - fprintf(file,", rcode = %s\n", p_rcode(hp->rcode)); - fprintf(file,"\theader flags: "); - if (hp->qr) { - fprintf(file," response"); - } else { - fprintf(file," query"); - } - if (hp->aa) - fprintf(file,", auth. answer"); - if (hp->tc) - fprintf(file,", truncation"); - if (hp->rd) - fprintf(file,", want recursion"); - if (hp->ra) - fprintf(file,", recursion avail."); - if (hp->unused) - fprintf(file,", UNUSED-QUERY_BIT"); - if (hp->ad) - fprintf(file,", authentic data"); - if (hp->cd) - fprintf(file,", checking disabled"); - fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount)); - fprintf(file,", answers = %d", ntohs(hp->ancount)); - fprintf(file,", authority records = %d", ntohs(hp->nscount)); - fprintf(file,", additional = %d\n\n", ntohs(hp->arcount)); - } - - /* - * Print question records. - */ - n = ntohs(hp->qdcount); - if (n > 0) { - fprintf(file," QUESTIONS:\n"); - while (--n >= 0) { - fprintf(file,"\t"); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) - return; - type = ns_get16((u_char*)cp); - cp += INT16SZ; - class = ns_get16((u_char*)cp); - cp += INT16SZ; - fprintf(file,", type = %s", p_type(type)); - fprintf(file,", class = %s\n", p_class(class)); - } - } - /* - * Print authoritative answer records - */ - n = ntohs(hp->ancount); - if (n > 0) { - fprintf(file," ANSWERS:\n"); - if (type == ns_t_a && n > MAXADDRS) { - printf("Limiting response to MAX Addrs = %d \n", - MAXADDRS); - n = MAXADDRS; - } - while (--n >= 0) { - fprintf(file, INDENT); - cp = Print_rr(cp, msg, eom, file); - if (cp == NULL) - return; - } - } - /* - * print name server records - */ - n = ntohs(hp->nscount); - if (n > 0) { - fprintf(file," AUTHORITY RECORDS:\n"); - while (--n >= 0) { - fprintf(file, INDENT); - cp = Print_rr(cp, msg, eom, file); - if (cp == NULL) - return; - } - } - /* - * print additional records - */ - n = ntohs(hp->arcount); - if (n > 0) { - fprintf(file," ADDITIONAL RECORDS:\n"); - while (--n >= 0) { - fprintf(file, INDENT); - cp = Print_rr(cp, msg, eom, file); - if (cp == NULL) - return; - } - } - fprintf(file,"\n------------\n"); -} - -const u_char * -Print_cdname_sub(const u_char *cp, const u_char *msg, const u_char *eom, - FILE *file, int format) -{ - char name[MAXDNAME]; - int n; - - n = dn_expand(msg, eom, cp, name, sizeof name); - if (n < 0) - return (NULL); - if (name[0] == '\0') - strcpy(name, "(root)"); - if (format) - fprintf(file, "%-30s", name); - else - fputs(name, file); - return (cp + n); -} - -const u_char * -Print_cdname(const u_char *cp, const u_char *msg, const u_char *eom, - FILE *file) -{ - return (Print_cdname_sub(cp, msg, eom, file, 0)); -} - -const u_char * -Print_cdname2(const u_char *cp, const u_char *msg, const u_char *eom, - FILE *file) -{ - return (Print_cdname_sub(cp, msg, eom, file, 1)); -} - -#define BOUNDS_CHECK(ptr, count) \ - do { \ - if ((ptr) + (count) > eom) { \ - fprintf(file, "(form error.)\n"); \ - return (NULL); \ - } \ - } while (0) - -/* - * Print resource record fields in human readable form (not master file form). - */ -const u_char * -Print_rr(const u_char *ocp, const u_char *msg, const u_char *eom, FILE *file) { - u_int type, class; - int dlen, n, c, debug; - u_long rrttl, ttl; - struct in_addr inaddr; - const u_char *cp, *cp1, *cp2; - - if ((cp = Print_cdname(ocp, msg, eom, file)) == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - - BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ); - NS_GET16(type, cp); - NS_GET16(class, cp); - NS_GET32(rrttl, cp); - NS_GET16(dlen, cp); - BOUNDS_CHECK(cp, dlen); - - debug = res.options & (RES_DEBUG|RES_DEBUG2); - if (debug) { - if (res.options & RES_DEBUG2) - fprintf(file,"\n\ttype = %s, class = %s, dlen = %d", - p_type(type), p_class(class), dlen); - if (type == T_SOA) - fprintf(file,"\n\tttl = %lu (%s)", - rrttl, p_time(rrttl)); - putc('\n', file); - } - - cp1 = cp; - - /* - * Print type specific data, if appropriate - */ - switch (type) { - case T_A: - BOUNDS_CHECK(cp, INADDRSZ); - memcpy(&inaddr, cp, INADDRSZ); - fprintf(file,"\tinternet address = %s\n", inet_ntoa(inaddr)); - cp += dlen; - break; - - case T_CNAME: - fprintf(file,"\tcanonical name = "); - goto doname; - - case T_MG: - fprintf(file,"\tmail group member = "); - goto doname; - - case T_MB: - fprintf(file,"\tmail box = "); - goto doname; - - case T_MR: - fprintf(file,"\tmailbox rename = "); - goto doname; - - case T_MX: - BOUNDS_CHECK(cp, INT16SZ); - fprintf(file,"\tpreference = %u",ns_get16((u_char*)cp)); - cp += INT16SZ; - fprintf(file,", mail exchanger = "); - goto doname; - - case T_NAPTR: - BOUNDS_CHECK(cp, 2 * INT16SZ); - fprintf(file, "\torder = %u",ns_get16((u_char*)cp)); - cp += INT16SZ; - fprintf(file,", preference = %u\n", ns_get16((u_char*)cp)); - cp += INT16SZ; - /* Flags */ - BOUNDS_CHECK(cp, 1); - n = *cp++; - BOUNDS_CHECK(cp, n); - fprintf(file,"\tflags = \"%.*s\"\n", (int)n, cp); - cp += n; - /* Service */ - BOUNDS_CHECK(cp, 1); - n = *cp++; - BOUNDS_CHECK(cp, n); - fprintf(file,"\tservices = \"%.*s\"\n", (int)n, cp); - cp += n; - /* Regexp */ - BOUNDS_CHECK(cp, 1); - n = *cp++; - BOUNDS_CHECK(cp, n); - fprintf(file,"\trule = \"%.*s\"\n", (int)n, cp); - cp += n; - /* Replacement */ - fprintf(file,"\treplacement = "); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(replacement truncated?)\n"); - return (NULL); /* compression error */ - } - (void) putc('\n', file); - break; - - case T_SRV: - BOUNDS_CHECK(cp, 3 * INT16SZ); - fprintf(file, "\tpriority = %u",ns_get16((u_char*)cp)); - cp += INT16SZ; - fprintf(file,", weight = %u", ns_get16((u_char*)cp)); - cp += INT16SZ; - fprintf(file,", port= %u\n", ns_get16((u_char*)cp)); - cp += INT16SZ; - - fprintf(file,"\thost = "); - goto doname; - - case T_PX: - BOUNDS_CHECK(cp, INT16SZ); - fprintf(file,"\tpreference = %u",ns_get16((u_char*)cp)); - cp += INT16SZ; - fprintf(file,", RFC 822 = "); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - fprintf(file,"\nX.400 = "); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - (void) putc('\n', file); - break; - - case T_RT: - BOUNDS_CHECK(cp, INT16SZ); - fprintf(file,"\tpreference = %u",ns_get16((u_char*)cp)); - cp += INT16SZ; - fprintf(file,", router = "); - goto doname; - - case T_AFSDB: - BOUNDS_CHECK(cp, INT16SZ); - fprintf(file,"\tsubtype = %d",ns_get16((u_char*)cp)); - cp += INT16SZ; - fprintf(file,", DCE/AFS server = "); - goto doname; - - case T_NS: - fprintf(file,"\tnameserver = "); - goto doname; - - case T_PTR: - fprintf(file,"\tname = "); - doname: - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - (void) putc('\n', file); - break; - - case T_HINFO: - cp2 = cp + dlen; - BOUNDS_CHECK(cp, 1); - if ((n = *cp++) != 0) { - BOUNDS_CHECK(cp, n); - fprintf(file,"\tCPU = %.*s", n, cp); - cp += n; - } - if ((cp < cp2) && ((n = *cp++) != 0)) { - BOUNDS_CHECK(cp, n); - fprintf(file,"\tOS = %.*s\n", n, cp); - cp += n; - } else fprintf(file, "\n*** Warning *** OS-type missing\n"); - break; - - case T_ISDN: - cp2 = cp + dlen; - BOUNDS_CHECK(cp, 1); - n = *cp++; - if (n != 0) { - BOUNDS_CHECK(cp, n); - fprintf(file,"\tISDN = \"%.*s", n, cp); - cp += n; - } - if ((cp < cp2) && (n = *cp++)) { - BOUNDS_CHECK(cp, n); - fprintf(file,"-%.*s\"\n", n, cp); - cp += n; - } else fprintf(file,"\"\n"); - break; - - case T_SOA: - if (!debug) - putc('\n', file); - fprintf(file,"\torigin = "); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - fprintf(file,"\n\tmail addr = "); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - BOUNDS_CHECK(cp, 5 * INT32SZ); - fprintf(file,"\n\tserial = %lu", ns_get32((u_char*)cp)); - cp += INT32SZ; - ttl = ns_get32((u_char*)cp); - fprintf(file,"\n\trefresh = %lu (%s)", ttl, p_time(ttl)); - cp += INT32SZ; - ttl = ns_get32((u_char*)cp); - fprintf(file,"\n\tretry = %lu (%s)", ttl, p_time(ttl)); - cp += INT32SZ; - ttl = ns_get32((u_char*)cp); - fprintf(file,"\n\texpire = %lu (%s)", ttl, p_time(ttl)); - cp += INT32SZ; - ttl = ns_get32((u_char*)cp); - fprintf(file, - "\n\tminimum ttl = %lu (%s)\n", ttl, p_time(ttl)); - cp += INT32SZ; - break; - - case T_MINFO: - if (!debug) - putc('\n', file); - fprintf(file,"\trequests = "); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - fprintf(file,"\n\terrors = "); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - (void) putc('\n', file); - break; - - case T_RP: - if (!debug) - putc('\n', file); - fprintf(file,"\tmailbox = "); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - fprintf(file,"\n\ttext = "); - cp = Print_cdname(cp, msg, eom, file); - if (cp == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - (void) putc('\n', file); - break; - - case T_TXT: - (void) fputs("\ttext = ", file); - cp2 = cp1 + dlen; - while (cp < cp2) { - (void) putc('"', file); - n = (unsigned char) *cp++; - if (n != 0) { - for (c = n; c > 0 && cp < cp2; c--) { - if ((*cp == '\n') || (*cp == '"') || (*cp == '\\')) - (void) putc('\\', file); - (void) putc(*cp++, file); - } - } - (void) putc('"', file); - if (cp < cp2) - (void) putc(' ', file); - } - (void) putc('\n', file); - break; - - case T_X25: - (void) fputs("\tX25 = \"", file); - cp2 = cp1 + dlen; - while (cp < cp2) { - n = (unsigned char) *cp++; - if (n != 0) { - for (c = n; c > 0 && cp < cp2; c--) - if (*cp == '\n') { - (void) putc('\\', file); - (void) putc(*cp++, file); - } else - (void) putc(*cp++, file); - } - } - (void) fputs("\"\n", file); - break; - - case T_NSAP: - fprintf(file, "\tnsap = %s\n", inet_nsap_ntoa(dlen, cp, NULL)); - cp += dlen; - break; - - case T_AAAA: { - char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - - BOUNDS_CHECK(cp, IN6ADDRSZ); - fprintf(file, "\tIPv6 address = %s\n", - inet_ntop(AF_INET6, cp, t, sizeof t)); - cp += IN6ADDRSZ; - break; - } - - case T_WKS: { - struct protoent *protoPtr; - - BOUNDS_CHECK(cp, INADDRSZ + 1); - if (!debug) - (void) putc('\n', file); - memcpy(&inaddr, cp, INADDRSZ); - cp += INADDRSZ; - if ((protoPtr = getprotobynumber(*cp)) != NULL) { - fprintf(file,"\tinet address = %s, protocol = %s\n\t", - inet_ntoa(inaddr), protoPtr->p_name); - } else { - fprintf(file,"\tinet address = %s, protocol = %d\n\t", - inet_ntoa(inaddr), *cp); - } - cp++; - n = 0; - while (cp < cp1 + dlen) { - c = *cp++; - do { - struct servent *s; - - if (c & 0200) { - s = getservbyport((int)htons(n), - protoPtr ? protoPtr->p_name : NULL); - if (s != NULL) { - fprintf(file," %s", s->s_name); - } else { - fprintf(file," #%d", n); - } - } - c <<= 1; - } while (++n & 07); - } - putc('\n',file); - break; - } - - case T_NULL: - fprintf(file, "\tNULL (dlen %d)\n", dlen); - cp += dlen; - break; - - case T_NXT: - case T_SIG: - case T_KEY: - default: { - char buf[2048]; /* XXX need to malloc/realloc. */ - char rrname[NS_MAXDNAME]; - - cp2 = p_fqnname(ocp, msg, NS_MAXCDNAME, rrname, sizeof rrname); - if (cp2 == NULL) { - fprintf(file, "(name truncated?)\n"); - return (NULL); /* compression error */ - } - - if (ns_sprintrrf(msg, eom - msg, rrname, (ns_class)class, - (ns_type)type, rrttl, cp1, dlen, NULL, NULL, - buf, sizeof buf) < 0) { - perror("ns_sprintrrf"); - } else { - fprintf(file, - "\trecord type %s, interpreted as:\n%s\n", - p_type(type), buf); - } - cp += dlen; - } - } - if (res.options & RES_DEBUG && type != T_SOA) { - fprintf(file,"\tttl = %lu (%s)\n", rrttl, p_time(rrttl)); - } - if (cp != cp1 + dlen) { - fprintf(file, - "\n*** Error: record size incorrect (%d != %d)\n\n", - cp - cp1, dlen); - cp = NULL; - } - return (cp); -} diff --git a/contrib/bind/bin/nslookup/getinfo.c b/contrib/bind/bin/nslookup/getinfo.c deleted file mode 100644 index 8d5c8df9738af..0000000000000 --- a/contrib/bind/bin/nslookup/getinfo.c +++ /dev/null @@ -1,874 +0,0 @@ -/* - * Copyright (c) 1985, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -static const char sccsid[] = "@(#)getinfo.c 5.26 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: getinfo.c,v 8.16 2000/07/11 04:36:26 vixie Exp $"; -#endif /* not lint */ - -/* - ****************************************************************************** - * - * getinfo.c -- - * - * Routines to create requests to name servers - * and interpret the answers. - * - * Adapted from 4.3BSD BIND gethostnamadr.c - * - ****************************************************************************** - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "port_after.h" - -#include "res.h" - -extern char *res_skip(); - -static char *addr_list[MAXADDRS + 1]; - -static char *host_aliases[MAXALIASES]; -static int host_aliases_len[MAXALIASES]; -static u_char hostbuf[MAXDNAME]; - -typedef struct { - char *name; - char *domain[MAXDOMAINS]; - int numDomains; - char *address[MAXADDRS]; - int numAddresses; -} ServerTable; - -ServerTable server[MAXSERVERS]; - -typedef union { - HEADER qb1; - u_char qb2[64*1024]; -} querybuf; - -typedef union { - int32_t al; - char ac; -} align; - -#define GetShort(cp) ns_get16(cp); cp += INT16SZ; - - -/* - ****************************************************************************** - * - * GetAnswer -- - * - * Interprets an answer packet and retrieves the following - * information: - * - * Results: - * SUCCESS the info was retrieved. - * NO_INFO the packet did not contain an answer. - * NONAUTH non-authoritative information was found. - * ERROR the answer was malformed. - * Other errors returned in the packet header. - * - ****************************************************************************** - */ - -static int -GetAnswer(nsAddrPtr, queryType, msg, msglen, iquery, hostPtr, isServer) - struct in_addr *nsAddrPtr; - char *msg; - int queryType; - int msglen; - Boolean iquery; - register HostInfo *hostPtr; - Boolean isServer; -{ - register HEADER *headerPtr; - register u_char *cp; - querybuf answer; - char **aliasPtr; - u_char *eom, *bp; - char **addrPtr; - char *namePtr; - char *dnamePtr; - int type, class; - int qdcount, ancount, arcount, nscount, buflen; - int origClass; - int numAliases = 0; - int numAddresses = 0; - int n, i, j; - int dlen; - int status; - int numServers; - size_t s; - Boolean haveAnswer; - Boolean printedAnswers = FALSE; - - - /* - * If the hostPtr was used before, free up the calloc'd areas. - */ - FreeHostInfoPtr(hostPtr); - - status = SendRequest(nsAddrPtr, msg, msglen, (u_char *) &answer, - sizeof(answer), &n); - - if (status != SUCCESS) { - if (res.options & RES_DEBUG2) - printf("SendRequest failed\n"); - return (status); - } - eom = (u_char *) &answer + n; - - headerPtr = (HEADER *) &answer; - - if (headerPtr->rcode != NOERROR) { - return (headerPtr->rcode); - } - - qdcount = ntohs(headerPtr->qdcount); - ancount = ntohs(headerPtr->ancount); - arcount = ntohs(headerPtr->arcount); - nscount = ntohs(headerPtr->nscount); - - /* - * If there are no answer, n.s. or additional records - * then return with an error. - */ - if (ancount == 0 && nscount == 0 && arcount == 0) { - return (NO_INFO); - } - - - bp = hostbuf; - buflen = sizeof(hostbuf); - cp = (u_char *) &answer + HFIXEDSZ; - - /* Skip over question section. */ - while (qdcount-- > 0) { - n = dn_skipname(cp, eom); - if (n < 0) - return (ERROR); - cp += n + QFIXEDSZ; - if (cp > eom) - return (ERROR); - } - - aliasPtr = host_aliases; - addrPtr = addr_list; - haveAnswer = FALSE; - - /* - * Scan through the answer resource records. - * Answers for address query types are saved. - * Other query type answers are just printed. - */ - if (ancount != 0) { - - if (headerPtr->ad) - printf("Answer crypto-validated by server:\n"); - - if (!isServer && !headerPtr->aa) { - printf("Non-authoritative answer:\n"); - } - - if (queryType != T_A && !(iquery && queryType == T_PTR)) { - while (--ancount >= 0 && cp < eom) { - if ((cp = (u_char *)Print_rr(cp, - (u_char *)&answer, eom, stdout)) == NULL) { - return(ERROR); - } - } - printedAnswers = TRUE; - } else { - while (--ancount >= 0 && cp < eom) { - n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen); - if (n < 0) - return(ERROR); - cp += n; - if (cp + 3 * INT16SZ + INT32SZ > eom) - return (ERROR); - type = GetShort(cp); - class = GetShort(cp); - cp += INT32SZ; /* skip TTL */ - dlen = GetShort(cp); - if (cp + dlen > eom) - return (ERROR); - if (type == T_CNAME) { - /* - * Found an alias. - */ - cp += dlen; - if (aliasPtr >= &host_aliases[MAXALIASES-1]) { - continue; - } - *aliasPtr++ = (char *)bp; - s = strlen((char *)bp) + 1; - host_aliases_len[numAliases] = s; - numAliases++; - bp += s; - buflen -= s; - continue; - } else if (type == T_PTR) { - /* - * Found a "pointer" to the real name. - */ - n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen); - if (n < 0) { - cp += n; - continue; - } - cp += n; - s = strlen((char *)bp) + 1; - hostPtr->name = Calloc(1, s); - memcpy(hostPtr->name, bp, s); - haveAnswer = TRUE; - break; - } else if (type != T_A) { - cp += dlen; - continue; - } - if (dlen != INADDRSZ) - return (ERROR); - if (haveAnswer) { - /* - * If we've already got 1 address, we aren't interested - * in addresses with a different length or class. - */ - if (dlen != hostPtr->addrLen) { - cp += dlen; - continue; - } - if (class != origClass) { - cp += dlen; - continue; - } - } else { - /* - * First address: record its length and class so we - * only save additonal ones with the same attributes. - */ - hostPtr->addrLen = dlen; - origClass = class; - hostPtr->addrType = (class == C_IN) ? AF_INET : AF_UNSPEC; - s = strlen((char *)bp) + 1; - hostPtr->name = Calloc(1, s); - memcpy(hostPtr->name, bp, s); - } - bp += (((u_int32_t)bp) % sizeof(align)); - - if (bp + dlen >= &hostbuf[sizeof(hostbuf)]) { - if (res.options & RES_DEBUG) { - printf("Size (%d) too big\n", dlen); - } - break; - } - if (numAddresses >= MAXADDRS) { - printf("MAXADDRS exceeded: skipping address\n"); - cp += dlen; - continue; - } - memcpy(*addrPtr++ = (char *)bp, cp, dlen); - bp += dlen; - cp += dlen; - numAddresses++; - haveAnswer = TRUE; - } - } - } - - if ((queryType == T_A || queryType == T_PTR) && haveAnswer) { - - /* - * Go through the alias and address lists and return them - * in the hostPtr variable. - */ - - if (numAliases > 0) { - hostPtr->aliases = - (char **) Calloc(1 + numAliases, sizeof(char *)); - for (i = 0; i < numAliases; i++) { - hostPtr->aliases[i] = Calloc(1, host_aliases_len[i]); - memcpy(hostPtr->aliases[i], host_aliases[i], - host_aliases_len[i]); - } - hostPtr->aliases[i] = NULL; - } - if (numAddresses > 0) { - hostPtr->addrList = - (char **)Calloc(1+numAddresses, sizeof(char *)); - for (i = 0; i < numAddresses; i++) { - hostPtr->addrList[i] = Calloc(1, hostPtr->addrLen); - memcpy(hostPtr->addrList[i], addr_list[i], hostPtr->addrLen); - } - hostPtr->addrList[i] = NULL; - } -#ifdef verbose - if (headerPtr->aa || nscount == 0) { - hostPtr->servers = NULL; - return (SUCCESS); - } -#else - hostPtr->servers = NULL; - return (SUCCESS); -#endif - } - - /* - * At this point, for the T_A query type, only empty answers remain. - * For other query types, additional information might be found - * in the additional resource records part. - */ - - if (!headerPtr->aa && (queryType != T_A) && (nscount > 0 || arcount > 0)) { - if (printedAnswers) { - putchar('\n'); - } - printf("Authoritative answers can be found from:\n"); - } - - cp = (u_char *)res_skip((char *) &answer, 2, eom); - - numServers = 0; - if (queryType != T_A) { - /* - * If we don't need to save the record, just print it. - */ - while (--nscount >= 0 && cp < eom) { - if ((cp = (u_char *)Print_rr(cp, - (u_char *) &answer, eom, stdout)) == NULL) { - return(ERROR); - } - } - } else { - while (--nscount >= 0 && cp < eom) { - /* - * Go through the NS records and retrieve the names of hosts - * that serve the requested domain. - */ - - n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen); - if (n < 0) { - return(ERROR); - } - cp += n; - s = strlen((char *)bp) + 1; - dnamePtr = Calloc(1, s); /* domain name */ - memcpy(dnamePtr, bp, s); - - if (cp + 3 * INT16SZ + INT32SZ > eom) - return (ERROR); - type = GetShort(cp); - class = GetShort(cp); - cp += INT32SZ; /* skip TTL */ - dlen = GetShort(cp); - if (cp + dlen > eom) - return (ERROR); - - if (type != T_NS) { - cp += dlen; - } else { - Boolean found; - - n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen); - if (n < 0) { - return(ERROR); - } - cp += n; - s = strlen((char *)bp) + 1; - namePtr = Calloc(1, s); /* server host name */ - memcpy(namePtr, bp, s); - - /* - * Store the information keyed by the server host name. - */ - found = FALSE; - for (j = 0; j < numServers; j++) { - if (strcmp(namePtr, server[j].name) == 0) { - found = TRUE; - free(namePtr); - break; - } - } - if (found) { - server[j].numDomains++; - if (server[j].numDomains <= MAXDOMAINS) { - server[j].domain[server[j].numDomains-1] = dnamePtr; - } - } else { - if (numServers >= MAXSERVERS) { - break; - } - server[numServers].name = namePtr; - server[numServers].domain[0] = dnamePtr; - server[numServers].numDomains = 1; - server[numServers].numAddresses = 0; - numServers++; - } - } - } - } - - /* - * Additional resource records contain addresses of servers. - */ - cp = (u_char *)res_skip((char *) &answer, 3, eom); - - if (queryType != T_A) { - /* - * If we don't need to save the record, just print it. - */ - while (--arcount >= 0 && cp < eom) { - if ((cp = (u_char *)Print_rr(cp, - (u_char *) &answer, eom, stdout)) == NULL) { - return(ERROR); - } - } - } else { - while (--arcount >= 0 && cp < eom) { - n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen); - if (n < 0) { - break; - } - cp += n; - if (cp + 3 * INT16SZ + INT32SZ > eom) - return (ERROR); - type = GetShort(cp); - class = GetShort(cp); - cp += INT32SZ; /* skip TTL */ - dlen = GetShort(cp); - if (cp + dlen > eom) - return (ERROR); - - if (type != T_A) { - cp += dlen; - continue; - } else { - if (dlen != INADDRSZ) - return (ERROR); - for (j = 0; j < numServers; j++) { - if (strcmp((char *)bp, server[j].name) == 0) { - server[j].numAddresses++; - if (server[j].numAddresses <= MAXADDRS) { - server[j].address[server[j].numAddresses-1] = - Calloc(1,dlen); - memcpy(server[j].address[server[j].numAddresses-1], - cp, dlen); - break; - } - } - } - cp += dlen; - } - } - } - - /* - * If we are returning name server info, transfer it to the hostPtr. - */ - if (numServers > 0) { - hostPtr->servers = (ServerInfo **) - Calloc(numServers+1, sizeof(ServerInfo *)); - - for (i = 0; i < numServers; i++) { - hostPtr->servers[i] = (ServerInfo *) Calloc(1, sizeof(ServerInfo)); - hostPtr->servers[i]->name = server[i].name; - - - hostPtr->servers[i]->domains = (char **) - Calloc(server[i].numDomains+1,sizeof(char *)); - for (j = 0; j < server[i].numDomains; j++) { - hostPtr->servers[i]->domains[j] = server[i].domain[j]; - } - hostPtr->servers[i]->domains[j] = NULL; - - - hostPtr->servers[i]->addrList = (char **) - Calloc(server[i].numAddresses+1,sizeof(char *)); - for (j = 0; j < server[i].numAddresses; j++) { - hostPtr->servers[i]->addrList[j] = server[i].address[j]; - } - hostPtr->servers[i]->addrList[j] = NULL; - - } - hostPtr->servers[i] = NULL; - } - - switch (queryType) { - case T_A: - return NONAUTH; - case T_PTR: - if (iquery) - return NO_INFO; - /* fall through */ - default: - return SUCCESS; - } -} - -/* -******************************************************************************* -* -* GetHostInfo -- -* -* Retrieves host name, address and alias information -* for a domain. -* -* Algorithm from res_nsearch(). -* -* Results: -* ERROR - res_nmkquery failed. -* + return values from GetAnswer() -* -******************************************************************************* -*/ - -int -GetHostInfoByName(nsAddrPtr, queryClass, queryType, name, hostPtr, isServer) - struct in_addr *nsAddrPtr; - int queryClass; - int queryType; - char *name; - HostInfo *hostPtr; - Boolean isServer; -{ - int n; - register int result; - register char **domain; - const char *cp; - Boolean got_nodata = FALSE; - struct in_addr ina; - Boolean tried_as_is = FALSE; - char tmp[NS_MAXDNAME]; - - /* Catch explicit addresses */ - if ((queryType == T_A) && IsAddr(name, &ina)) { - hostPtr->name = Calloc(strlen(name)+3, 1); - (void)sprintf(hostPtr->name,"[%s]",name); - hostPtr->aliases = NULL; - hostPtr->servers = NULL; - hostPtr->addrType = AF_INET; - hostPtr->addrLen = INADDRSZ; - hostPtr->addrList = (char **)Calloc(2, sizeof(char *)); - hostPtr->addrList[0] = Calloc(INT32SZ, sizeof(char)); - memcpy(hostPtr->addrList[0], &ina, INADDRSZ); - hostPtr->addrList[1] = NULL; - return(SUCCESS); - } - - result = NXDOMAIN; - for (cp = name, n = 0; *cp; cp++) - if (*cp == '.') - n++; - if (n == 0 && (cp = res_hostalias(&res, name, tmp, sizeof tmp))) { - printf("Aliased to \"%s\"\n\n", cp); - return (GetHostDomain(nsAddrPtr, queryClass, queryType, - cp, (char *)NULL, hostPtr, isServer)); - } - - /* - * If there are dots in the name already, let's just give it a try - * 'as is'. The threshold can be set with the "ndots" option. - */ - if (n >= (int)res.ndots) { - result = GetHostDomain(nsAddrPtr, queryClass, queryType, - name, (char *)NULL, hostPtr, isServer); - if (result == SUCCESS) - return (result); - if (result == NO_INFO) - got_nodata++; - tried_as_is++; - } - - /* - * We do at least one level of search if - * - there is no dot and RES_DEFNAME is set, or - * - there is at least one dot, there is no trailing dot, - * and RES_DNSRCH is set. - */ - if ((n == 0 && (res.options & RES_DEFNAMES) != 0) || - (n != 0 && *--cp != '.' && (res.options & RES_DNSRCH) != 0)) - for (domain = res.dnsrch; *domain != NULL; domain++) { - result = GetHostDomain(nsAddrPtr, queryClass, queryType, - name, *domain, hostPtr, isServer); - /* - * If no server present, give up. - * If name isn't found in this domain, - * keep trying higher domains in the search list - * (if that's enabled). - * On a NO_INFO error, keep trying, otherwise - * a wildcard entry of another type could keep us - * from finding this entry higher in the domain. - * If we get some other error (negative answer or - * server failure), then stop searching up, - * but try the input name below in case it's fully-qualified. - */ - if (result == SUCCESS || result == NO_RESPONSE) - return result; - if (result == NO_INFO) - got_nodata++; - if ((result != NXDOMAIN && result != NO_INFO) || - (res.options & RES_DNSRCH) == 0) - break; - } - /* if we have not already tried the name "as is", do that now. - * note that we do this regardless of how many dots were in the - * name or whether it ends with a dot. - */ - if (!tried_as_is && - (result = GetHostDomain(nsAddrPtr, queryClass, queryType, - name, (char *)NULL, hostPtr, isServer) - ) == SUCCESS) - return (result); - if (got_nodata) - result = NO_INFO; - return (result); -} - -/* - * Perform a query on the concatenation of name and domain, - * removing a trailing dot from name if domain is NULL. - */ -GetHostDomain(nsAddrPtr, queryClass, queryType, name, domain, hostPtr, isServer) - struct in_addr *nsAddrPtr; - int queryClass; - int queryType; - char *name, *domain; - HostInfo *hostPtr; - Boolean isServer; -{ - querybuf buf; - char nbuf[2*MAXDNAME+2]; - char *longname = nbuf; - int n; - - if (domain == NULL) { - /* - * Check for trailing '.'; - * copy without '.' if present. - */ - n = strlen(name) - 1; - if (name[n] == '.' && n < sizeof(nbuf) - 1) { - memcpy(nbuf, name, n); - nbuf[n] = '\0'; - } else - longname = name; - } else { - (void)sprintf(nbuf, "%.*s.%.*s", - MAXDNAME, name, MAXDNAME, domain); - longname = nbuf; - } - n = res_nmkquery(&res, QUERY, longname, queryClass, queryType, - NULL, 0, 0, buf.qb2, sizeof(buf)); - if (n < 0) { - if (res.options & RES_DEBUG) { - printf("Res_nmkquery failed\n"); - } - return (ERROR); - } - - n = GetAnswer(nsAddrPtr, queryType, (char *)&buf, n, 0, hostPtr, isServer); - - /* - * GetAnswer didn't find a name, so set it to the specified one. - */ - if (n == NONAUTH) { - if (hostPtr->name == NULL) { - size_t len = strlen(longname) + 1; - - hostPtr->name = Calloc(len, sizeof(char)); - memcpy(hostPtr->name, longname, len); - } - } - return(n); -} - - -/* -******************************************************************************* -* -* GetHostInfoByAddr -- -* -* Performs a PTR lookup in in-addr.arpa to find the host name -* that corresponds to the given address. -* -* Results: -* ERROR - res_nmkquery failed. -* + return values from GetAnswer() -* -******************************************************************************* -*/ - -int -GetHostInfoByAddr(nsAddrPtr, address, hostPtr) - struct in_addr *nsAddrPtr; - struct in_addr *address; - HostInfo *hostPtr; -{ - int n; - querybuf buf; - char qbuf[MAXDNAME]; - char *p = (char *) &address->s_addr; - - (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", - ((unsigned)p[3] & 0xff), - ((unsigned)p[2] & 0xff), - ((unsigned)p[1] & 0xff), - ((unsigned)p[0] & 0xff)); - n = res_nmkquery(&res, QUERY, qbuf, C_IN, T_PTR, NULL, 0, NULL, - buf.qb2, sizeof buf); - if (n < 0) { - if (res.options & RES_DEBUG) { - printf("res_nmkquery() failed\n"); - } - return (ERROR); - } - n = GetAnswer(nsAddrPtr, T_PTR, (char *) &buf, n, 1, hostPtr, 1); - if (n == SUCCESS) { - hostPtr->addrType = AF_INET; - hostPtr->addrLen = 4; - hostPtr->addrList = (char **)Calloc(2, sizeof(char *)); - hostPtr->addrList[0] = Calloc(INT32SZ, sizeof(char)); - memcpy(hostPtr->addrList[0], p, INADDRSZ); - hostPtr->addrList[1] = NULL; - } - return n; -} - -/* -******************************************************************************* -* -* FreeHostInfoPtr -- -* -* Deallocates all the calloc'd areas for a HostInfo variable. -* -******************************************************************************* -*/ - -void -FreeHostInfoPtr(hostPtr) - register HostInfo *hostPtr; -{ - int i, j; - - if (hostPtr->name != NULL) { - free(hostPtr->name); - hostPtr->name = NULL; - } - - if (hostPtr->aliases != NULL) { - i = 0; - while (hostPtr->aliases[i] != NULL) { - free(hostPtr->aliases[i]); - i++; - } - free((char *)hostPtr->aliases); - hostPtr->aliases = NULL; - } - - if (hostPtr->addrList != NULL) { - i = 0; - while (hostPtr->addrList[i] != NULL) { - free(hostPtr->addrList[i]); - i++; - } - free((char *)hostPtr->addrList); - hostPtr->addrList = NULL; - } - - if (hostPtr->servers != NULL) { - i = 0; - while (hostPtr->servers[i] != NULL) { - - if (hostPtr->servers[i]->name != NULL) { - free(hostPtr->servers[i]->name); - } - - if (hostPtr->servers[i]->domains != NULL) { - j = 0; - while (hostPtr->servers[i]->domains[j] != NULL) { - free(hostPtr->servers[i]->domains[j]); - j++; - } - free((char *)hostPtr->servers[i]->domains); - } - - if (hostPtr->servers[i]->addrList != NULL) { - j = 0; - while (hostPtr->servers[i]->addrList[j] != NULL) { - free(hostPtr->servers[i]->addrList[j]); - j++; - } - free((char *)hostPtr->servers[i]->addrList); - } - free((char *)hostPtr->servers[i]); - i++; - } - free((char *)hostPtr->servers); - hostPtr->servers = NULL; - } -} diff --git a/contrib/bind/bin/nslookup/list.c b/contrib/bind/bin/nslookup/list.c deleted file mode 100644 index db46d7f6da55a..0000000000000 --- a/contrib/bind/bin/nslookup/list.c +++ /dev/null @@ -1,650 +0,0 @@ -/* - * Copyright (c) 1985, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -static const char sccsid[] = "@(#)list.c 5.23 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: list.c,v 8.23 2000/03/30 23:25:34 vixie Exp $"; -#endif /* not lint */ - -/* - ******************************************************************************* - * - * list.c -- - * - * Routines to obtain info from name and finger servers. - * - * Adapted from 4.3BSD BIND ns_init.c and from finger.c. - * - ******************************************************************************* - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <netdb.h> -#include <resolv.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "port_after.h" - -#include "res.h" - -extern char *pager; - -typedef union { - HEADER qb1; - u_char qb2[PACKETSZ]; -} querybuf; - -extern HostInfo *defaultPtr; -extern HostInfo curHostInfo; -extern int curHostValid; -extern int queryType; -extern int queryClass; - -static int sockFD = -1; -int ListSubr(); - -/* - * During a listing to a file, hash marks are printed - * every HASH_SIZE records. - */ - -#define HASH_SIZE 50 - - -/* - ******************************************************************************* - * - * ListHosts -- - * ListHostsByType -- - * - * Requests the name server to do a zone transfer so we - * find out what hosts it knows about. - * - * For ListHosts, there are five types of output: - * - Internet addresses (default) - * - cpu type and operating system (-h option) - * - canonical and alias names (-a option) - * - well-known service names (-s option) - * - ALL records (-d option) - * ListHostsByType prints records of the default type or of a speicific - * type. - * - * To see all types of information sorted by name, do the following: - * ls -d domain.edu > file - * - * Results: - * SUCCESS the listing was successful. - * ERROR the server could not be contacted because - * a socket could not be obtained or an error - * occured while receiving, or the output file - * could not be opened. - * - ******************************************************************************* - */ - -void -ListHostsByType(char *string, int putToFile) { - char *namePtr, name[NAME_LEN], option[NAME_LEN]; - int i, j, qtype, result; - - /* - * Parse the command line. It maybe of the form "ls -t domain" - * or "ls -t type domain". - */ - - /* simulate sscanf(string, " ls -t %s %s", option, name) */ - i = matchString(" ls -t ", string); - if (i > 0) { - j = pickString(string + i, option, sizeof option); - if (j > 0) { - j = pickString(string + i + j, name, sizeof name); - if (j > 0) - i = 2; - else - i = 1; - } else { - i = 0; - } - } - - if (putToFile && i == 2 && name[0] == '>') - i--; - if (i == 2) { - qtype = StringToType(option, -1, stderr); - if (qtype == -1) - return; - namePtr = name; - } else if (i == 1) { - namePtr = option; - qtype = queryType; - } else { - fprintf(stderr, "*** ls: invalid request %s\n", string); - return; - } - result = ListSubr(qtype, namePtr, putToFile ? string : NULL); - if (result != SUCCESS) - fprintf(stderr, "*** Can't list domain %s: %s\n", - namePtr, DecodeError(result)); -} - -void -ListHosts(char *string, int putToFile) { - char *namePtr, name[NAME_LEN], option[NAME_LEN]; - int i, j, qtype, result; - - /* - * Parse the command line. It maybe of the form "ls domain", - * "ls -X domain". - */ - - /* simulate i = sscanf(string, " ls %s %s", option, name) */ - i = matchString(" ls ", string); - if (i > 0) { - j = pickString(string + i, option, sizeof option); - if (j > 0) { - j = pickString(string + i + j, name, sizeof name); - if (j > 0) - i = 2; - else - i = 1; - } else { - i = 0; - } - } - - if (putToFile && i == 2 && name[0] == '>') - i--; - if (i == 2) { - if (strcmp("-a", option) == 0) - qtype = T_CNAME; - else if (strcmp("-h", option) == 0) - qtype = T_HINFO; - else if (strcmp("-m", option) == 0) - qtype = T_MX; - else if (strcmp("-p", option) == 0) - qtype = T_PX; - else if (strcmp("-s", option) == 0) - qtype = T_WKS; - else if (strcmp("-d", option) == 0) - qtype = T_ANY; - else if (strcmp("-n", option) == 0) - qtype = T_NAPTR; - else - qtype = T_A; - namePtr = name; - } else if (i == 1) { - namePtr = option; - qtype = T_A; - } else { - fprintf(stderr, "*** ls: invalid request %s\n",string); - return; - } - result = ListSubr(qtype, namePtr, putToFile ? string : NULL); - if (result != SUCCESS) - fprintf(stderr, "*** Can't list domain %s: %s\n", - namePtr, DecodeError(result)); -} - -int -ListSubr(int qtype, char *domain, char *cmd) { - static u_char *answer = NULL; - static int answerLen = 0; - - ns_msg handle; - querybuf buf; - struct sockaddr_in sin; - HEADER *headerPtr; - int msglen, amtToRead, numRead, n, count, soacnt; - u_int len; - int numAnswers = 0; - int numRecords = 0; - u_char tmp[INT16SZ], *cp; - char soaname[2][NAME_LEN], file[PATH_MAX]; - enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING } - error = NO_ERRORS; - - /* - * Create a query packet for the requested domain name. - */ - msglen = res_nmkquery(&res, QUERY, domain, queryClass, T_AXFR, - NULL, 0, 0, buf.qb2, sizeof buf); - if (msglen < 0) { - if (_res.options & RES_DEBUG) - fprintf(stderr, "*** ls: res_nmkquery failed\n"); - return (ERROR); - } - - memset(&sin, 0, sizeof sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(nsport); - - /* - * Check to see if we have the address of the server or the - * address of a server who knows about this domain. - * - * For now, just use the first address in the list. XXX. - */ - - if (defaultPtr->addrList != NULL) - sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0]; - else - sin.sin_addr = *(struct in_addr *) - defaultPtr->servers[0]->addrList[0]; - - /* - * Set up a virtual circuit to the server. - */ - sockFD = socket(AF_INET, SOCK_STREAM, 0); - if (sockFD < 0) { - perror("ls: socket"); - return (ERROR); - } - if (connect(sockFD, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - int e; - - if (errno == ECONNREFUSED) - e = NO_RESPONSE; - else { - perror("ls: connect"); - e = ERROR; - } - (void) close(sockFD); - sockFD = -1; - return (e); - } - - /* - * Send length & message for zone transfer - */ - ns_put16(msglen, tmp); - if (write(sockFD, (char *)tmp, INT16SZ) != INT16SZ || - write(sockFD, (char *)buf.qb2, msglen) != msglen) { - perror("ls: write"); - (void) close(sockFD); - sockFD = -1; - return(ERROR); - } - - fprintf(stdout,"[%s]\n", (defaultPtr->addrList != NULL) - ? defaultPtr->name : defaultPtr->servers[0]->name); - - if (cmd == NULL) { - filePtr = stdout; - } else { - filePtr = OpenFile(cmd, file, sizeof file); - if (filePtr == NULL) { - fprintf(stderr, "*** Can't open %s for writing\n", - file); - (void) close(sockFD); - sockFD = -1; - return (ERROR); - } - fprintf(filePtr, "> %s\n", cmd); - fprintf(filePtr, "[%s]\n", (defaultPtr->addrList != NULL) - ? defaultPtr->name : defaultPtr->servers[0]->name); - } - - soacnt = 0; - while (soacnt < 2) { - /* - * Read the length of the response. - */ - - cp = tmp; amtToRead = INT16SZ; - while (amtToRead > 0 && - (numRead = read(sockFD, cp, amtToRead)) > 0) { - cp += numRead; - amtToRead -= numRead; - } - if (numRead <= 0) { - error = ERR_READING_LEN; - break; - } - - len = ns_get16(tmp); - if (len == 0) - break; /* nothing left to read */ - - /* - * If the server sent too much data to fit the existing - * buffer, allocate a new one. - */ - if (len > (u_int)answerLen) { - if (answerLen != 0) - free(answer); - answerLen = len; - answer = (u_char *)Malloc(answerLen); - } - - /* - * Read the response. - */ - amtToRead = len; cp = answer; - while (amtToRead > 0 && - (numRead = read(sockFD, cp, amtToRead)) > 0) { - cp += numRead; - amtToRead -= numRead; - } - if (numRead <= 0) { - error = ERR_READING_MSG; - break; - } - - if (ns_initparse(answer, cp - answer, &handle) < 0) { - perror("ns_initparse"); - error = ERR_PRINTING; - break; - } - if (ns_msg_getflag(handle, ns_f_rcode) != ns_r_noerror || - ns_msg_count(handle, ns_s_an) == 0) { - /* Signalled protocol error, or empty message. */ - error = ERR_PRINTING; - break; - } - - for (;;) { - static char origin[NS_MAXDNAME], name_ctx[NS_MAXDNAME]; - const char *name; - char buf[2048]; /* XXX need to malloc/realloc. */ - ns_rr rr; - - if (ns_parserr(&handle, ns_s_an, -1, &rr)) { - if (errno != ENODEV) { - perror("ns_parserr"); - error = ERR_PRINTING; - } - break; - } - name = ns_rr_name(rr); - if (origin[0] == '\0' && name[0] != '\0') { - if (strcmp(name, ".") != 0) - strcpy(origin, name); - fprintf(filePtr, "$ORIGIN %s.\n", origin); - if (strcmp(name, ".") == 0) - strcpy(origin, name); - strcpy(name_ctx, "@"); - } - if (qtype == T_ANY || ns_rr_type(rr) == qtype) { - if (ns_sprintrr(&handle, &rr, name_ctx, origin, - buf, sizeof buf) < 0) { - perror("ns_sprintrr"); - error = ERR_PRINTING; - break; - } - strcpy(name_ctx, name); - numRecords++; - fputs(buf, filePtr); - fputc('\n', filePtr); - } - if (ns_rr_type(rr) == T_SOA) { - strcpy(soaname[soacnt], name); - if (soacnt == 0) - soacnt = 1; - else if (ns_samename(soaname[0], - soaname[1]) == 1) { - soacnt = 2; - /* This means we're finished. - * But we've to reset origin and - * name_ctx now ! */ - origin[0] = name_ctx[0] ='\0'; - } - } - } - if (error != NO_ERRORS) - break; - numAnswers++; - if (cmd != NULL && ((numAnswers % HASH_SIZE) == 0)) { - fprintf(stdout, "#"); - fflush(stdout); - } - } - - if (cmd != NULL) - fprintf(stdout, "%sReceived %d answer%s (%d record%s).\n", - (numAnswers >= HASH_SIZE) ? "\n" : "", - numAnswers, (numAnswers != 1) ? "s" : "", - numRecords, (numRecords != 1) ? "s" : ""); - - (void) close(sockFD); - sockFD = -1; - if (cmd != NULL && filePtr != NULL) { - fclose(filePtr); - filePtr = NULL; - } - - switch (error) { - case NO_ERRORS: - return (SUCCESS); - - case ERR_READING_LEN: - return (ERROR); - - case ERR_PRINTING: - return (ERROR); - - case ERR_READING_MSG: - headerPtr = (HEADER *) answer; - fprintf(stderr,"*** ls: error receiving zone transfer:\n"); - fprintf(stderr, - " result: %s, answers = %d, authority = %d, additional = %d\n", - p_rcode(headerPtr->rcode), - ntohs(headerPtr->ancount), ntohs(headerPtr->nscount), - ntohs(headerPtr->arcount)); - return (ERROR); - default: - return (ERROR); - } -} - -/* - ******************************************************************************* - * - * Finger -- - * - * Connects with the finger server for the current host - * to request info on the specified person (long form) - * who is on the system (short form). - * - * Results: - * SUCCESS the finger server was contacted. - * ERROR the server could not be contacted because - * a socket could not be obtained or connected - * to or the service could not be found. - * - ******************************************************************************* - */ - -Finger(string, putToFile) - char *string; - int putToFile; -{ - struct servent *sp; - struct sockaddr_in sin; - FILE *f; - int c; - int lastc; - char name[NAME_LEN]; - char file[PATH_MAX]; - int i; - - /* - * We need a valid current host info to get an inet address. - */ - if (!curHostValid) { - fprintf(stderr, "Finger: no current host defined.\n"); - return (ERROR); - } - - /* simulate: sscanf("finger %s") ; */ - - i = matchString(" finger ", string); - if (i > 0) { - i = pickString(string + i, name, sizeof name); - if (i > 0) { - i = 1 ; - } - /* note that if the argument to the finger command is - bigger than sizeof name it will be treated as if there - was no argument. */ - } - - if (i == 1) { - if (putToFile && (name[0] == '>')) { - name[0] = '\0'; - } - } else { - name[0] = '\0'; - } - - sp = getservbyname("finger", "tcp"); - if (sp == 0) { - fprintf(stderr, "Finger: unknown service\n"); - return (ERROR); - } - - memset(&sin, 0, sizeof sin); - sin.sin_family = curHostInfo.addrType; - sin.sin_port = sp->s_port; - memcpy(&sin.sin_addr, curHostInfo.addrList[0], curHostInfo.addrLen); - - /* - * Set up a virtual circuit to the host. - */ - - sockFD = socket(curHostInfo.addrType, SOCK_STREAM, 0); - if (sockFD < 0) { - fflush(stdout); - perror("finger: socket"); - return (ERROR); - } - - if (connect(sockFD, (struct sockaddr *)&sin, sizeof (sin)) < 0) { - fflush(stdout); - perror("finger: connect"); - close(sockFD); - sockFD = -1; - return (ERROR); - } - - if (!putToFile) { - filePtr = stdout; - } else { - filePtr = OpenFile(string, file, sizeof file); - if (filePtr == NULL) { - fprintf(stderr, "*** Can't open %s for writing\n", file); - close(sockFD); - sockFD = -1; - return(ERROR); - } - fprintf(filePtr,"> %s\n", string); - } - fprintf(filePtr, "[%s]\n", curHostInfo.name); - - if (name[0] != '\0') { - write(sockFD, "/W ", 3); - } - write(sockFD, name, strlen(name)); - write(sockFD, "\r\n", 2); - f = fdopen(sockFD, "r"); - lastc = '\n'; - while ((c = getc(f)) != EOF) { - switch (c) { - case 0210: - case 0211: - case 0212: - case 0214: - c -= 0200; - break; - case 0215: - c = '\n'; - break; - } - putc(lastc = c, filePtr); - } - if (lastc != '\n') { - putc('\n', filePtr); - } - putc('\n', filePtr); - - close(sockFD); - sockFD = -1; - - if (putToFile) { - fclose(filePtr); - filePtr = NULL; - } - return (SUCCESS); -} - -void -ListHost_close() -{ - if (sockFD != -1) { - (void) close(sockFD); - sockFD = -1; - } -} diff --git a/contrib/bind/bin/nslookup/main.c b/contrib/bind/bin/nslookup/main.c deleted file mode 100644 index f78d9273cd1f2..0000000000000 --- a/contrib/bind/bin/nslookup/main.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * Copyright (c) 1985, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -char copyright[] = -"@(#) Copyright (c) 1985,1989 Regents of the University of California.\n\ - All rights reserved.\n\ - @(#) Portions Copyright (c) 1996-1999 Internet Software Consortium.\n"; -#endif /* not lint */ - -#ifndef lint -static const char sccsid[] = "@(#)main.c 5.42 (Berkeley) 3/3/91"; -static const char rcsid[] = "$Id: main.c,v 8.14 2000/03/30 23:25:34 vixie Exp $"; -#endif /* not lint */ - -/* - ****************************************************************************** - * - * main.c -- - * - * Main routine and some action routines for the name server - * lookup program. - * - * Andrew Cherenson - * U.C. Berkeley Computer Science Div. - * CS298-26, Fall 1985 - * - ****************************************************************************** - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <netdb.h> -#include <resolv.h> -#include <setjmp.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "port_after.h" - -#include "res.h" -#include "pathnames.h" - -/* - * Name of a top-level name server. Can be changed with - * the "set root" command. - */ - -#ifndef ROOT_SERVER -#define ROOT_SERVER "a.root-servers.net." -#endif -char rootServerName[NAME_LEN] = ROOT_SERVER; - -/* - * Declare a resolver context. - */ - -struct __res_state res; - - -/* - * Info about the most recently queried host. - */ - -HostInfo curHostInfo; -int curHostValid = FALSE; - - -/* - * Info about the default name server. - */ - -HostInfo *defaultPtr = NULL; -char defaultServer[NAME_LEN]; -struct in_addr defaultAddr; - - -/* - * Initial name server query type is Address. - */ - -int queryType = T_A; -int queryClass = C_IN; - -/* - * Stuff for Interrupt (control-C) signal handler. - */ - -extern SIG_FN IntrHandler(); -FILE *filePtr; -jmp_buf env; - - -/* - * Browser command for help. - */ -char *pager; - -static void CvtAddrToPtr(); -static void ReadRC(); - -/* - * Forward declarations. - */ -void LocalServer(HostInfo *defaultPtr); -void res_re_init(void); -void res_dnsrch(char *cp); - - -/* - ****************************************************************************** - * - * main -- - * - * Initializes the resolver library and determines the address - * of the initial name server. The yylex routine is used to - * read and perform commands. - * - ****************************************************************************** - */ - -main(argc, argv) - int argc; - char **argv; -{ - char *wantedHost = NULL; - Boolean useLocalServer; - int result; - int i; - struct hostent *hp; - - /* - * Initialize the resolver library routines. - */ - - if (res_ninit(&res) == -1) { - fprintf(stderr,"*** Can't initialize resolver.\n"); - exit(1); - } - - /* - * Allocate space for the default server's host info and - * find the server's address and name. If the resolver library - * already has some addresses for a potential name server, - * then use them. Otherwise, see if the current host has a server. - * Command line arguments may override the choice of initial server. - */ - - defaultPtr = (HostInfo *) Calloc(1, sizeof(HostInfo)); - - /* - * Parse the arguments: - * no args = go into interactive mode, use default host as server - * 1 arg = use as host name to be looked up, default host will be server - * non-interactive mode - * 2 args = 1st arg: - * if it is '-', then - * ignore but go into interactive mode - * else - * use as host name to be looked up, - * go into non-interactive mode - * 2nd arg: name or inet address of server - * - * "Set" options are specified with a leading - and must come before - * any arguments. For example, to find the well-known services for - * a host, type "nslookup -query=wks host" - */ - - ReadRC(); /* look for options file */ - - ++argv; --argc; /* skip prog name */ - - while (argc && *argv[0] == '-' && argv[0][1]) { - (void) SetOption (&(argv[0][1])); - ++argv; --argc; - } - if (argc > 2) { - Usage(); - } - if (argc && *argv[0] != '-') { - wantedHost = *argv; /* name of host to be looked up */ - } - - useLocalServer = FALSE; - if (argc == 2) { - struct in_addr addr; - - /* - * Use an explicit name server. If the hostname lookup fails, - * default to the server(s) in resolv.conf. - */ - - if (inet_aton(*++argv, &addr)) { - res.nscount = 1; - res.nsaddr.sin_addr = addr; - } else { - hp = gethostbyname(*argv); - if (hp == NULL) { - fprintf(stderr, "*** Can't find server address for '%s': ", - *argv); - herror((char *)NULL); - fputc('\n', stderr); - } else { - for (i = 0; i < MAXNS && hp->h_addr_list[i] != NULL; i++) { - memcpy(&res.nsaddr_list[i].sin_addr, hp->h_addr_list[i], - hp->h_length); - } - res.nscount = i; - } - } - } - - - if (res.nscount == 0 || useLocalServer) { - LocalServer(defaultPtr); - } else { - for (i = 0; i < res.nscount; i++) { - if (res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) { - LocalServer(defaultPtr); - break; - } else { - result = GetHostInfoByAddr(&(res.nsaddr_list[i].sin_addr), - &(res.nsaddr_list[i].sin_addr), - defaultPtr); - if (result != SUCCESS) { - fprintf(stderr, - "*** Can't find server name for address %s: %s\n", - inet_ntoa(res.nsaddr_list[i].sin_addr), - DecodeError(result)); - } else { - defaultAddr = res.nsaddr_list[i].sin_addr; - break; - } - } - } - - /* - * If we have exhausted the list, tell the user about the - * command line argument to specify an address. - */ - - if (i == res.nscount) { - fprintf(stderr, "*** Default servers are not available\n"); - exit(1); - } - - } - strcpy(defaultServer, defaultPtr->name); - - -#ifdef DEBUG -#ifdef DEBUG2 - res.options |= RES_DEBUG2; -#endif - res.options |= RES_DEBUG; - res.retry = 2; -#endif /* DEBUG */ - - /* - * If we're in non-interactive mode, look up the wanted host and quit. - * Otherwise, print the initial server's name and continue with - * the initialization. - */ - - if (wantedHost != (char *) NULL) { - LookupHost(wantedHost, 0); - } else { - PrintHostInfo(stdout, "Default Server:", defaultPtr); - - pager = getenv("PAGER"); - if (pager == NULL) { - pager = _PATH_PAGERCMD; - } - - /* - * Setup the environment to allow the interrupt handler to return here. - */ - - (void) setjmp(env); - - /* - * Return here after a longjmp. - */ - - signal(SIGINT, IntrHandler); - signal(SIGPIPE, SIG_IGN); - - /* - * Read and evaluate commands. The commands are described in commands.l - * Yylex returns 0 when ^D or 'exit' is typed. - */ - - printf("> "); - fflush(stdout); - while(yylex()) { - printf("> "); - fflush(stdout); - } - } - exit(0); -} - - -void -LocalServer(defaultPtr) - HostInfo *defaultPtr; -{ - char hostName[NAME_LEN]; - - (void) gethostname(hostName, sizeof(hostName)); - - defaultAddr.s_addr = htonl(INADDR_ANY); - (void) GetHostInfoByName(&defaultAddr, C_IN, T_A, - "0.0.0.0", defaultPtr, 1); - free(defaultPtr->name); - defaultPtr->name = Calloc(1, sizeof(hostName)+1); - strcpy(defaultPtr->name, hostName); -} - - -/* - ****************************************************************************** - * - * Usage -- - * - * Lists the proper methods to run the program and exits. - * - ****************************************************************************** - */ - -Usage() -{ - fprintf(stderr, "Usage:\n"); - fprintf(stderr, -" nslookup [-opt ...] # interactive mode using default server\n"); - fprintf(stderr, -" nslookup [-opt ...] - server # interactive mode using 'server'\n"); - fprintf(stderr, -" nslookup [-opt ...] host # just look up 'host' using default server\n"); - fprintf(stderr, -" nslookup [-opt ...] host server # just look up 'host' using 'server'\n"); - exit(1); -} - -/* - ****************************************************************************** - * - * IsAddr -- - * - * Returns TRUE if the string looks like an Internet address. - * A string with a trailing dot is not an address, even if it looks - * like one. - * - ****************************************************************************** - */ - -Boolean -IsAddr(host, addrPtr) - char *host; - struct in_addr *addrPtr; /* If return TRUE, contains IP address */ -{ - register char *cp; - - if (isdigit(host[0])) { - /* Make sure it has only digits and dots. */ - for (cp = host; *cp; ++cp) { - if (!isdigit(*cp) && *cp != '.') - return FALSE; - } - /* If it has a trailing dot, don't treat it as an address. */ - if (*--cp != '.') { - return inet_aton(host, addrPtr); - } - } - return FALSE; -} - - -/* - ****************************************************************************** - * - * SetDefaultServer -- - * - * Changes the default name server to the one specified by - * the first argument. The command "server name" uses the current - * default server to lookup the info for "name". The command - * "lserver name" uses the original server to lookup "name". - * - * Side effects: - * This routine will cause a core dump if the allocation requests fail. - * - * Results: - * SUCCESS The default server was changed successfully. - * NONAUTH The server was changed but addresses of - * other servers who know about the requested server - * were returned. - * Errors No info about the new server was found or - * requests to the current server timed-out. - * - ****************************************************************************** - */ - -int -SetDefaultServer(string, local) - char *string; - Boolean local; -{ - register HostInfo *newDefPtr; - struct in_addr *servAddrPtr; - struct in_addr addr; - char newServer[NAME_LEN]; - int result; - int i; - int j; - - /* - * Parse the command line. It maybe of the form "server name", - * "lserver name" or just "name". - */ - - if (local) { - i = matchString (" lserver ", string); - if (i > 0) { - j = pickString(string + i, newServer, sizeof newServer); - if (j == 0) { /* value was too big for newServer variable */ - fprintf(stderr, - "SetDefaultServer: invalid name: %s\n", - string + i); - return(ERROR); - } - } - } else { - i = matchString(" server ", string); - if (i > 0) { - j = pickString(string + i, newServer, sizeof newServer); - if (j == 0) { /* value was too big for newServer variable */ - fprintf(stderr, - "SetDefaultServer: invalid name: %s\n", - string + i); - return(ERROR); - } - } - } - - if (i == 0) { - i = pickString(string, newServer, sizeof newServer); - if (i == 0) { /* value was too big for newServer variable */ - fprintf(stderr,"SetDefaultServer: invalid name: %s\n", string); - return(ERROR); - } - } - - /* - * Allocate space for a HostInfo variable for the new server. Don't - * overwrite the old HostInfo struct because info about the new server - * might not be found and we need to have valid default server info. - */ - - newDefPtr = (HostInfo *) Calloc(1, sizeof(HostInfo)); - - - /* - * A 'local' lookup uses the original server that the program was - * initialized with. - * - * Check to see if we have the address of the server or the - * address of a server who knows about this domain. - * XXX For now, just use the first address in the list. - */ - - if (local) { - servAddrPtr = &defaultAddr; - } else if (defaultPtr->addrList != NULL) { - servAddrPtr = (struct in_addr *) defaultPtr->addrList[0]; - } else { - servAddrPtr = (struct in_addr *) defaultPtr->servers[0]->addrList[0]; - } - - result = ERROR; - if (IsAddr(newServer, &addr)) { - result = GetHostInfoByAddr(servAddrPtr, &addr, newDefPtr); - /* If we can't get the name, fall through... */ - } - if (result != SUCCESS && result != NONAUTH) { - result = GetHostInfoByName(servAddrPtr, C_IN, T_A, - newServer, newDefPtr, 1); - } - - /* If we ask for an A record and get none back, but get an NS - record for the NS server, this is the NONAUTH case. - We must check whether we got an IP address for the NS - server or not. */ - if ((result == SUCCESS || result == NONAUTH) && - ((newDefPtr->addrList && newDefPtr->addrList[0] != 0) || - (newDefPtr->servers && newDefPtr->servers[0] && - newDefPtr->servers[0]->addrList[0] != 0))) { - /* - * Found info about the new server. Free the resources for - * the old server. - */ - - FreeHostInfoPtr(defaultPtr); - free((char *)defaultPtr); - defaultPtr = newDefPtr; - strcpy(defaultServer, defaultPtr->name); - PrintHostInfo(stdout, "Default Server:", defaultPtr); - return(SUCCESS); - } else { - fprintf(stderr, "*** Can't find address for server %s: %s\n", - newServer, DecodeError(result)); - free((char *)newDefPtr); - - return(result); - } -} - -/* - ****************************************************************************** - * - * DoLoookup -- - * - * Common subroutine for LookupHost and LookupHostWithServer. - * - * Results: - * SUCCESS - the lookup was successful. - * Misc. Errors - an error message is printed if the lookup failed. - * - ****************************************************************************** - */ - -static int -DoLookup(host, servPtr, serverName) - char *host; - HostInfo *servPtr; - char *serverName; -{ - int result; - struct in_addr *servAddrPtr; - struct in_addr addr; - - /* Skip escape character */ - if (host[0] == '\\') - host++; - - /* - * If the user gives us an address for an address query, - * silently treat it as a PTR query. If the query type is already - * PTR, then convert the address into the in-addr.arpa format. - * - * Use the address of the server if it exists, otherwise use the - * address of a server who knows about this domain. - * XXX For now, just use the first address in the list. - */ - - if (servPtr->addrList != NULL) { - servAddrPtr = (struct in_addr *) servPtr->addrList[0]; - } else { - servAddrPtr = (struct in_addr *) servPtr->servers[0]->addrList[0]; - } - - /* - * RFC1123 says we "SHOULD check the string syntactically for a - * dotted-decimal number before looking it up [...]" (p. 13). - */ - if (queryType == T_A && IsAddr(host, &addr)) { - result = GetHostInfoByAddr(servAddrPtr, &addr, &curHostInfo); - } else { - if (queryType == T_PTR) { - CvtAddrToPtr(host); - } - result = GetHostInfoByName(servAddrPtr, queryClass, queryType, host, - &curHostInfo, 0); - } - - switch (result) { - case SUCCESS: - /* - * If the query was for an address, then the &curHostInfo - * variable can be used by Finger. - * There's no need to print anything for other query types - * because the info has already been printed. - */ - if (queryType == T_A) { - curHostValid = TRUE; - PrintHostInfo(filePtr, "Name:", &curHostInfo); - } - break; - - /* - * No Authoritative answer was available but we got names - * of servers who know about the host. - */ - case NONAUTH: - PrintHostInfo(filePtr, "Name:", &curHostInfo); - break; - - case NO_INFO: - fprintf(stderr, "*** No %s (%s) records available for %s\n", - DecodeType(queryType), p_type(queryType), host); - break; - - case TIME_OUT: - fprintf(stderr, "*** Request to %s timed-out\n", serverName); - break; - - default: - fprintf(stderr, "*** %s can't find %s: %s\n", serverName, host, - DecodeError(result)); - } - return result; -} - -/* - ****************************************************************************** - * - * LookupHost -- - * - * Asks the default name server for information about the - * specified host or domain. The information is printed - * if the lookup was successful. - * - * Results: - * ERROR - the output file could not be opened. - * + results of DoLookup - * - ****************************************************************************** - */ - -int -LookupHost(string, putToFile) - char *string; - Boolean putToFile; -{ - char host[NAME_LEN]; - char file[PATH_MAX]; - int result; - int i; - - /* - * Invalidate the current host information to prevent Finger - * from using bogus info. - */ - - curHostValid = FALSE; - - /* - * Parse the command string into the host and - * optional output file name. - * - */ - - i = pickString(string, host, sizeof host); - if (i == 0) { /* string was too long for host variable */ - fprintf(stderr, "*** invalid name: %s\n", string); - return(ERROR); - } - - if (!putToFile) { - filePtr = stdout; - } else { - filePtr = OpenFile(string, file, sizeof file); - if (filePtr == NULL) { - fprintf(stderr, "*** Can't open %s for writing\n", file); - return(ERROR); - } - fprintf(filePtr,"> %s\n", string); - } - - PrintHostInfo(filePtr, "Server:", defaultPtr); - - result = DoLookup(host, defaultPtr, defaultServer); - - if (putToFile) { - fclose(filePtr); - filePtr = NULL; - } - return(result); -} - -/* - ****************************************************************************** - * - * LookupHostWithServer -- - * - * Asks the name server specified in the second argument for - * information about the host or domain specified in the first - * argument. The information is printed if the lookup was successful. - * - * Address info about the requested name server is obtained - * from the default name server. This routine will return an - * error if the default server doesn't have info about the - * requested server. Thus an error return status might not - * mean the requested name server doesn't have info about the - * requested host. - * - * Comments from LookupHost apply here, too. - * - * Results: - * ERROR - the output file could not be opened. - * + results of DoLookup - * - ****************************************************************************** - */ - -int -LookupHostWithServer(string, putToFile) - char *string; - Boolean putToFile; -{ - char file[PATH_MAX]; - char host[NAME_LEN]; - char server[NAME_LEN]; - int result; - static HostInfo serverInfo; - int i; - int j; - - curHostValid = FALSE; - - i = pickString(string, host, sizeof host); - if (i == 0) { /* value was too big for host variable */ - fprintf(stderr, "*** invalid name: %s\n", string); - return(ERROR); - } - - j = pickString(string + i, server, sizeof server); - if (j == 0) { /* value was too big for server variable */ - fprintf(stderr, "*** invalid server name: %s\n", string + i); - return(ERROR); - } - - if (!putToFile) { - filePtr = stdout; - } else { - filePtr = OpenFile(string, file, sizeof file); - if (filePtr == NULL) { - fprintf(stderr, "*** Can't open %s for writing\n", file); - return(ERROR); - } - fprintf(filePtr,"> %s\n", string); - } - - result = GetHostInfoByName( - defaultPtr->addrList ? - (struct in_addr *) defaultPtr->addrList[0] : - (struct in_addr *) defaultPtr->servers[0]->addrList[0], - C_IN, T_A, server, &serverInfo, 1); - - if (result != SUCCESS) { - fprintf(stderr,"*** Can't find address for server %s: %s\n", server, - DecodeError(result)); - } else { - PrintHostInfo(filePtr, "Server:", &serverInfo); - - result = DoLookup(host, &serverInfo, server); - } - if (putToFile) { - fclose(filePtr); - filePtr = NULL; - } - return(result); -} - -/* - ****************************************************************************** - * - * SetOption -- - * - * This routine is used to change the state information - * that affect the lookups. The command format is - * set keyword[=value] - * Most keywords can be abbreviated. Parsing is very simplistic-- - * A value must not be separated from its keyword by white space. - * - * Valid keywords: Meaning: - * all lists current values of options. - * ALL lists current values of options, including - * hidden options. - * [no]d2 turn on/off extra debugging mode. - * [no]debug turn on/off debugging mode. - * [no]defname use/don't use default domain name. - * [no]search use/don't use domain search list. - * domain=NAME set default domain name to NAME. - * [no]ignore ignore/don't ignore trunc. errors. - * query=value set default query type to value, - * value is one of the query types in RFC883 - * without the leading T_. (e.g., A, HINFO) - * [no]recurse use/don't use recursive lookup. - * retry=# set number of retries to #. - * root=NAME change root server to NAME. - * time=# set timeout length to #. - * [no]vc use/don't use virtual circuit. - * port TCP/UDP port to server. - * - * Deprecated: - * [no]primary use/don't use primary server. - * - * Results: - * SUCCESS the command was parsed correctly. - * ERROR the command was not parsed correctly. - * - ****************************************************************************** - */ - -int -SetOption(option) - register char *option; -{ - char type[NAME_LEN]; - char *ptr; - int tmp; - int i; - - while (isspace(*option)) - ++option; - if (strncmp (option, "set ", 4) == 0) - option += 4; - while (isspace(*option)) - ++option; - - if (*option == 0) { - fprintf(stderr, "*** Invalid set command\n"); - return(ERROR); - } else { - if (strncmp(option, "all", 3) == 0) { - ShowOptions(); - } else if (strncmp(option, "ALL", 3) == 0) { - ShowOptions(); - } else if (strncmp(option, "d2", 2) == 0) { /* d2 (more debug) */ - res.options |= (RES_DEBUG | RES_DEBUG2); - } else if (strncmp(option, "nod2", 4) == 0) { - res.options &= ~RES_DEBUG2; - printf("d2 mode disabled; still in debug mode\n"); - } else if (strncmp(option, "def", 3) == 0) { /* defname */ - res.options |= RES_DEFNAMES; - } else if (strncmp(option, "nodef", 5) == 0) { - res.options &= ~RES_DEFNAMES; - } else if (strncmp(option, "do", 2) == 0) { /* domain */ - ptr = strchr(option, '='); - if (ptr != NULL) { - i = pickString(++ptr, res.defdname, sizeof res.defdname); - if (i == 0) { /* name too long or nothing there */ - fprintf(stderr, "** invalid 'domain' value: %s\n", - ptr) ; - return(ERROR); - } - - res_re_init(); - } - } else if (strncmp(option, "deb", 1) == 0) { /* debug */ - res.options |= RES_DEBUG; - } else if (strncmp(option, "nodeb", 5) == 0) { - res.options &= ~(RES_DEBUG | RES_DEBUG2); - } else if (strncmp(option, "ig", 2) == 0) { /* ignore */ - res.options |= RES_IGNTC; - } else if (strncmp(option, "noig", 4) == 0) { - res.options &= ~RES_IGNTC; - } else if (strncmp(option, "po", 2) == 0) { /* port */ - ptr = strchr(option, '='); - if (ptr != NULL) { - sscanf(++ptr, "%hu", &nsport); - } -#ifdef deprecated - } else if (strncmp(option, "pri", 3) == 0) { /* primary */ - res.options |= RES_PRIMARY; - } else if (strncmp(option, "nopri", 5) == 0) { - res.options &= ~RES_PRIMARY; -#endif - } else if (strncmp(option, "q", 1) == 0 || /* querytype */ - strncmp(option, "ty", 2) == 0) { /* type */ - ptr = strchr(option, '='); - if (ptr != NULL) { - i = pickString(++ptr, type, sizeof type); - if (i == 0) { /* value too big or nothing there */ - fprintf(stderr, "*** invalid type value: %s\n", - ptr) ; - return(ERROR); - } - - queryType = StringToType(type, queryType, stderr); - } - } else if (strncmp(option, "cl", 2) == 0) { /* query class */ - ptr = strchr(option, '='); - if (ptr != NULL) { - i = pickString(++ptr, type, sizeof type); - if (i == 0) { /* value too big or nothing there */ - fprintf(stderr, "*** invalid class : %s\n", - ptr) ; - return(ERROR); - } - - queryClass = StringToClass(type, queryClass, stderr); - } - } else if (strncmp(option, "rec", 3) == 0) { /* recurse */ - res.options |= RES_RECURSE; - } else if (strncmp(option, "norec", 5) == 0) { - res.options &= ~RES_RECURSE; - } else if (strncmp(option, "ret", 3) == 0) { /* retry */ - ptr = strchr(option, '='); - if (ptr != NULL) { - sscanf(++ptr, "%d", &tmp); - if (tmp >= 0) { - res.retry = tmp; - } - } - } else if (strncmp(option, "ro", 2) == 0) { /* root */ - ptr = strchr(option, '='); - if (ptr != NULL) { - i = pickString(++ptr, rootServerName, sizeof rootServerName); - if (i == 0) { /* value too big or nothing there */ - fprintf(stderr, "*** invalid root server name : %s\n", - ptr) ; - return(ERROR) ; - } - } - } else if (strncmp(option, "sea", 3) == 0) { /* search list */ - res.options |= RES_DNSRCH; - } else if (strncmp(option, "nosea", 5) == 0) { - res.options &= ~RES_DNSRCH; - } else if (strncmp(option, "srchl", 5) == 0) { /* domain search list */ - ptr = strchr(option, '='); - if (ptr != NULL) { - res_dnsrch(++ptr); - } - } else if (strncmp(option, "ti", 2) == 0) { /* timeout */ - ptr = strchr(option, '='); - if (ptr != NULL) { - sscanf(++ptr, "%d", &tmp); - if (tmp >= 0) { - res.retrans = tmp; - } - } - } else if (strncmp(option, "v", 1) == 0) { /* vc */ - res.options |= RES_USEVC; - } else if (strncmp(option, "nov", 3) == 0) { - res.options &= ~RES_USEVC; - } else { - fprintf(stderr, "*** Invalid option: %s\n", option); - return(ERROR); - } - } - return(SUCCESS); -} - -/* - * Fake a reinitialization when the domain is changed. - */ -void -res_re_init(void) { - register char *cp, **pp; - int n; - - /* find components of local domain that might be searched */ - pp = res.dnsrch; - *pp++ = res.defdname; - for (cp = res.defdname, n = 0; *cp; cp++) - if (*cp == '.') - n++; - cp = res.defdname; - for (; n >= LOCALDOMAINPARTS && pp < res.dnsrch + MAXDFLSRCH; n--) { - cp = strchr(cp, '.'); - *pp++ = ++cp; - } - *pp = 0; - res.options |= RES_INIT; -} - -#define SRCHLIST_SEP '/' - -void -res_dnsrch(char *cp) { - char **pp; - int n; - - (void)strncpy(res.defdname, cp, sizeof(res.defdname) - 1); - res.defdname[sizeof(res.defdname) - 1] = '\0'; - if ((cp = strchr(res.defdname, '\n')) != NULL) - *cp = '\0'; - /* - * Set search list to be blank-separated strings - * on rest of line. - */ - cp = res.defdname; - pp = res.dnsrch; - *pp++ = cp; - for (n = 0; *cp && pp < res.dnsrch + MAXDNSRCH; cp++) { - if (*cp == SRCHLIST_SEP) { - *cp = '\0'; - n = 1; - } else if (n) { - *pp++ = cp; - n = 0; - } - } - if ((cp = strchr(pp[-1], SRCHLIST_SEP)) != NULL) { - *cp = '\0'; - } - *pp = NULL; -} - - -/* - ****************************************************************************** - * - * ShowOptions -- - * - * Prints out the state information used by the resolver - * library and other options set by the user. - * - ****************************************************************************** - */ - -void -ShowOptions() -{ - register char **cp; - - PrintHostInfo(stdout, "Default Server:", defaultPtr); - if (curHostValid) { - PrintHostInfo(stdout, "Host:", &curHostInfo); - } - - printf("Set options:\n"); - printf(" %sdebug \t", (res.options & RES_DEBUG) ? "" : "no"); - printf(" %sdefname\t", (res.options & RES_DEFNAMES) ? "" : "no"); - printf(" %ssearch\t", (res.options & RES_DNSRCH) ? "" : "no"); - printf(" %srecurse\n", (res.options & RES_RECURSE) ? "" : "no"); - - printf(" %sd2\t\t", (res.options & RES_DEBUG2) ? "" : "no"); - printf(" %svc\t\t", (res.options & RES_USEVC) ? "" : "no"); - printf(" %signoretc\t", (res.options & RES_IGNTC) ? "" : "no"); - printf(" port=%u\n", nsport); - - printf(" querytype=%s\t", p_type(queryType)); - printf(" class=%s\t", p_class(queryClass)); - printf(" timeout=%d\t", res.retrans); - printf(" retry=%d\n", res.retry); - printf(" root=%s\n", rootServerName); - printf(" domain=%s\n", res.defdname); - - cp = res.dnsrch; - if (cp != NULL) { - printf(" srchlist=%s", *cp); - for (cp++; *cp; cp++) { - printf("%c%s", SRCHLIST_SEP, *cp); - } - putchar('\n'); - } - putchar('\n'); -} -#undef SRCHLIST_SEP - -/* - ****************************************************************************** - * - * PrintHelp -- - * - * Displays the help file. - * - ****************************************************************************** - */ - -void -PrintHelp() -{ - char cmd[PATH_MAX]; - - sprintf(cmd, "%s %s", pager, _PATH_HELPFILE); - system(cmd); -} - -/* - ****************************************************************************** - * - * CvtAddrToPtr -- - * - * Convert a dotted-decimal Internet address into the standard - * PTR format (reversed address with .in-arpa. suffix). - * - * Assumes the argument buffer is large enougth to hold the result. - * - ****************************************************************************** - */ - -static void -CvtAddrToPtr(name) - char *name; -{ - const char *p; - int ip[4]; - struct in_addr addr; - - if (IsAddr(name, &addr)) { - p = inet_ntoa(addr); - if (sscanf(p, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4) { - sprintf(name, "%d.%d.%d.%d.in-addr.arpa.", - ip[3], ip[2], ip[1], ip[0]); - } - } -} - -/* - ****************************************************************************** - * - * ReadRC -- - * - * Use the contents of ~/.nslookuprc as options. - * - ****************************************************************************** - */ - -static void -ReadRC() -{ - register FILE *fp; - register char *cp; - char buf[PATH_MAX]; - - if ((cp = getenv("HOME")) != NULL && - (strlen(cp) + strlen(_PATH_NSLOOKUPRC)) < sizeof(buf)) { - - (void) strcpy(buf, cp); - (void) strcat(buf, _PATH_NSLOOKUPRC); - - if ((fp = fopen(buf, "r")) != NULL) { - while (fgets(buf, sizeof(buf), fp) != NULL) { - if ((cp = strchr(buf, '\n')) != NULL) { - *cp = '\0'; - } - (void) SetOption(buf); - } - (void) fclose(fp); - } - } -} diff --git a/contrib/bind/bin/nslookup/nslookup.help b/contrib/bind/bin/nslookup/nslookup.help deleted file mode 100644 index 31a66345a5236..0000000000000 --- a/contrib/bind/bin/nslookup/nslookup.help +++ /dev/null @@ -1,33 +0,0 @@ -$Id: nslookup.help,v 8.5 2000/03/30 23:25:35 vixie Exp $ - -Commands: (identifiers are shown in uppercase, [] means optional) -NAME - print info about the host/domain NAME using default server -NAME1 NAME2 - as above, but use NAME2 as server -help or ? - print info on common commands; see nslookup(1) for details -set OPTION - set an option - all - print options, current server and host - [no]debug - print debugging information - [no]d2 - print exhaustive debugging information - [no]defname - append domain name to each query - [no]recurse - ask for recursive answer to query - [no]vc - always use a virtual circuit - domain=NAME - set default domain name to NAME - srchlist=N1[/N2/.../N6] - set domain to N1 and search list to N1,N2, etc. - root=NAME - set root server to NAME - retry=X - set number of retries to X - timeout=X - set initial time-out interval to X seconds - querytype=X - set query type, e.g., A,ANY,CNAME,HINFO,MX,PX,NS,PTR,SOA,TXT,WKS,SRV,NAPTR - port=X - set port number to send query on - type=X - synonym for querytype - class=X - set query class to one of IN (Internet), CHAOS, HESIOD or ANY -server NAME - set default server to NAME, using current default server -lserver NAME - set default server to NAME, using initial server -finger [USER] - finger the optional USER at the current default host -root - set current default server to the root -ls [opt] DOMAIN [> FILE] - list addresses in DOMAIN (optional: output to FILE) - -a - list canonical names and aliases - -h - list HINFO (CPU type and operating system) - -s - list well-known services - -d - list all records - -t TYPE - list records of the given type (e.g., A,CNAME,MX, etc.) -exit - exit the program, ^D also exits diff --git a/contrib/bind/bin/nslookup/pathnames.h b/contrib/bind/bin/nslookup/pathnames.h deleted file mode 100644 index bfeae4f8ab24d..0000000000000 --- a/contrib/bind/bin/nslookup/pathnames.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ++Copyright++ 1990 - * - - * Copyright (c) 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* - * @(#)pathnames.h 5.1 (Berkeley) 5/28/90 - * $Id: pathnames.h,v 8.1 1994/12/15 06:24:31 vixie Exp $ - */ - -#define _PATH_NSLOOKUPRC "/.nslookuprc" -#define _PATH_PAGERCMD "more" - -#ifndef _PATH_HELPFILE -#if defined(BSD) && BSD >= 198810 -#define _PATH_HELPFILE "/usr/share/misc/nslookup.help" -#else -#define _PATH_HELPFILE "/usr/lib/nslookup.help" -#endif -#endif - diff --git a/contrib/bind/bin/nslookup/res.h b/contrib/bind/bin/nslookup/res.h deleted file mode 100644 index 5ffd6ce46dd38..0000000000000 --- a/contrib/bind/bin/nslookup/res.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * ++Copyright++ 1985, 1989 - * - - * Copyright (c) 1985, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* - * @(#)res.h 5.10 (Berkeley) 6/1/90 - * $Id: res.h,v 8.5 1998/09/16 17:03:17 vixie Exp $ - */ - -/* - ******************************************************************************* - * - * res.h -- - * - * Definitions used by modules of the name server lookup program. - * - * Copyright (c) 1985 - * Andrew Cherenson - * U.C. Berkeley - * CS298-26 Fall 1985 - * - ******************************************************************************* - */ - -#define TRUE 1 -#define FALSE 0 -typedef int Boolean; - -#define MAXALIASES 35 -#define MAXADDRS 35 -#define MAXDOMAINS 35 -#define MAXSERVERS 10 - -/* - * Define return statuses in addtion to the ones defined in namserv.h - * let SUCCESS be a synonym for NOERROR - * - * TIME_OUT - a socket connection timed out. - * NO_INFO - the server didn't find any info about the host. - * ERROR - one of the following types of errors: - * dn_expand, res_mkquery failed - * bad command line, socket operation failed, etc. - * NONAUTH - the server didn't have the desired info but - * returned the name(s) of some servers who should. - * NO_RESPONSE - the server didn't respond. - * - */ - -#define SUCCESS 0 -#define TIME_OUT -1 -#define NO_INFO -2 -#define ERROR -3 -#define NONAUTH -4 -#define NO_RESPONSE -5 - -/* - * Define additional options for the resolver state structure. - * - * RES_DEBUG2 more verbose debug level - */ - -#define RES_DEBUG2 0x80000000 - -/* - * Maximum length of server, host and file names. - */ - -#define NAME_LEN 256 - - -/* - * Modified struct hostent from <netdb.h> - * - * "Structures returned by network data base library. All addresses - * are supplied in host order, and returned in network order (suitable - * for use in system calls)." - */ - -typedef struct { - char *name; /* official name of host */ - char **domains; /* domains it serves */ - char **addrList; /* list of addresses from name server */ -} ServerInfo; - -typedef struct { - char *name; /* official name of host */ - char **aliases; /* alias list */ - char **addrList; /* list of addresses from name server */ - int addrType; /* host address type */ - int addrLen; /* length of address */ - ServerInfo **servers; -} HostInfo; - - -/* - * FilePtr is used for directing listings to a file. - * It is global so the Control-C handler can close it. - */ - -extern FILE *filePtr; - -/* - * TCP/UDP port of server. - */ -extern unsigned short nsport; - -/* - * Our resolver context. - */ -extern struct __res_state res; - -/* - * External routines: - */ - -/* XXX need prototypes */ -extern Boolean IsAddr(); -void Print_query(const u_char *msg, const u_char *eom, int printHeader); -void Fprint_query(const u_char *msg, const u_char *eom, int printHeader, - FILE *file); -const u_char *Print_cdname(const u_char *cp, const u_char *msg, - const u_char *eom, FILE *file); -const u_char *Print_cdname2(const u_char *cp, const u_char *msg, - const u_char *eom, FILE *file); -const u_char *Print_rr(const u_char *ocp, const u_char *msg, - const u_char *eom, FILE *file); -extern const char *DecodeType(); /* descriptive version of p_type */ -extern const char *DecodeError(); -extern char *Calloc(); -extern char *Malloc(); -extern void NsError(); -extern void PrintServer(); -extern void PrintHostInfo(); -extern void ShowOptions(); -extern void FreeHostInfoPtr(); -extern FILE *OpenFile(); -extern char *res_skip(); diff --git a/contrib/bind/bin/nslookup/send.c b/contrib/bind/bin/nslookup/send.c deleted file mode 100644 index 61a8751401fee..0000000000000 --- a/contrib/bind/bin/nslookup/send.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (c) 1985, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -static const char sccsid[] = "@(#)send.c 5.18 (Berkeley) 3/2/91"; -static const char rcsid[] = "$Id: send.c,v 8.9 1999/10/13 16:39:19 vixie Exp $"; -#endif /* not lint */ - -/* - ****************************************************************************** - * - * send.c -- - * - * Routine to send request packets to a name server. - * - * Based on "@(#)res_send.c 6.25 (Berkeley) 6/1/90". - * - ****************************************************************************** - */ - - -/* - * Send query to name server and wait for reply. - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <sys/uio.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <errno.h> -#include <resolv.h> -#include <stdio.h> -#include <unistd.h> - -#include "port_after.h" - -#include "res.h" - -static int s = -1; /* socket used for communications */ - -unsigned short nsport = NAMESERVER_PORT; - - - -/* - ****************************************************************************** - * - * SendRequest -- - * - * Sends a request packet to a name server whose address - * is specified by the first argument and returns with - * the answer packet. - * - * Results: - * SUCCESS - the request was sent and an answer - * was received. - * TIME_OUT - the virtual circuit connection timed-out - * or a reply to a datagram wasn't received. - * - * - ****************************************************************************** - */ - -int -SendRequest(struct in_addr *nsAddrPtr, const u_char *buf, int buflen, - u_char *answer, u_int anslen, int *trueLenPtr) -{ - int n, try, v_circuit, resplen, salen; - int gotsomewhere = 0, connected = 0; - int connreset = 0; - u_short id, len; - u_char *cp; - fd_set dsmask; - struct timeval timeout; - const HEADER *hp = (HEADER *) buf; - HEADER *anhp = (HEADER *) answer; - struct iovec iov[2]; - int terrno = ETIMEDOUT; - char junk[512]; - struct sockaddr_in sin, sa; - - if (res.options & RES_DEBUG2) { - printf("------------\nSendRequest(), len %d\n", buflen); - Print_query(buf, buf + buflen, 1); - } - sin.sin_family = AF_INET; - sin.sin_port = htons(nsport); - sin.sin_addr = *nsAddrPtr; - v_circuit = (res.options & RES_USEVC) || buflen > PACKETSZ; - id = hp->id; - /* - * Send request, RETRY times, or until successful - */ - for (try = 0; try < res.retry; try++) { - usevc: - if (v_circuit) { - int truncated = 0; - - /* - * Use virtual circuit; - * at most one attempt per server. - */ - try = res.retry; - if (s < 0) { - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) { - terrno = errno; - if (res.options & RES_DEBUG) - perror("socket (vc) failed"); - continue; - } - if (connect(s, (struct sockaddr *)&sin, - sizeof(struct sockaddr)) < 0) { - terrno = errno; - if (res.options & RES_DEBUG) - perror("connect failed"); - (void) close(s); - s = -1; - continue; - } - } - /* - * Send length & message - */ - __putshort(buflen, (u_char *)&len); - iov[0].iov_base = (caddr_t)&len; - iov[0].iov_len = INT16SZ; - iov[1].iov_base = (caddr_t)buf; - iov[1].iov_len = buflen; - if (writev(s, iov, 2) != INT16SZ + buflen) { - terrno = errno; - if (res.options & RES_DEBUG) - perror("write failed"); - (void) close(s); - s = -1; - continue; - } - /* - * Receive length & response - */ - cp = answer; - len = INT16SZ; - while ((n = read(s, (char *)cp, (int)len)) > 0) { - cp += n; - if ((len -= n) <= 0) - break; - } - if (n <= 0) { - terrno = errno; - if (res.options & RES_DEBUG) - perror("read failed"); - (void) close(s); - s = -1; - /* - * A long running process might get its TCP - * connection reset if the remote server was - * restarted. Requery the server instead of - * trying a new one. When there is only one - * server, this means that a query might work - * instead of failing. We only allow one reset - * per query to prevent looping. - */ - if (terrno == ECONNRESET && !connreset) { - connreset = 1; - } - continue; - } - cp = answer; - if ((resplen = ns_get16((u_char*)cp)) > anslen) { - if (res.options & RES_DEBUG) - fprintf(stderr, "response truncated\n"); - len = anslen; - truncated = 1; - } else - len = resplen; - while (len != 0 && - (n = read(s, (char *)cp, (int)len)) > 0) { - cp += n; - len -= n; - } - if (n <= 0) { - terrno = errno; - if (res.options & RES_DEBUG) - perror("read failed"); - (void) close(s); - s = -1; - continue; - } - if (truncated) { - /* - * Flush rest of answer - * so connection stays in synch. - */ - anhp->tc = 1; - len = resplen - anslen; - while (len != 0) { - n = (len > sizeof(junk) ? - sizeof(junk) : len); - if ((n = read(s, junk, n)) > 0) - len -= n; - else - break; - } - } - } else { - /* - * Use datagrams. - */ - if (s < 0) { - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) { - terrno = errno; - if (res.options & RES_DEBUG) - perror("socket (dg) failed"); - continue; - } - } -#if BSD >= 43 - if (connected == 0) { - if (connect(s, (struct sockaddr *)&sin, - sizeof sin) < 0) { - if (res.options & RES_DEBUG) - perror("connect"); - continue; - } - connected = 1; - } - if (send(s, buf, buflen, 0) != buflen) { - if (res.options & RES_DEBUG) - perror("send"); - continue; - } -#else /* BSD */ - if (sendto(s, (const char *)buf, buflen, 0, - (struct sockaddr *) &sin, - sizeof sin) != buflen) { - if (res.options & RES_DEBUG) - perror("sendto"); - continue; - } -#endif - - /* - * Wait for reply - */ - timeout.tv_sec = (res.retrans << try); - if (timeout.tv_sec <= 0) - timeout.tv_sec = 1; - timeout.tv_usec = 0; - wait: - FD_ZERO(&dsmask); - FD_SET(s, &dsmask); - n = select(s+1, &dsmask, (fd_set *)NULL, - (fd_set *)NULL, &timeout); - if (n < 0) { - if (res.options & RES_DEBUG) - perror("select"); - continue; - } - if (n == 0) { - /* - * timeout - */ - if (res.options & RES_DEBUG) - printf("timeout\n"); -#if BSD >= 43 - gotsomewhere = 1; -#endif - continue; - } - - salen = sizeof sa; - resplen = recvfrom(s, (char *)answer, anslen, 0, - (struct sockaddr *)&sa, &salen); - if (resplen <= 0) { - if (res.options & RES_DEBUG) - perror("recvfrom"); - continue; - } - gotsomewhere = 1; - if (id != anhp->id) { - /* - * response from old query, ignore it - */ - if (res.options & RES_DEBUG2) { - printf("------------\nOld answer:\n"); - Print_query(answer, answer+resplen, 1); - } - goto wait; - } - if (!(res.options & RES_IGNTC) && anhp->tc) { - /* - * get rest of answer; - * use TCP with same server. - */ - if (res.options & RES_DEBUG) - printf("truncated answer\n"); - (void) close(s); - s = -1; - v_circuit = 1; - goto usevc; - } - } - if (res.options & RES_DEBUG) { - if (res.options & RES_DEBUG2) - printf("------------\nGot answer (%d bytes):\n", - resplen); - else - printf("------------\nGot answer:\n"); - Print_query(answer, answer+resplen, 1); - } - (void) close(s); - s = -1; - *trueLenPtr = resplen; - return (SUCCESS); - } - if (s >= 0) { - (void) close(s); - s = -1; - } - if (v_circuit == 0) - if (gotsomewhere == 0) - return NO_RESPONSE; /* no nameservers found */ - else - return TIME_OUT; /* no answer obtained */ - else - if (errno == ECONNREFUSED) - return NO_RESPONSE; - else - return ERROR; -} - -/* - * This routine is for closing the socket if a virtual circuit is used and - * the program wants to close it. - * - * Called from the interrupt handler. - */ -void SendRequest_close() -{ - if (s != -1) { - (void) close(s); - s = -1; - } -} diff --git a/contrib/bind/bin/nslookup/skip.c b/contrib/bind/bin/nslookup/skip.c deleted file mode 100644 index 5318ef657c23b..0000000000000 --- a/contrib/bind/bin/nslookup/skip.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 1985, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -static const char sccsid[] = "@(#)skip.c 5.12 (Berkeley) 3/21/91"; -static const char rcsid[] = "$Id: skip.c,v 8.5 1999/10/13 16:39:20 vixie Exp $"; -#endif /* not lint */ - -/* - ******************************************************************************* - * - * skip.c -- - * - * Routines to skip over portions of a query buffer. - * - * Note: this file has been submitted for inclusion in - * BIND resolver library. When this has been done, this file - * is no longer necessary (assuming there haven't been any - * changes). - * - * Adapted from 4.3BSD BIND res_debug.c - * - ******************************************************************************* - */ - -#include "port_before.h" - -#include <sys/param.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> - -#include <resolv.h> -#include <stdio.h> - -#include "port_after.h" - -char *res_skip_rr(); - - -/* - ******************************************************************************* - * - * res_skip -- - * - * Skip the contents of a query. - * - * Interpretation of numFieldsToSkip argument: - * res_skip returns pointer to: - * 1 -> start of question records. - * 2 -> start of authoritative answer records. - * 3 -> start of additional records. - * 4 -> first byte after end of additional records. - * - * Results: - * (address) - success operation. - * NULL - a resource record had an incorrect format. - * - ******************************************************************************* - */ - -char * -res_skip(msg, numFieldsToSkip, eom) - char *msg; - int numFieldsToSkip; - char *eom; -{ - register char *cp; - register HEADER *hp; - register int tmp; - register int n; - - /* - * Skip the header fields. - */ - hp = (HEADER *)msg; - cp = msg + HFIXEDSZ; - - /* - * skip question records. - */ - n = ntohs(hp->qdcount); - if (n > 0) { - while (--n >= 0 && cp < eom) { - tmp = dn_skipname((u_char *)cp, (u_char *)eom); - if (tmp == -1) return(NULL); - cp += tmp; - cp += INT16SZ; /* type */ - cp += INT16SZ; /* class */ - } - } - if (--numFieldsToSkip <= 0) return(cp); - - /* - * skip authoritative answer records - */ - n = ntohs(hp->ancount); - if (n > 0) { - while (--n >= 0 && cp < eom) { - cp = res_skip_rr(cp, eom); - if (cp == NULL) return(NULL); - } - } - if (--numFieldsToSkip == 0) return(cp); - - /* - * skip name server records - */ - n = ntohs(hp->nscount); - if (n > 0) { - while (--n >= 0 && cp < eom) { - cp = res_skip_rr(cp, eom); - if (cp == NULL) return(NULL); - } - } - if (--numFieldsToSkip == 0) return(cp); - - /* - * skip additional records - */ - n = ntohs(hp->arcount); - if (n > 0) { - while (--n >= 0 && cp < eom) { - cp = res_skip_rr(cp, eom); - if (cp == NULL) return(NULL); - } - } - - return(cp); -} - - -/* - ******************************************************************************* - * - * res_skip_rr -- - * - * Skip over resource record fields. - * - * Results: - * (address) - success operation. - * NULL - a resource record had an incorrect format. - ******************************************************************************* - */ - -char * -res_skip_rr(cp, eom) - char *cp; - char *eom; -{ - int tmp; - int dlen; - - if ((tmp = dn_skipname((u_char *)cp, (u_char *)eom)) == -1) - return (NULL); /* compression error */ - cp += tmp; - if ((cp + RRFIXEDSZ) > eom) - return (NULL); - cp += INT16SZ; /* type */ - cp += INT16SZ; /* class */ - cp += INT32SZ; /* ttl */ - dlen = ns_get16((u_char*)cp); - cp += INT16SZ; /* dlen */ - cp += dlen; - if (cp > eom) - return (NULL); - return (cp); -} diff --git a/contrib/bind/bin/nslookup/subr.c b/contrib/bind/bin/nslookup/subr.c deleted file mode 100644 index a3b9f964a0af6..0000000000000 --- a/contrib/bind/bin/nslookup/subr.c +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Copyright (c) 1985, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef lint -static const char sccsid[] = "@(#)subr.c 5.24 (Berkeley) 3/2/91"; -static const char rcsid[] = "$Id: subr.c,v 8.13 1999/10/13 16:39:20 vixie Exp $"; -#endif /* not lint */ - -/* - ******************************************************************************* - * - * subr.c -- - * - * Miscellaneous subroutines for the name server - * lookup program. - * - * Copyright (c) 1985 - * Andrew Cherenson - * U.C. Berkeley - * CS298-26 Fall 1985 - * - ******************************************************************************* - */ - -#include "port_before.h" - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <netdb.h> -#include <setjmp.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "port_after.h" - -#include "resolv.h" -#include "res.h" - -/* - ******************************************************************************* - * - * IntrHandler -- - * - * This routine is called whenever a control-C is typed. - * It performs three main functions: - * - closes an open socket connection, - * - closes an open output file (used by LookupHost, et al.), - * - jumps back to the main read-eval loop. - * - * If a user types a ^C in the middle of a routine that uses a socket, - * the routine would not be able to close the socket. To prevent an - * overflow of the process's open file table, the socket and output - * file descriptors are closed by the interrupt handler. - * - * Side effects: - * Open file descriptors are closed. - * If filePtr is valid, it is closed. - * Flow of control returns to the main() routine. - * - ******************************************************************************* - */ - -SIG_FN -IntrHandler() -{ - extern jmp_buf env; -#if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD) && !defined(__osf__) - extern FILE *yyin; /* scanner input file */ - extern void yyrestart(); /* routine to restart scanner after interrupt */ -#endif - extern void ListHost_close(void); - - SendRequest_close(); - ListHost_close(); - if (filePtr != NULL && filePtr != stdout) { - fclose(filePtr); - filePtr = NULL; - } - printf("\n"); -#if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD) && !defined(__osf__) - yyrestart(yyin); -#endif - longjmp(env, 1); -} - - -/* - ******************************************************************************* - * - * Malloc -- - * Calloc -- - * - * Calls the malloc library routine with SIGINT blocked to prevent - * corruption of malloc's data structures. We need to do this because - * a control-C doesn't kill the program -- it causes a return to the - * main command loop. - * - * NOTE: This method doesn't prevent the pointer returned by malloc - * from getting lost, so it is possible to get "core leaks". - * - * If malloc fails, the program exits. - * - * Results: - * (address) - address of new buffer. - * - ******************************************************************************* - */ - -char * -Malloc(size) - int size; -{ - char *ptr; - -#ifdef SYSV -#if defined(SVR3) || defined(SVR4) - sighold(SIGINT); - ptr = malloc((unsigned) size); - sigrelse(SIGINT); -#else - { SIG_FN (*old)(); - old = signal(SIGINT, SIG_IGN); - ptr = malloc((unsigned) size); - signal(SIGINT, old); - } -#endif -#else -#ifdef POSIX_SIGNALS - { sigset_t sset; - sigemptyset(&sset); - sigaddset(&sset,SIGINT); - sigprocmask(SIG_BLOCK,&sset,NULL); - ptr = malloc((unsigned) size); - sigprocmask(SIG_UNBLOCK,&sset,NULL); - } -#else - { int saveMask; - saveMask = sigblock(sigmask(SIGINT)); - ptr = malloc((unsigned) size); - (void) sigsetmask(saveMask); - } -#endif -#endif - if (ptr == NULL) { - fflush(stdout); - fprintf(stderr, "*** Can't allocate memory\n"); - fflush(stderr); - abort(); - /*NOTREACHED*/ - } - return (ptr); -} - -char * -Calloc(num, size) - register int num, size; -{ - char *ptr = Malloc(num*size); - memset(ptr, 0, num*size); - return(ptr); -} - - -/* - ******************************************************************************* - * - * PrintHostInfo -- - * - * Prints out the HostInfo structure for a host. - * - ******************************************************************************* - */ - -void -PrintHostInfo(file, title, hp) - FILE *file; - char *title; - register HostInfo *hp; -{ - register char **cp; - register ServerInfo **sp; - char comma; - int i; - - fprintf(file, "%-7s %s", title, hp->name); - - if (hp->addrList != NULL) { - if (hp->addrList[1] != NULL) { - fprintf(file, "\nAddresses:"); - } else { - fprintf(file, "\nAddress:"); - } - comma = ' '; - i = 0; - for (cp = hp->addrList; cp && *cp; cp++) { - i++; - if (i > 4) { - fprintf(file, "\n\t"); - comma = ' '; - i = 0; - } - fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp)); - comma = ','; - } - } - - if (hp->aliases != NULL) { - fprintf(file, "\nAliases:"); - comma = ' '; - i = 10; - for (cp = hp->aliases; cp && *cp && **cp; cp++) { - i += strlen(*cp) + 2; - if (i > 75) { - fprintf(file, "\n\t"); - comma = ' '; - i = 10; - } - fprintf(file, "%c %s", comma, *cp); - comma = ','; - } - } - - if (hp->servers != NULL) { - fprintf(file, "\nServed by:\n"); - for (sp = hp->servers; *sp != NULL ; sp++) { - - fprintf(file, "- %s\n\t", (*sp)->name); - - comma = ' '; - i = 0; - for (cp = (*sp)->addrList; cp && *cp && **cp; cp++) { - i++; - if (i > 4) { - fprintf(file, "\n\t"); - comma = ' '; - i = 0; - } - fprintf(file, - "%c %s", comma, inet_ntoa(*(struct in_addr *)*cp)); - comma = ','; - } - fprintf(file, "\n\t"); - - comma = ' '; - i = 10; - for (cp = (*sp)->domains; cp && *cp && **cp; cp++) { - i += strlen(*cp) + 2; - if (i > 75) { - fprintf(file, "\n\t"); - comma = ' '; - i = 10; - } - fprintf(file, "%c %s", comma, *cp); - comma = ','; - } - fprintf(file, "\n"); - } - } - - fprintf(file, "\n\n"); -} - -/* - ******************************************************************************* - * - * OpenFile -- - * - * Parses a command string for a file name and opens - * the file. The file name is copued to the argument FILE. The - * parameter SIZE parameter includes space for a null byte. - * - * Results: - * file pointer - the open was successful. - * NULL - there was an error opening the file or - * the input string was invalid. - * - ******************************************************************************* - */ - -FILE * -OpenFile(string, file, size) - char *string; - char *file; - size_t size; -{ - char *redirect; - FILE *tmpPtr; - int i; - - /* - * Open an output file if we see '>' or >>'. - * Check for overwrite (">") or concatenation (">>"). - */ - - redirect = strchr(string, '>'); - if (redirect == NULL) { - return(NULL); - } - - tmpPtr = NULL; - if (redirect[1] == '>') { - i = pickString(redirect + 2, file, size); - if (i > 0) { - tmpPtr = fopen(file, "a+"); - } - } else { - i = pickString(redirect + 1, file, size); - if (i > 0) { - tmpPtr = fopen(file, "w"); - } - } - - if (tmpPtr != NULL) { - redirect[0] = '\0'; - } - - return(tmpPtr); -} - -/* - ******************************************************************************* - * - * DecodeError -- - * - * Converts an error code into a character string. - * - ******************************************************************************* - */ - -const struct res_sym error_syms[] = { - { NOERROR, "Success" }, - { FORMERR, "Format error" }, - { SERVFAIL, "Server failed" }, - { NXDOMAIN, "Non-existent host/domain" }, - { NOTIMP, "Not implemented" }, - { REFUSED, "Query refused" }, -#ifdef NOCHANGE - { NOCHANGE, "No change" }, -#endif - { TIME_OUT, "Timed out" }, - { NO_INFO, "No information" }, - { ERROR, "Unspecified error" }, - { NONAUTH, "Non-authoritative answer" }, - { NO_RESPONSE, "No response from server" }, - { 0, NULL } -}; - -const char * -DecodeError(result) - int result; -{ - const char *string; - int success; - - string = sym_ntos(error_syms, result, &success); - if (success) - return string; - return ("BAD ERROR VALUE"); -} - - -int -StringToClass(class, dflt, errorfile) - char *class; - int dflt; - FILE *errorfile; -{ - int result, success; - - result = sym_ston(__p_class_syms, class, &success); - if (success) - return result; - - if (errorfile) - fprintf(errorfile, "unknown query class: %s\n", class); - return(dflt); -} - - -/* - ******************************************************************************* - * - * StringToType -- - * - * Converts a string form of a query type name to its - * corresponding integer value. - * - ******************************************************************************* - */ - -int -StringToType(type, dflt, errorfile) - char *type; - int dflt; - FILE *errorfile; -{ - int result, success; - - result = sym_ston(__p_type_syms, type, &success); - if (success) - return (result); - - if (errorfile) - fprintf(errorfile, "unknown query type: %s\n", type); - return (dflt); -} - -/* - ******************************************************************************* - * - * DecodeType -- - * - * Converts a query type to a descriptive name. - * (A more verbose form of p_type.) - * - * - ******************************************************************************* - */ - -const char * -DecodeType(type) - int type; -{ - - return (sym_ntop(__p_type_syms, type, (int *)0)); -} - - - - -/* - * Skip over leading white space in SRC and then copy the next sequence of - * non-whitespace characters into DEST. No more than (DEST_SIZE - 1) - * characters are copied. DEST is always null-terminated. Returns 0 if no - * characters could be copied into DEST. Returns the number of characters - * in SRC that were processed (i.e. the count of characters in the leading - * white space and the first non-whitespace sequence). - * - * int i; - * char *p = " foo bar ", *q; - * char buf[100]; - * - * q = p + pickString(p, buf, sizeof buff); - * assert (strcmp (q, " bar ") == 0) ; - * - */ - -int -pickString(const char *src, char *dest, size_t dest_size) { - const char *start; - const char *end ; - size_t sublen ; - - if (dest_size == 0 || dest == NULL || src == NULL) - return 0; - - for (start = src ; isspace(*start) ; start++) - /* nada */ ; - - for (end = start ; *end != '\0' && !isspace(*end) ; end++) - /* nada */ ; - - sublen = end - start ; - - if (sublen == 0 || sublen > (dest_size - 1)) - return 0; - - strncpy (dest, start, sublen); - - dest[sublen] = '\0' ; - - return (end - src); -} - - - - -/* - * match the string FORMAT against the string SRC. Leading whitespace in - * FORMAT will match any amount of (including no) leading whitespace in - * SRC. Any amount of whitespace inside FORMAT matches any non-zero amount - * of whitespace in SRC. Value returned is 0 if match didn't occur, or the - * amount of characters in SRC that did match - * - * int i ; - * - * i = matchString(" a b c", "a b c") ; - * assert (i == 5) ; - * i = matchString("a b c", " a b c"); - * assert (i == 0) ; becasue no leading white space in format - * i = matchString(" a b c", " a b c"); - * assert(i == 12); - * i = matchString("aa bb ", "aa bb ddd sd"); - * assert(i == 16); - */ -int -matchString (const char *format, const char *src) { - const char *f = format; - const char *s = src; - - if (f == NULL || s == NULL) - goto notfound; - - if (isspace(*f)) { - while (isspace(*f)) - f++ ; - while (isspace(*s)) - s++ ; - } - - while (1) { - if (isspace(*f)) { - if (!isspace(*s)) - goto notfound; - while(isspace(*s)) - s++; - /* any amount of whitespace in the format string - will match any amount of space in the source - string. */ - while (isspace(*f)) - f++; - } else if (*f == '\0') { - return (s - src); - } else if (*f != *s) { - goto notfound; - } else { - s++ ; - f++ ; - } - } - notfound: - return 0 ; -} diff --git a/contrib/bind/bin/nsupdate/Makefile b/contrib/bind/bin/nsupdate/Makefile deleted file mode 100644 index d8bd2b18e7268..0000000000000 --- a/contrib/bind/bin/nsupdate/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -## Copyright (c) 1996,1999 by Internet Software Consortium -## -## Permission to use, copy, modify, and distribute this software for any -## purpose with or without fee is hereby granted, provided that the above -## copyright notice and this permission notice appear in all copies. -## -## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS -## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -## SOFTWARE. - -# $Id: Makefile,v 8.25 2000/07/11 06:41:35 vixie Exp $ - -DESTDIR= -CC= cc -SHELL= /bin/sh - -CDEBUG= -g - -#(net2 and its descendents) -SYSTYPE = bsdos -TOP = ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.a -A=a -O=o -EXE= -LEX = lex -I -SYSLIBS = -ll -lutil -DESTBIN = /usr/local/bin -DESTSBIN = /usr/local/sbin -DESTEXEC = /usr/local/libexec -DESTMAN = /usr/share/man -DESTHELP= /usr/share/misc -STRIP=-s -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin - -LDFLAGS= -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} - -PROG= nsupdate -SRCS= ${PROG}.c -OBJS= ${PROG}.${O} - -all: ${PROG}${EXE} - -${PROG}${EXE}: ${OBJS} ${LIBBIND} Makefile - ${CC} ${CDEBUG} ${LDFLAGS} ${BOUNDS} -o ${PROG}${EXE} ${OBJS} \ - ${LIBBIND} ${SYSLIBS} - -.c.${O}: - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c - -distclean: clean - -clean: FRC - rm -f ${PROG}${EXE} ${OBJS} core .depend - rm -f *.BAK *.CKP *~ *.orig - -depend: ${SRCS} - mkdep ${CPPFLAGS} -I${INCL} -I${PORTINCL} ${SRCS} - -${DESTDIR}${DESTBIN}: - mkdir -p ${DESTDIR}${DESTBIN} - -install: ${DESTDIR}${DESTBIN} ${PROG}${EXE} - ${INSTALL} ${STRIP} -c ${INSTALL_EXEC} -m 755 ${PROG}${EXE} ${DESTDIR}${DESTBIN}/${PROG}${EXE} - -links: FRC - @set -e; ln -s SRC/*.[ch] . - -tags: FRC - ctags *.[ch] - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/bin/nsupdate/nsupdate.c b/contrib/bind/bin/nsupdate/nsupdate.c deleted file mode 100644 index d164bb1f62cb1..0000000000000 --- a/contrib/bind/bin/nsupdate/nsupdate.c +++ /dev/null @@ -1,689 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: nsupdate.c,v 8.24 2000/07/11 06:32:01 vixie Exp $"; -#endif /* not lint */ - -/* - * Copyright (c) 1996,1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "port_before.h" - -#include <sys/param.h> -#include <sys/socket.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <netdb.h> -#include <resolv.h> -#include <res_update.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <isc/dst.h> -#include "port_after.h" -#include "../named/db_defs.h" - -/* XXX all of this stuff should come from libbind.a */ - -/* - * Map class and type names to number - */ -struct map { - char token[10]; - int val; -}; - -struct map class_strs[] = { - { "in", C_IN }, - { "chaos", C_CHAOS }, - { "hs", C_HS }, -}; -#define M_CLASS_CNT (sizeof(class_strs) / sizeof(struct map)) - -struct map type_strs[] = { - { "a", T_A }, - { "ns", T_NS }, - { "cname", T_CNAME }, - { "soa", T_SOA }, - { "mb", T_MB }, - { "mg", T_MG }, - { "mr", T_MR }, - { "null", T_NULL }, - { "wks", T_WKS }, - { "ptr", T_PTR }, - { "hinfo", T_HINFO }, - { "minfo", T_MINFO }, - { "mx", T_MX }, - { "txt", T_TXT }, - { "rp", T_RP }, - { "afsdb", T_AFSDB }, - { "x25", T_X25 }, - { "isdn", T_ISDN }, - { "rt", T_RT }, - { "nsap", T_NSAP }, - { "nsap_ptr", T_NSAP_PTR }, - { "sig", T_SIG }, - { "key", T_KEY }, - { "px", T_PX }, - { "loc", T_LOC }, - { "nxt", T_NXT }, - { "eid", T_EID }, - { "nimloc", T_NIMLOC }, - { "srv", T_SRV }, - { "atma", T_ATMA }, - { "naptr", T_NAPTR }, - { "kx", ns_t_kx }, - { "cert", ns_t_cert }, - { "aaaa", ns_t_aaaa }, -}; -#define M_TYPE_CNT (sizeof(type_strs) / sizeof(struct map)) - -struct map section_strs[] = { - { "zone", S_ZONE }, - { "prereq", S_PREREQ }, - { "update", S_UPDATE }, - { "reserved", S_ADDT }, -}; -#define M_SECTION_CNT (sizeof(section_strs) / sizeof(struct map)) - -struct map opcode_strs[] = { - { "nxdomain", NXDOMAIN }, - { "yxdomain", YXDOMAIN }, - { "nxrrset", NXRRSET }, - { "yxrrset", YXRRSET }, - { "delete", DELETE }, - { "add", ADD }, -}; -#define M_OPCODE_CNT (sizeof(opcode_strs) / sizeof(struct map)) - -static int getcharstring(char *, char *, int, int, int); -static char *progname; - -static void usage(void); -static int getword_str(char *, int, char **, char *); - -static struct __res_state res; - -int dns_findprimary (res_state, char *, struct ns_tsig_key *, char *, - int, struct in_addr *); - -/* - * format of file read by nsupdate is kept the same as the log - * file generated by updates, so that the log file can be fed - * to nsupdate to reconstruct lost updates. - * - * file is read on line at a time using fgets() rather than - * one word at a time using getword() so that it is easy to - * adapt nsupdate to read piped input from other scripts - * - * overloading of class/type has to be deferred to res_update() - * because class is needed by res_update() to determined the - * zone to which a resource record belongs - */ -int -main(argc, argv) - int argc; - char **argv; -{ - FILE *fp = NULL; - char buf[BUFSIZ], buf2[BUFSIZ], hostbuf[100], filebuf[100]; - char dnbuf[MAXDNAME], data[MAXDATA]; - u_char packet[PACKETSZ], answer[PACKETSZ]; - char *host = hostbuf, *batchfile = filebuf; - char *r_dname, *cp, *startp, *endp, *svstartp; - char section[15], opcode[10]; - int i, c, n, n1, inside, lineno = 0, vc = 0, - debug = 0, r_size, r_section, r_opcode, - prompt = 0, ret = 0, stringtobin = 0; - int16_t r_class, r_type; - u_int32_t r_ttl; - struct map *mp; - ns_updrec *rrecp; - ns_updque listuprec; - struct in_addr hostaddr; - extern int getopt(); - extern char *optarg; - extern int optind, opterr, optopt; - ns_tsig_key key; - char *keyfile=NULL, *keyname=NULL, *p, *pp; - int file_major, file_minor, alg; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "dsvk:n:")) != -1) { - switch (c) { - case 'v': - vc = 1; - break; - case 'd': - debug = 1; - break; - case 's': - stringtobin = 1; - break; - case 'k': { - /* -k keydir:keyname */ - char *colon; - - if ((colon=strchr(optarg, ':'))==NULL) { - fprintf(stderr, "key option argument should be keydir:keyname\n"); - exit(1); - } - keyname=colon+1; - keyfile=optarg; - *colon='\0'; - break; - } - case 'n': - keyname=optarg; - break; - default: - usage(); - } - } - - INIT_LIST(listuprec); - - if (keyfile) { -#ifdef PARSE_KEYFILE - if ((fp=fopen(keyfile, "r"))==NULL) { - perror("open keyfile"); - exit(1); - } - /* now read the header info from the file */ - if ((i=fread(buf, 1, BUFSIZ, fp)) < 5) { - fclose(fp); - exit(1); - } - fclose(fp); - fp=NULL; - - p=buf; - - n=strlen(p); /* get length of strings */ - n1=strlen("Private-key-format: v"); - if (n1 > n || strncmp(buf, "Private-key-format: v", n1)) { - fprintf(stderr, "Invalid key file format\n"); - exit(1); /* not a match */ - } - p+=n1; /* advance pointer */ - sscanf((char *)p, "%d.%d", &file_major, &file_minor); - /* should do some error checking with these someday */ - while (*p++!='\n'); /* skip to end of line */ - - n=strlen(p); /* get length of strings */ - n1=strlen("Algorithm: "); - if (n1 > n || strncmp(p, "Algorithm: ", n1)) { - fprintf(stderr, "Invalid key file format\n"); - exit(1); /* not a match */ - } - p+=n1; /* advance pointer */ - if (sscanf((char *)p, "%d", &alg)!=1) { - fprintf(stderr, "Invalid key file format\n"); - exit(1); - } - while (*p++!='\n'); /* skip to end of line */ - - n=strlen(p); /* get length of strings */ - n1=strlen("Key: "); - if (n1 > n || strncmp(p, "Key: ", n1)) { - fprintf(stderr, "Invalid key file format\n"); - exit(1); /* not a match */ - } - p+=n1; /* advance pointer */ - pp=p; - while (*pp++!='\n'); /* skip to end of line, terminate it */ - *--pp='\0'; - - key.data=malloc(1024*sizeof(char)); - key.len=b64_pton(p, key.data, 1024); - - strcpy(key.name, keyname); - strcpy(key.alg, "HMAC-MD5.SIG-ALG.REG.INT"); -#else - /* use the dst* routines to parse the key files - * - * This requires that both the .key and the .private files - * exist in your cwd, so the keyfile parmeter here is - * assumed to be a path in which the K*.{key,private} files - * exist. - */ - DST_KEY *dst_key; - char cwd[PATH_MAX+1]; - - if (getcwd(cwd, PATH_MAX)==NULL) { - perror("unable to get current directory"); - exit(1); - } - if (chdir(keyfile)<0) { - fprintf(stderr, "unable to chdir to %s: %s\n", keyfile, - strerror(errno)); - exit(1); - } - - dst_init(); - dst_key = dst_read_key(keyname, - 0 /* not used for private keys */, - KEY_HMAC_MD5, DST_PRIVATE); - if (!dst_key) { - fprintf(stderr, "dst_read_key: error reading key\n"); - exit(1); - } - key.data=malloc(1024*sizeof(char)); - dst_key_to_buffer(dst_key, key.data, 1024); - key.len=dst_key->dk_key_size; - - strcpy(key.name, keyname); - strcpy(key.alg, "HMAC-MD5.SIG-ALG.REG.INT"); - - if (chdir(cwd)<0) { - fprintf(stderr, "unable to chdir to %s: %s\n", cwd, - strerror(errno)); - exit(1); - } -#endif - } - - if ((argc - optind) == 0) { - /* no file specified, read from stdin */ - ret = system("tty -s"); - if (ret == 0) /* terminal */ - prompt = 1; - else /* stdin redirect from a file or a pipe */ - prompt = 0; - } else { - /* file specified, open it */ - /* XXX - currently accepts only one filename */ - if ((fp = fopen(argv[optind], "r")) == NULL) { - fprintf(stderr, "error opening file: %s\n", argv[optind]); - exit (1); - } - } - for (;;) { - - inside = 1; - if (prompt) - fprintf(stdout, "> "); - if (!fp) - cp = fgets(buf, sizeof buf, stdin); - else - cp = fgets(buf, sizeof buf, fp); - if (cp == NULL) /* EOF */ - break; - lineno++; - - /* get rid of the trailing newline */ - n = strlen(buf); - buf[--n] = '\0'; - - startp = cp; - endp = strchr(cp, ';'); - if (endp != NULL) - endp--; - else - endp = cp + n - 1; - - /* verify section name */ - if (!getword_str(section, sizeof section, &startp, endp)) { - /* empty line */ - inside = 0; - } - if (inside) { - /* inside the same update packet, - * continue accumulating records */ - r_section = -1; - n1 = strlen(section); - if (section[n1-1] == ':') - section[--n1] = '\0'; - for (mp = section_strs; mp < section_strs+M_SECTION_CNT; mp++) - if (!strcasecmp(section, mp->token)) { - r_section = mp->val; - break; - } - if (r_section == -1) { - fprintf(stderr, "incorrect section name: %s\n", section); - exit (1); - } - if (r_section == S_ZONE) { - fprintf(stderr, "section ZONE not permitted\n"); - exit (1); - } - /* read operation code */ - if (!getword_str(opcode, sizeof opcode, &startp, endp)) { - fprintf(stderr, "failed to read operation code\n"); - exit (1); - } - r_opcode = -1; - if (opcode[0] == '{') { - n1 = strlen(opcode); - for (i = 0; i < n1; i++) - opcode[i] = opcode[i+1]; - if (opcode[n1-2] == '}') - opcode[n1-2] = '\0'; - } - for (mp = opcode_strs; mp < opcode_strs+M_OPCODE_CNT; mp++) { - if (!strcasecmp(opcode, mp->token)) { - r_opcode = mp->val; - break; - } - } - if (r_opcode == -1) { - fprintf(stderr, "incorrect operation code: %s\n", opcode); - exit (1); - } - /* read owner's domain name */ - if (!getword_str(dnbuf, sizeof dnbuf, &startp, endp)) { - fprintf(stderr, "failed to read owner name\n"); - exit (1); - } - r_dname = dnbuf; - r_ttl = (r_opcode == ADD) ? -1 : 0; - r_type = -1; - r_class = C_IN; /* default to IN */ - r_size = 0; - - (void) getword_str(buf2, sizeof buf2, &startp, endp); - - if (isdigit(buf2[0])) { /* ttl */ - r_ttl = strtoul(buf2, 0, 10); - if (errno == ERANGE && r_ttl == ULONG_MAX) { - fprintf(stderr, "oversized ttl: %s\n", buf2); - exit (1); - } - (void) getword_str(buf2, sizeof buf2, &startp, endp); - } - - if (buf2[0]) { /* possibly class */ - for (mp = class_strs; mp < class_strs+M_CLASS_CNT; mp++) { - if (!strcasecmp(buf2, mp->token)) { - r_class = mp->val; - (void) getword_str(buf2, sizeof buf2, &startp, endp); - break; - } - } - } - /* - * type and rdata field may or may not be required depending - * on the section and operation - */ - switch (r_section) { - case S_PREREQ: - if (r_ttl) { - fprintf(stderr, "nonzero ttl in prereq section: %ul\n", - r_ttl); - r_ttl = 0; - } - switch (r_opcode) { - case NXDOMAIN: - case YXDOMAIN: - if (buf2[0]) { - fprintf (stderr, "invalid field: %s, ignored\n", - buf2); - exit (1); - } - break; - case NXRRSET: - case YXRRSET: - if (buf2[0]) - for (mp = type_strs; mp < type_strs+M_TYPE_CNT; mp++) - if (!strcasecmp(buf2, mp->token)) { - r_type = mp->val; - break; - } - if (r_type == -1) { - fprintf (stderr, "invalid type for RRset: %s\n", - buf2); - exit (1); - } - if (r_opcode == NXRRSET) - break; - /* - * for RRset exists (value dependent) case, - * nonempty rdata field will be present. - * simply copy the whole string now and let - * res_update() interpret the various fields - * depending on type - */ - cp = startp; - while (cp <= endp && isspace(*cp)) - cp++; - r_size = endp - cp + 1; - break; - default: - fprintf (stderr, - "unknown operation in prereq section\"%s\"\n", - opcode); - exit (1); - } - break; - case S_UPDATE: - switch (r_opcode) { - case DELETE: - r_ttl = 0; - r_type = T_ANY; - /* read type, if specified */ - if (buf2[0]) - for (mp = type_strs; mp < type_strs+M_TYPE_CNT; mp++) - if (!strcasecmp(buf2, mp->token)) { - r_type = mp->val; - svstartp = startp; - (void) getword_str(buf2, sizeof buf2, - &startp, endp); - if (buf2[0]) /* unget preference */ - startp = svstartp; - break; - } - /* read rdata portion, if specified */ - cp = startp; - while (cp <= endp && isspace(*cp)) - cp++; - r_size = endp - cp + 1; - break; - case ADD: - if (r_ttl == -1) { - fprintf (stderr, - "ttl must be specified for record to be added: %s\n", buf); - exit (1); - } - /* read type */ - if (buf2[0]) - for (mp = type_strs; mp < type_strs+M_TYPE_CNT; mp++) - if (!strcasecmp(buf2, mp->token)) { - r_type = mp->val; - break; - } - if (r_type == -1) { - fprintf(stderr, - "invalid type for record to be added: %s\n", buf2); - exit (1); - } - /* read rdata portion */ - cp = startp; - while (cp < endp && isspace(*cp)) - cp++; - r_size = endp - cp + 1; - if (r_size <= 0) { - fprintf(stderr, - "nonempty rdata field needed to add the record at line %d\n", - lineno); - exit (1); - } - break; - default: - fprintf(stderr, - "unknown operation in update section \"%s\"\n", opcode); - exit (1); - } - break; - default: - fprintf(stderr, - "unknown section identifier \"%s\"\n", section); - exit (1); - } - - if ( !(rrecp = res_mkupdrec(r_section, r_dname, r_class, - r_type, r_ttl)) || - (r_size > 0 && !(rrecp->r_data = (u_char *)malloc(r_size))) ) { - if (rrecp) - res_freeupdrec(rrecp); - fprintf(stderr, "saverrec error\n"); - exit (1); - } - if (stringtobin) { - switch(r_opcode) { - case T_HINFO: - if (!getcharstring(buf,(char *)data,2,2,lineno)) - exit(1); - cp = data; - break; - case T_ISDN: - if (!getcharstring(buf,(char *)data,1,2,lineno)) - exit(1); - cp = data; - break; - case T_TXT: - if (!getcharstring(buf,(char *)data,1,0,lineno)) - exit(1); - cp = data; - break; - case T_X25: - if (!getcharstring(buf,(char *)data,1,1,lineno)) - exit(1); - cp = data; - break; - default: - break; - } - } - rrecp->r_opcode = r_opcode; - rrecp->r_size = r_size; - (void) strncpy((char *)rrecp->r_data, cp, r_size); - APPEND(listuprec, rrecp, r_link); - } else { /* end of an update packet */ - (void) res_ninit(&res); - if (vc) - res.options |= RES_USEVC | RES_STAYOPEN; - if (debug) - res.options |= RES_DEBUG; - if (!EMPTY(listuprec)) { - n = res_nupdate(&res, HEAD(listuprec), - keyfile != NULL ? &key : NULL); - if (n < 0) - fprintf(stderr, "failed update packet\n"); - while (!EMPTY(listuprec)) { - ns_updrec *tmprrecp = HEAD(listuprec); - - UNLINK(listuprec, tmprrecp, r_link); - if (tmprrecp->r_size != 0) - free((char *)tmprrecp->r_data); - res_freeupdrec(tmprrecp); - } - } - } - } /* for */ - return (0); -} - -static void -usage() { - fprintf(stderr, "Usage: %s [ -k keydir:keyname ] [-d] [-v] [file]\n", - progname); - exit(1); -} - -/* - * Get a whitespace delimited word from a string (not file) - * into buf. modify the start pointer to point after the - * word in the string. - */ -static int -getword_str(char *buf, int size, char **startpp, char *endp) { - char *cp; - int c; - - for (cp = buf; *startpp <= endp; ) { - c = **startpp; - if (isspace(c) || c == '\0') { - if (cp != buf) /* trailing whitespace */ - break; - else { /* leading whitespace */ - (*startpp)++; - continue; - } - } - (*startpp)++; - if (cp >= buf+size-1) - break; - *cp++ = (u_char)c; - } - *cp = '\0'; - return (cp != buf); -} - -#define MAXCHARSTRING 255 - -static int -getcharstring(char *buf, char *data, - int minfields, int maxfields, int lineno) -{ - int nfield = 0, n = 0, i; - - do { - nfield++; - i = 0; - if (*buf == '"') { - buf++; - while(buf[i] && buf[i] != '"') - i++; - } else { - while(isspace(*buf)) - i++; - } - if (i > MAXCHARSTRING) { - fprintf(stderr, - "%d: RDATA field %d too long", - lineno, nfield); - return(0); - } - if (n + i + 1 > MAXDATA) { - fprintf(stderr, - "%d: total RDATA too long", lineno); - return(0); - } - data[n]=i; - memmove(data + 1 + n, buf, i); - buf += i + 1; - n += i + 1; - while(*buf && isspace(*buf)) - buf++; - } while (nfield < maxfields && *buf); - - if (nfield < minfields) { - fprintf(stderr, - "%d: expected %d RDATA fields, only saw %d", - lineno, minfields, nfield); - return (0); - } - - return (n); -} |