summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in48
-rw-r--r--source3/configure.in118
-rw-r--r--source3/libaddns/addns.h32
-rw-r--r--source3/libaddns/dns.h521
-rw-r--r--source3/libaddns/dnserr.h74
-rw-r--r--source3/libaddns/dnsgss.c550
-rw-r--r--source3/libaddns/dnsrecord.c548
-rw-r--r--source3/libaddns/dnsrequest.c478
-rw-r--r--source3/libaddns/dnsresponse.c589
-rw-r--r--source3/libaddns/dnssign.c52
-rw-r--r--source3/libaddns/dnssock.c766
-rw-r--r--source3/libaddns/dnsupdate.c644
-rw-r--r--source3/libaddns/dnsuprequest.c428
-rw-r--r--source3/libaddns/dnsupresp.c397
-rw-r--r--source3/libaddns/dnsutils.c596
-rw-r--r--source3/libads/ldap.c6
-rw-r--r--source3/utils/net_ads.c179
-rw-r--r--source3/utils/net_dns.c99
18 files changed, 6110 insertions, 15 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 34217592c7..a82caa5d4a 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -39,6 +39,7 @@ IDMAP_LIBS=@IDMAP_LIBS@
KRB5LIBS=@KRB5_LIBS@
LDAP_LIBS=@LDAP_LIBS@
NSCD_LIBS=@NSCD_LIBS@
+UUID_LIBS=@UUID_LIBS@
INSTALLCMD=@INSTALL@
INSTALLLIBCMD_SH=@INSTALLLIBCMD_SH@
@@ -76,7 +77,6 @@ CONFIGLIBDIR = $(LIBDIR)/config
CONFIGDIR = @configdir@
VARDIR = @localstatedir@
MANDIR = @mandir@
-datarootdir = @datarootdir@
DATADIR = @datadir@
# The permissions to give the executables
@@ -116,7 +116,11 @@ LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@
LIBSMBSHAREMODES_MAJOR=0
LIBSMBSHAREMODES_MINOR=2
-FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/tdb/include @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) -D_SAMBA_BUILD_
+LIBADDNS=bin/libaddns.a @LIBADDNS_SHARED@
+LIBADDNS_MAJOR=0
+LIBADDNS_MINOR=1
+
+FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/tdb/include @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) -D_SAMBA_BUILD_ -I$(srcdir)/libaddns
FLAGS2 =
FLAGS3 =
FLAGS4 =
@@ -158,7 +162,7 @@ BIN_PROGS = $(BIN_PROGS1) $(BIN_PROGS2) $(BIN_PROGS3) @EXTRA_BIN_PROGS@
EVERYTHING_PROGS = bin/debug2html@EXEEXT@ bin/smbfilter@EXEEXT@ bin/talloctort@EXEEXT@ \
bin/log2pcap@EXEEXT@
-SHLIBS = @SHLIB_PROGS@ @LIBSMBCLIENT@ @LIBSMBSHAREMODES@ @LIBMSRPC@
+SHLIBS = @SHLIB_PROGS@ @LIBSMBCLIENT@ @LIBSMBSHAREMODES@ @LIBMSRPC@ @LIBADDNS@
PAM_MODULES = @PAM_MODULES@
@@ -205,8 +209,8 @@ PASSCHANGE_OBJ = libsmb/passchange.o
SOCKET_WRAPPER_OBJ = lib/socket_wrapper.o
LIBNDR_OBJ = libndr/ndr_basic.o libndr/ndr.o libndr/ndr_misc.o \
- libndr/ndr_sec_helper.o libndr/ndr_string.o libndr/sid.o
+TALLOC_OBJ = lib/talloc.o
RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o
LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
@@ -220,7 +224,7 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/util_str.o lib/clobber.o lib/util_sid.o lib/util_uuid.o \
lib/util_unistr.o lib/util_file.o lib/data_blob.o \
lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \
- lib/talloc.o lib/substitute.o lib/fsusage.o \
+ lib/substitute.o lib/fsusage.o \
lib/ms_fnmatch.o lib/select.o lib/messages.o \
lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
lib/md5.o lib/hmacmd5.o lib/arc4.o lib/iconv.o \
@@ -229,7 +233,7 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
lib/module.o lib/events.o lib/ldap_escape.o @CHARSET_STATIC@ \
lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o @SOCKWRAP@ \
- libads/krb5_errs.o lib/system_smbd.o lib/audit.o
+ libads/krb5_errs.o lib/system_smbd.o lib/audit.o $(TALLOC_OBJ)
LIB_DUMMY_OBJ = lib/dummysmbd.o lib/dummyroot.o
LIB_NONSMBD_OBJ = $(LIB_OBJ) $(LIB_DUMMY_OBJ)
@@ -244,6 +248,11 @@ PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o lib/sharesec.o
KRBCLIENT_OBJ = libads/kerberos.o libads/ads_status.o
+LIBADDNS_OBJ0 = libaddns/dnsrecord.o libaddns/dnsrequest.o libaddns/dnsresponse.o \
+ libaddns/dnsutils.o libaddns/dnssock.o libaddns/dnsuprequest.o \
+ libaddns/dnsupresp.o libaddns/dnsupdate.o libaddns/dnsgss.o
+LIBADDNS_OBJ = $(LIBADDNS_OBJ0) $(TALLOC_OBJ)
+
LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \
libads/krb5_setpw.o libads/ldap_user.o \
libads/ads_struct.o libads/kerberos_keytab.o \
@@ -580,11 +589,11 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_domain.o utils/net_help.o \
utils/net_rpc_service.o utils/net_rpc_registry.o utils/net_usershare.o \
utils/netlookup.o utils/net_sam.o utils/net_rpc_shell.o \
utils/net_util.o utils/net_rpc_sh_acct.o utils/net_rpc_audit.o \
- utils/passwd_util.o
+ utils/passwd_util.o utils/net_dns.o
NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
+ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(LIBADDNS_OBJ0)\
$(LIBMSRPC_OBJ) $(IDMAP_OBJ) \
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
$(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \
@@ -944,7 +953,7 @@ bin/smbctool@EXEEXT@: $(TOOL_OBJ) @BUILD_POPT@ bin/.dummy
bin/net@EXEEXT@: $(NET_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS)
+ @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS)
bin/profiles@EXEEXT@: $(PROFILES_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -1086,6 +1095,17 @@ bin/smbfilter@EXEEXT@: $(SMBFILTER_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+
+bin/libaddns.@SHLIBEXT@: $(LIBADDNS_OBJ:.o=.@PICSUFFIX@)
+ @echo Linking libaddns shared library $@
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBADDNS_OBJ:.o=.@PICSUFFIX@) $(LDFLAGS) $(LIBS) \
+ $(KRB5LIBS) $(UUID_LIBS)\
+ @SONAMEFLAG@`basename $@`.$(LIBADDNS_MAJOR)
+
+bin/libaddns.a: $(LIBADDNS_OBJ:.o=.@PICSUFFIX@)
+ @echo Linking libaddns non-shared library $@
+ @-$(AR) -rc $@ $(LIBADDNS_OBJ:.o=.@PICSUFFIX@)
+
bin/libsmbclient.@SHLIBEXT@: $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@)
@echo Linking libsmbclient shared library $@
@$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@) $(LDFLAGS) $(LIBS) \
@@ -1131,6 +1151,7 @@ bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS)
libsmbclient: $(LIBSMBCLIENT)
libsmbsharemodes: $(LIBSMBSHAREMODES)
libmsrpc: $(LIBMSRPC)
+libaddns: $(LIBADDNS)
bin/librpc_lsarpc.@SHLIBEXT@: $(RPC_LSA_OBJ)
@echo "Linking $@"
@@ -1535,6 +1556,11 @@ installlibsmbsharemodes: installdirs libsmbsharemodes
-$(INSTALLLIBCMD_SH) bin/libsmbsharemodes.@SHLIBEXT@ $(DESTDIR)$(LIBDIR)
-$(INSTALLLIBCMD_A) bin/libsmbsharemodes.a $(DESTDIR)$(LIBDIR)
+installlibaddns: installdirs libaddns
+ @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS) $(DESTDIR) $(LIBDIR)
+ -$(INSTALLLIBCMD_SH) bin/libaddns.@SHLIBEXT@ $(DESTDIR)$(LIBDIR)
+ -$(INSTALLLIBCMD_A) bin/libaddns.a $(DESTDIR)$(LIBDIR)
+
installpammodules: $(PAM_MODULES)
@$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS) $(DESTDIR) $(PAMMODULESDIR)
@for module in $(PAM_MODULES); do \
@@ -1647,6 +1673,10 @@ uninstalllibsmbsharemodes:
-$(UNINSTALLLIBCMD_SH) $(DESTDIR)$(LIBDIR)/libsmbsharemodes.@SHLIBEXT@
-$(UNINSTALLLIBCMD_A) $(DESTDIR)$(LIBDIR)/libsmbsharemodes.a
+uninstalllibaddns:
+ -$(UNINSTALLLIBCMD_SH) $(DESTDIR)$(LIBDIR)/libaddns.@SHLIBEXT@
+ -$(UNINSTALLLIBCMD_A) $(DESTDIR)$(LIBDIR)/libaddns.a
+
uninstallpammodules:
@for module in $(PAM_MODULES); do \
echo "Removing $(DESTDIR)/$(PAMMODULESDIR)/$${module}.@SHLIBEXT@ "; \
diff --git a/source3/configure.in b/source3/configure.in
index dc2f516139..160791eff7 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -259,6 +259,10 @@ AC_SUBST(INSTALL_LIBMSRPC)
AC_SUBST(UNINSTALL_LIBMSRPC)
AC_SUBST(LIBMSRPC_SHARED)
AC_SUBST(LIBMSRPC)
+AC_SUBST(INSTALL_LIBADDNS)
+AC_SUBST(UNINSTALL_LIBADDNS)
+AC_SUBST(LIBADDNS_SHARED)
+AC_SUBST(LIBADDNS)
AC_SUBST(INSTALL_LIBSMBCLIENT)
AC_SUBST(UNINSTALL_LIBSMBCLIENT)
AC_SUBST(LIBSMBCLIENT_SHARED)
@@ -3791,6 +3795,71 @@ fi
AC_CHECK_LIB_EXT(nscd, NSCD_LIBS, nscd_flush_cache)
+########################################################
+# Compile with DNS Updates support?
+
+with_dnsupdate_support=no
+AC_MSG_CHECKING([whether to enable DNS Updates support])
+
+AC_ARG_WITH(dnsupdate,
+[ --with-dnsupdate Enable DNS Updates support (default no)],
+[ case "$withval" in
+ yes|no)
+ with_dnsupdate_support=$withval
+ ;;
+ esac ])
+
+AC_MSG_RESULT($with_dnsupdate_support)
+
+if test x"$with_dnsupdate_support" != x"no"; then
+
+ ################################################################
+ # first test for Active Directory support being enabled
+ #if test x"$with_ads_support" = x"no"; then
+ # AC_MSG_ERROR(Active Directory support is required to enable DNS Update support)
+ # with_dnsupdate_support=no
+ #fi
+ ##################################################################
+ # then test for uuid.h (necessary to generate unique DNS keynames
+ # (uuid.h is required for this test)
+ AC_CHECK_HEADERS(uuid/uuid.h)
+
+ if test x"$ac_cv_header_uuid_uuid_h" != x"yes"; then
+ if test x"$with_dnsupdate_support" = x"yes"; then
+ AC_MSG_ERROR(uuid.h is needed to enable DNS Updates support)
+ else
+ AC_MSG_WARN(uuid.h is needed to enable DNS Updates support)
+ fi
+ with_dnsupdate_support=no
+ fi
+fi
+
+if test x"$with_dnsupdate_support" != x"no"; then
+ ac_save_LIBS=$LIBS
+
+ ########################################################
+ # now see if we can find the uuid libs in standard paths
+ AC_CHECK_LIB_EXT(uuid, UUID_LIBS, uuid_generate)
+
+ LIBS="$LIBS $UUID_LIBS"
+
+ if test x"$ac_cv_lib_ext_uuid_uuid_generate" = x"yes"; then
+ with_dnsupdate_support=yes
+ AC_DEFINE(WITH_DNS_UPDATES,1,[Whether to enable DNS Update support])
+ AC_MSG_CHECKING(whether UUID support is used)
+ AC_MSG_RESULT(yes)
+ else
+ if test x"$with_dnsupdate_support" = x"yes"; then
+ AC_MSG_ERROR(libuuid is needed to enable DNS Updates support)
+ else
+ AC_MSG_WARN(libuuid is needed to enable DNS Updates support)
+ fi
+ UUID_LIBS=""
+ with_dnsupdate_support=no
+ fi
+ LIBS=$ac_save_LIBS
+fi
+
#################################################
# check for automount support
AC_MSG_CHECKING(whether to use automount)
@@ -4408,6 +4477,52 @@ AC_ARG_WITH(libmsrpc,
#################################################
+# should we build libaddns?
+INSTALL_LIBADDNS=
+UNINSTALL_LIBADDNS=
+LIBADDNS_SHARED=
+LIBADDNS=
+AC_MSG_CHECKING(whether to build the libaddns shared library)
+AC_ARG_WITH(libaddns,
+[ --with-libaddns Build the libaddns shared library (default=yes if shared libs supported)],
+[ case "$withval" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ if test $BLDSHARED = true; then
+ LIBADDNS_SHARED=bin/libaddns.$SHLIBEXT
+ LIBADDNS=libaddns
+ AC_MSG_RESULT(yes)
+ else
+ enable_static=yes
+ AC_MSG_RESULT(no shared library support -- will supply static library)
+ fi
+ if test $enable_static = yes; then
+ LIBADDNS=libaddns
+ fi
+ INSTALL_LIBADDNS=installlibaddns
+ UNINSTALL_LIBADDNS=uninstalllibaddns
+ ;;
+ esac ],
+[
+# if unspecified, default is to built it if possible.
+ if test $BLDSHARED = true; then
+ LIBADDNS_SHARED=bin/libaddns.$SHLIBEXT
+ LIBADDNS=libaddns
+ AC_MSG_RESULT(yes)
+ else
+ enable_static=yes
+ AC_MSG_RESULT(no shared library support -- will supply static library)
+ fi
+ if test $enable_static = yes; then
+ LIBADDNS=libaddns
+ fi]
+ INSTALL_LIBADDNS=installlibaddns
+ UNINSTALL_LIBADDNS=uninstalllibaddns
+)
+
+#################################################
# should we build libsmbclient?
INSTALL_LIBSMBCLIENT=
UNINSTALL_LIBSMBCLIENT=
@@ -5719,6 +5834,9 @@ fi
if test x"$with_ldap_support" != x"no"; then
AC_MSG_RESULT([ LDAP_LIBS = $LDAP_LIBS])
fi
+if test x"$with_dnsupdate_support" != x"no"; then
+ AC_MSG_RESULT([ UUID_LIBS = $UUID_LIBS])
+fi
AC_MSG_RESULT([ AUTH_LIBS = $AUTH_LIBS])
#################################################
diff --git a/source3/libaddns/addns.h b/source3/libaddns/addns.h
new file mode 100644
index 0000000000..d7774537fe
--- /dev/null
+++ b/source3/libaddns/addns.h
@@ -0,0 +1,32 @@
+/*
+ Public Interface file for Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#ifndef _ADDNS_H
+#define _ADDNS_H
+
+
+#endif /* _ADDNS_H */
+
diff --git a/source3/libaddns/dns.h b/source3/libaddns/dns.h
new file mode 100644
index 0000000000..ec61dff23b
--- /dev/null
+++ b/source3/libaddns/dns.h
@@ -0,0 +1,521 @@
+/*
+ Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#ifndef _DNS_H
+#define _DNS_H
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <uuid/uuid.h>
+#include <krb5.h>
+
+#if HAVE_GSSAPI_H
+#include <gssapi.h>
+#elif HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif HAVE_GSSAPI_GSSAPI_GENERIC_H
+#include <gssapi/gssapi_generic.h>
+#endif
+
+#include <talloc.h>
+
+#define TALLOC(ctx, size) talloc_named_const(ctx, size, __location__)
+#define TALLOC_P(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
+#define TALLOC_ARRAY(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
+#define TALLOC_MEMDUP(ctx, ptr, size) _talloc_memdup(ctx, ptr, size, __location__)
+#define TALLOC_ZERO(ctx, size) _talloc_zero(ctx, size, __location__)
+#define TALLOC_ZERO_P(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
+#define TALLOC_ZERO_ARRAY(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
+#define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__)
+#define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type)
+#define TALLOC_FREE(ctx) do { if ((ctx) != NULL) {talloc_free(ctx); ctx=NULL;} } while(0)
+
+/*******************************************************************
+ Type definitions for int16, int32, uint16 and uint32. Needed
+ for Samba coding style
+*******************************************************************/
+
+#ifndef uint8
+# define uint8 unsigned char
+#endif
+
+#if !defined(int16) && !defined(HAVE_INT16_FROM_RPC_RPC_H)
+# if (SIZEOF_SHORT == 4)
+# define int16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16;
+# else /* SIZEOF_SHORT != 4 */
+# define int16 short
+# endif /* SIZEOF_SHORT != 4 */
+ /* needed to work around compile issue on HP-UX 11.x */
+# define _INT16 1
+#endif
+
+/*
+ * Note we duplicate the size tests in the unsigned
+ * case as int16 may be a typedef from rpc/rpc.h
+ */
+
+#if !defined(uint16) && !defined(HAVE_UINT16_FROM_RPC_RPC_H)
+# if (SIZEOF_SHORT == 4)
+# define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16;
+# else /* SIZEOF_SHORT != 4 */
+# define uint16 unsigned short
+# endif /* SIZEOF_SHORT != 4 */
+#endif
+
+#if !defined(int32) && !defined(HAVE_INT32_FROM_RPC_RPC_H)
+# if (SIZEOF_INT == 4)
+# define int32 int
+# elif (SIZEOF_LONG == 4)
+# define int32 long
+# elif (SIZEOF_SHORT == 4)
+# define int32 short
+# else
+ /* uggh - no 32 bit type?? probably a CRAY. just hope this works ... */
+# define int32 int
+# endif
+ /* needed to work around compile issue on HP-UX 11.x */
+# define _INT32 1
+#endif
+
+/*
+ * Note we duplicate the size tests in the unsigned
+ * case as int32 may be a typedef from rpc/rpc.h
+ */
+
+#if !defined(uint32) && !defined(HAVE_UINT32_FROM_RPC_RPC_H)
+# if (SIZEOF_INT == 4)
+# define uint32 unsigned int
+# elif (SIZEOF_LONG == 4)
+# define uint32 unsigned long
+# elif (SIZEOF_SHORT == 4)
+# define uint32 unsigned short
+# else
+ /* uggh - no 32 bit type?? probably a CRAY. just hope this works ... */
+# define uint32 unsigned
+# endif
+#endif
+
+/*
+ * check for 8 byte long long
+ */
+
+#if !defined(uint64)
+# if (SIZEOF_LONG == 8)
+# define uint64 unsigned long
+# elif (SIZEOF_LONG_LONG == 8)
+# define uint64 unsigned long long
+# endif /* don't lie. If we don't have it, then don't use it */
+#endif
+
+#include "dnserr.h"
+
+
+#define DNS_TCP 1
+#define DNS_UDP 2
+
+#define DNS_OPCODE_UPDATE 1
+
+#define BAIL_ON_ERROR(x) \
+ if ((x)){ \
+ goto error; \
+ }
+
+#define BAIL_ON_DNS_ERROR(x) \
+ if ( !ERR_DNS_IS_OK((x)) ) { \
+ goto error; \
+ }
+
+#define BAIL_ON_SEC_ERROR(dwMajorStatus) \
+ if ((dwMajorStatus!= GSS_S_COMPLETE)\
+ && (dwMajorStatus != GSS_S_CONTINUE_NEEDED)) {\
+ goto sec_error; \
+ }
+
+/* DNS Class Types */
+
+#define DNS_CLASS_IN 1
+#define DNS_CLASS_ANY 255
+#define DNS_CLASS_NONE 254
+
+/* DNS RR Types */
+
+#define DNS_RR_A 1
+
+#define DNS_TCP_PORT 53
+#define DNS_UDP_PORT 53
+
+#define QTYPE_A 1
+#define QTYPE_NS 2
+#define QTYPE_MD 3
+#define QTYPE_CNAME 5
+#define QTYPE_SOA 6
+#define QTYPE_ANY 255
+#define QTYPE_TKEY 249
+#define QTYPE_TSIG 250
+
+/*
+MF 4 a mail forwarder (Obsolete - use MX)
+CNAME 5 the canonical name for an alias
+SOA 6 marks the start of a zone of authority
+MB 7 a mailbox domain name (EXPERIMENTAL)
+MG 8 a mail group member (EXPERIMENTAL)
+MR 9 a mail rename domain name (EXPERIMENTAL)
+NULL 10 a null RR (EXPERIMENTAL)
+WKS 11 a well known service description
+PTR 12 a domain name pointer
+HINFO 13 host information
+MINFO 14 mailbox or mail list information
+MX 15 mail exchange
+TXT 16 text strings
+*/
+
+#define QR_QUERY 0x0000
+#define QR_RESPONSE 0x0001
+
+#define OPCODE_QUERY 0x00
+#define OPCODE_IQUERY 0x01
+#define OPCODE_STATUS 0x02
+
+#define AA 1
+
+#define RECURSION_DESIRED 0x01
+
+#define RCODE_NOERROR 0
+#define RCODE_FORMATERROR 1
+#define RCODE_SERVER_FAILURE 2
+#define RCODE_NAME_ERROR 3
+#define RCODE_NOTIMPLEMENTED 4
+#define RCODE_REFUSED 5
+
+#define SENDBUFFER_SIZE 65536
+#define RECVBUFFER_SIZE 65536
+
+#define DNS_ONE_DAY_IN_SECS 86400
+#define DNS_TEN_HOURS_IN_SECS 36000
+
+#define SOCKET_ERROR -1
+#define INVALID_SOCKET -1
+
+#define DNS_NO_ERROR 0
+#define DNS_FORMAT_ERROR 1
+#define DNS_SERVER_FAILURE 2
+#define DNS_NAME_ERROR 3
+#define DNS_NOT_IMPLEMENTED 4
+#define DNS_REFUSED 5
+
+typedef long HANDLE;
+typedef gss_ctx_id_t CtxtHandle, *PCtxtHandle;
+
+#ifndef _BOOL
+typedef int BOOL;
+
+#define _BOOL /* So we don't typedef BOOL again */
+#endif
+
+
+typedef struct dns_domain_label {
+ struct dns_domain_label *pNext;
+ char *pszLabel;
+ int32 dwLength;
+} DNS_DOMAIN_LABEL;
+
+typedef struct {
+ DNS_DOMAIN_LABEL *pLabelList;
+} DNS_DOMAIN_NAME;
+
+typedef struct {
+ DNS_DOMAIN_NAME *pDomainName;
+ int16 wQueryType;
+ int16 wQueryClass;
+} DNS_QUESTION_RECORD;
+
+
+typedef struct {
+ DNS_DOMAIN_NAME *pDomainName;
+ int16 wZoneType;
+ int16 wZoneClass;
+} DNS_ZONE_RECORD;
+
+
+typedef struct {
+ DNS_DOMAIN_NAME *pDomainName;
+ int16 wType;
+ int16 wClass;
+ int32 dwTTL;
+ int16 wRDataSize;
+ uint8 *pRData;
+} DNS_RR_HEADER;
+
+
+typedef struct {
+ uint8 *pDefData;
+} DNS_DEF_RDATA;
+
+typedef struct {
+ int16 wAlgorithmOffset;
+ int16 wInceptionOffset;
+ int16 wExpirationOffset;
+ int16 wModeOffset;
+ int16 wErrorOffset;
+ int16 wKeySizeOffset;
+ int16 wKeyDataOffset;
+ int16 wOtherSizeOffset;
+ int16 wOtherDataOffset;
+} DNS_TKEY_OFFSETS;
+
+typedef struct {
+ int16 wAlgorithmOffset;
+ int16 wTimeSignedOffset;
+ int16 wFudgeOffset;
+ int16 wMacSizeOffset;
+ int16 wMacDataOffset;
+ int16 wOriginalMessageIdOffset;
+ int16 wErrorOffset;
+ int16 wOtherSizeOffset;
+ int16 wOtherDataOffset;
+} DNS_TSIG_OFFSETS;
+
+
+typedef struct {
+ DNS_RR_HEADER RRHeader;
+ union {
+ DNS_TKEY_OFFSETS TKey;
+ DNS_TSIG_OFFSETS TSig;
+ } Offsets;
+ uint8 *pRData;
+} DNS_RR_RECORD;
+
+
+typedef struct {
+ int16 wIdentification;
+ int16 wParameter;
+ int16 wQuestions;
+ int16 wAnswers;
+ int16 wAuthoritys;
+ int16 wAdditionals;
+ DNS_QUESTION_RECORD **ppQuestionRRSet;
+ DNS_RR_RECORD **ppAnswerRRSet;
+ DNS_RR_RECORD **ppAuthorityRRSet;
+ DNS_RR_RECORD **ppAdditionalRRSet;
+} DNS_REQUEST;
+
+
+typedef struct {
+ int16 wIdentification;
+ int16 wParameter;
+ int16 wZones;
+ int16 wPRs;
+ int16 wUpdates;
+ int16 wAdditionals;
+ DNS_ZONE_RECORD **ppZoneRRSet;
+ DNS_RR_RECORD **ppPRRRSet;
+ DNS_RR_RECORD **ppUpdateRRSet;
+ DNS_RR_RECORD **ppAdditionalRRSet;
+} DNS_UPDATE_REQUEST;
+
+
+typedef struct {
+ int16 wIdentification;
+ int16 wParameter;
+ int16 wQuestions;
+ int16 wAnswers;
+ int16 wAuthoritys;
+ int16 wAdditionals;
+ DNS_QUESTION_RECORD **ppQuestionRRSet;
+ DNS_RR_RECORD **ppAnswerRRSet;
+ DNS_RR_RECORD **ppAuthorityRRSet;
+ DNS_RR_RECORD **ppAdditionalRRSet;
+ uint8 *pDNSOutBuffer;
+ int32 dwNumBytes;
+} DNS_RESPONSE;
+
+typedef struct {
+ int16 wIdentification;
+ int16 wParameter;
+ int16 wZones;
+ int16 wPRs;
+ int16 wUpdates;
+ int16 wAdditionals;
+ DNS_ZONE_RECORD **ppZoneRRSet;
+ DNS_RR_RECORD **ppPRRRSet;
+ DNS_RR_RECORD **ppUpdateRRSet;
+ DNS_RR_RECORD **ppAdditionalRRSet;
+ uint8 *pDNSOutBuffer;
+ int32 dwNumBytes;
+} DNS_UPDATE_RESPONSE;
+
+typedef struct {
+ int32 hType;
+ int s;
+ struct sockaddr RecvAddr;
+} DNS_CONNECTION_CONTEXT;
+
+typedef struct {
+ uint8 *pSendBuffer;
+ int32 dwBufferSize;
+ int32 dwBytesWritten;
+ int32 dwBufferOffset;
+} DNS_SENDBUFFER_CONTEXT;
+
+typedef struct {
+ uint8 *pRecvBuffer;
+ int32 dwBufferSize;
+ int32 dwBytesRecvd;
+ int32 dwBytesRead;
+} DNS_RECEIVEBUFFER_CONTEXT;
+
+/* from dnsutils.c */
+
+int32 DNSGenerateIdentifier( int16 * pwIdentifer );
+int32 DNSGetDomainNameLength( DNS_DOMAIN_NAME * pDomainName, int32 * pdwLength );
+int32 DNSCopyDomainName( uint8 * pBuffer, DNS_DOMAIN_NAME * pDomainName, int32 * pdwCopied );
+int32 DNSAllocateString( char *pszInputString, char **ppszOutputString );
+int32 DNSGenerateKeyName( char **pszKeyName );
+int32 DNSMakeRRHeader( DNS_RR_HEADER * pDNSRR, char *szOwnerName, int16 wType, int32 dwTTL );
+int32 DNSDomainNameFromString( char *pszDomainName, DNS_DOMAIN_NAME ** ppDomainName );
+int32 DNSAppendLabel( DNS_DOMAIN_LABEL * pLabelList, DNS_DOMAIN_LABEL * pLabel, DNS_DOMAIN_LABEL ** ppNewLabelList );
+int32 DNSGenerateKeyName( char **ppszKeyName );
+void DNSRecordGenerateOffsets( DNS_RR_RECORD * pDNSRecord );
+int32 MapDNSResponseCodes( int16 wResponseCode );
+int32 GetLastError( void );
+int32 WSAGetLastError( void );
+int32 DNSAllocateMemory(int32 dwSize, void * * ppMemory);
+int32 DNSReallocMemory(void * pMemory, void * * ppNewMemory, int32 dwSize);
+void DNSFreeMemory( void * pMemory );
+int32 DNSAllocateString(char *pszInputString, char **ppszOutputString);
+void DNSFreeString(char * pszString);
+void DNSFreeDomainName(DNS_DOMAIN_NAME *pDomainName);
+
+/* from dnsrecord.c */
+
+int32 DNSCreateDeleteRecord( char *szHost, int16 wClass, int16 wType, DNS_RR_RECORD ** ppDNSRecord );
+int32 DNSCreateARecord( char *szHost, int16 wClass, int16 wType, int32 dwIP, DNS_RR_RECORD ** ppDNSRecord );
+int32 DNSCreateTKeyRecord( char *szKeyName, uint8 * pKeyData, int16 dwKeyLen, DNS_RR_RECORD ** ppDNSRecord );
+int32 DNSCreateTSIGRecord( char *szKeyName, int32 dwTimeSigned, int16 wFudge, int16 wOriginalID, uint8 * pMac, int16 wMacSize, DNS_RR_RECORD ** ppDNSRecord );
+int32 DNSCreateQuestionRecord( char *pszQName, int16 wQType, int16 wQClass, DNS_QUESTION_RECORD ** ppDNSQuestionRecord );
+int32 DNSAddQuestionSection( DNS_REQUEST * pDNSRequest, DNS_QUESTION_RECORD * pDNSQuestion );
+int32 DNSAddAdditionalSection( DNS_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord );
+int32 DNSAddAnswerSection( DNS_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord );
+int32 DNSAddAuthoritySection( DNS_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord );
+int32 DNSCreateZoneRecord( char *pszZName, DNS_ZONE_RECORD ** ppDNSZoneRecord );
+int32 DNSFreeZoneRecord( DNS_ZONE_RECORD * pDNSZoneRecord );
+int32 DNSCreateNameInUseRecord( char *pszName, int32 qtype, struct in_addr *addr, DNS_RR_RECORD ** ppDNSRRRecord );
+int32 DNSCreateNameNotInUseRecord( char *pszName, int32 qtype, DNS_RR_RECORD ** ppDNSRRRecord );
+
+/* from dnsresponse.c */
+
+int32 DNSStdReceiveStdResponse( HANDLE hDNSHandle, DNS_RESPONSE ** ppDNSResponse );
+int32 DNSUnmarshallDomainName( HANDLE hRecvBuffer, DNS_DOMAIN_NAME ** ppDomainName );
+int32 DNSUnmarshallRRHeader( HANDLE hRecvBuffer, DNS_RR_HEADER * pRRHeader );
+int32 DNSUnmarshallRData( HANDLE hRecvBuffer, int32 dwSize, uint8 ** ppRData, int32 * pdwRead );
+int32 DNSUpdateGetResponseCode( DNS_UPDATE_RESPONSE * pDNSUpdateResponse, int32 * pdwResponseCode );
+
+/* from dnsrequest.c */
+
+int32 DNSStdSendMarshallSection( HANDLE hSendBuffer, DNS_RR_RECORD ** ppDNSAnswerRRRecords, int16 wAnswers );
+int32 DNSMarshallDomainName( HANDLE hSendBuffer, DNS_DOMAIN_NAME * pDomainName );
+int32 DNSMarshallRRHeader( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord );
+int32 DNSMarshallRData( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord );
+int32 DNSWriteDomainName( HANDLE hDNSHandle, DNS_DOMAIN_NAME * pDomainName );
+void DNSFreeRequest( DNS_REQUEST * pDNSRequest );
+int32 DNSStdAddQuestionSection( DNS_REQUEST * pDNSRequest, DNS_QUESTION_RECORD * pDNSQuestion );
+int32 DNSStdAddAdditionalSection( DNS_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord );
+int32 DNSStdCreateStdRequest( DNS_REQUEST ** ppDNSRequest );
+int32 DNSStdSendStdRequest2( HANDLE hDNSServer, DNS_REQUEST * pDNSRequest );
+
+/* from dnsuprequest.c */
+
+int32 DNSUpdateSendUpdateRequest2( HANDLE hSendBuffer, DNS_UPDATE_REQUEST * pDNSRequest );
+int32 DNSUpdateBuildRequestMessage( DNS_UPDATE_REQUEST * pDNSRequest, HANDLE * phSendBuffer );
+void DNSUpdateFreeRequest( DNS_UPDATE_REQUEST * pDNSRequest );
+int32 DNSWriteDomainName( HANDLE hDNSHandle, DNS_DOMAIN_NAME * pDomainName );
+void DNSUpdateFreeRequest( DNS_UPDATE_REQUEST * pDNSRequest );
+int32 DNSUpdateAddZoneSection( DNS_UPDATE_REQUEST * pDNSRequest, DNS_ZONE_RECORD * pDNSZone );
+int32 DNSUpdateAddAdditionalSection( DNS_UPDATE_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord );
+int32 DNSUpdateAddPRSection( DNS_UPDATE_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord );
+int32 DNSUpdateAddUpdateSection( DNS_UPDATE_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord );
+int32 DNSUpdateCreateUpdateRequest( DNS_UPDATE_REQUEST ** ppDNSRequest );
+
+/* from dnssock.c */
+
+DNS_ERROR DNSOpen( char *nameserver, int32 dwType, HANDLE * phDNSServer );
+int32 DNSReceiveBufferContext( HANDLE hDNSHandle, HANDLE hDNSRecvBuffer, int32 * pdwBytesRead );
+int32 DNSCreateSendBuffer( HANDLE * phDNSSendBuffer );
+int32 DNSMarshallBuffer( HANDLE hDNSSendBuffer, uint8 * pDNSSendBuffer, int32 dwBufferSize, int32 * pdwBytesWritten );;
+int32 DNSSendBufferContext( HANDLE hDNSServer, HANDLE hSendBuffer, int32 * pdwBytesSent );
+int32 DNSCreateReceiveBuffer( HANDLE * phDNSRecvBuffer );
+int32 DNSUnmarshallBuffer( HANDLE hDNSRecvBuffer, uint8 * pDNSRecvBuffer, int32 dwBufferSize, int32 * pdwBytesRead );
+int32 DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer, int16 wOffset, DNS_DOMAIN_NAME ** ppDomainName );
+int32 DNSReceiveBufferMoveBackIndex( HANDLE hRecvBuffer, int16 wOffset );
+void DNSFreeSendBufferContext( HANDLE hSendBuffer );
+int32 DNSGetSendBufferContextSize( HANDLE hSendBuffer );
+uint8 *DNSGetSendBufferContextBuffer( HANDLE hSendBuffer );
+
+/* from linux/dnsgss.c */
+
+int32 DNSVerifyResponseMessage_GSSSuccess( PCtxtHandle pGSSContext, DNS_RR_RECORD * pClientTKeyRecord, DNS_RESPONSE * pDNSResponse );
+int32 DNSVerifyResponseMessage_GSSContinue( PCtxtHandle pGSSContext, DNS_RR_RECORD * pClientTKeyRecord, DNS_RESPONSE * pDNSResponse, uint8 ** ppServerKeyData, int16 * pwServerKeyDataSize );
+int32 DNSResponseGetRCode( DNS_RESPONSE * pDNSResponse, int16 * pwRCode );
+int32 DNSResponseGetTSIGRecord( DNS_RESPONSE * pDNSResponse, DNS_RR_RECORD ** ppTSIGRecord );
+int32 DNSCompareTKeyRecord( DNS_RR_RECORD * pClientTKeyRecord, DNS_RR_RECORD * pTKeyRecord );
+int32 DNSBuildTKeyQueryRequest( char *szKeyName, uint8 * pKeyData, int32 dwKeyLen, DNS_REQUEST ** ppDNSRequest );
+int32 DNSResponseGetTKeyRecord( DNS_RESPONSE * pDNSResponse, DNS_RR_RECORD ** ppTKeyRecord );
+int32 DNSGetTKeyData( DNS_RR_RECORD * pTKeyRecord, uint8 ** ppKeyData, int16 * pwKeyDataSize );
+int32 DNSNegotiateSecureContext( HANDLE hDNSServer, char *szDomain, char *szServerName, char *szKeyName, PCtxtHandle pGSSContext );
+void display_status( const char *msg, OM_uint32 maj_stat, OM_uint32 min_stat );
+int32 DNSNegotiateContextAndSecureUpdate( HANDLE hDNSServer, char *szServiceName, char *szDomainName, char *szHost, int32 dwIPAddress );
+
+/* from linux/dnsupdate.c */
+
+int32 DNSSendUpdate( HANDLE hDNSServer, char *szDomainName, char *szHost, struct in_addr *iplist, int num_addrs, DNS_UPDATE_RESPONSE ** ppDNSUpdateResponse );
+int32 DNSSendSecureUpdate( HANDLE hDNSServer, PCtxtHandle pGSSContext, char *pszKeyName, char *szDomainName, char *szHost, int32 dwIP, DNS_UPDATE_RESPONSE ** ppDNSUpdateResponse );
+int32 DNSUpdateGenerateSignature( PCtxtHandle pGSSContext, DNS_UPDATE_REQUEST * pDNSUpdateRequest, char *pszKeyName );
+int32 DNSBuildSignatureBuffer( int32 dwMaxSignatureSize, uint8 ** ppSignature );
+int32 DNSBuildMessageBuffer( DNS_UPDATE_REQUEST * pDNSUpdateRequest, char *szKeyName, int32 * pdwTimeSigned, int16 * pwFudge, uint8 ** ppMessageBuffer, int32 * pdwMessageSize );
+int32 DNSClose( HANDLE hDNSUpdate );
+
+/* from dnsupresp.c */
+
+int32 DNSUpdateReceiveUpdateResponse( HANDLE hDNSHandle, DNS_UPDATE_RESPONSE ** ppDNSResponse );
+
+/* from dnssign.c */
+
+int32 DNSGenerateHash( CtxtHandle * gss_context, uint8 * pRequestBuffer, uint8 ** ppMAC, int32 * pdwMacLen );
+int32 BuildHashInputBuffer( DNS_REQUEST * pDNSRequest, int32 dwLength, uint8 ** ppHashInputBuffer, int32 * pdwHashInputBufferLen );
+int32 DNSStdValidateAndGetTSIGRecord( CtxtHandle * gss_context, DNS_RESPONSE * pDNSResponse, DNS_RR_RECORD ** ppDNSTSIGRecord );
+
+#endif /* _DNS_H */
diff --git a/source3/libaddns/dnserr.h b/source3/libaddns/dnserr.h
new file mode 100644
index 0000000000..eee1303c00
--- /dev/null
+++ b/source3/libaddns/dnserr.h
@@ -0,0 +1,74 @@
+/*
+ Error codes for Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#ifndef _DNSERR_H
+#define _DNSERR_H
+
+
+/* The Splint code analysis tool (http://www.splint.org.) doesn't
+ like immediate structures. */
+
+#ifdef _SPLINT_
+#undef HAVE_IMMEDIATE_STRUCTURES
+#endif
+
+/* Setup the DNS_ERROR typedef. Technique takes from nt_status.h */
+
+#if defined(HAVE_IMMEDIATE_STRUCTURES)
+typedef struct {uint32 v;} DNS_ERROR;
+#define ERROR_DNS(x) ((DNS_ERROR) { x })
+#define ERROR_DNS_V(x) ((x).v)
+#else
+typedef uint32 DNS_ERROR;
+#define ERROR_DNS(x) (x)
+#define ERROR_DNS_V(x) (x)
+#endif
+
+#define ERR_DNS_IS_OK(x) (ERROR_DNS_V(x) == 0)
+#define ERR_DNS_EQUAL(x,y) (ERROR_DNS_V(x) == ERROR_DNS_V(y))
+
+/*************************************************
+ * Define the error codes here
+ *************************************************/
+
+#define ERROR_DNS_SUCCESS ERROR_DNS(0)
+#define ERROR_DNS_RECORD_NOT_FOUND ERROR_DNS(1)
+#define ERROR_DNS_BAD_RESPONSE ERROR_DNS(2)
+#define ERROR_DNS_INVALID_PARAMETER ERROR_DNS(3)
+#define ERROR_DNS_NO_MEMORY ERROR_DNS(4)
+#define ERROR_DNS_INVALID_NAME_SERVER ERROR_DNS(5)
+#define ERROR_DNS_CONNECTION_FAILED ERROR_DNS(6)
+
+
+#define ERROR_BAD_RESPONSE 1
+#define ERROR_RECORD_NOT_FOUND 2
+#define ERROR_OUTOFMEMORY 8
+#if !defined(ERROR_INVALID_PARAMETER)
+#define ERROR_INVALID_PARAMETER 87
+#endif
+
+#endif /* _DNSERR_H */
+
diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c
new file mode 100644
index 0000000000..d710604b01
--- /dev/null
+++ b/source3/libaddns/dnsgss.c
@@ -0,0 +1,550 @@
+/*
+ Public Interface file for Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+#include <ctype.h>
+
+
+/*********************************************************************
+*********************************************************************/
+
+static int strupr( char *szDomainName )
+{
+ if ( !szDomainName ) {
+ return ( 0 );
+ }
+ while ( *szDomainName != '\0' ) {
+ *szDomainName = toupper( *szDomainName );
+ szDomainName++;
+ }
+ return ( 0 );
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSBuildTKeyQueryRequest( char *szKeyName,
+ uint8 * pKeyData,
+ int32 dwKeyLen, DNS_REQUEST ** ppDNSRequest )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSTKeyRecord = NULL;
+ DNS_REQUEST *pDNSRequest = NULL;
+ DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL;
+
+ dwError = DNSStdCreateStdRequest( &pDNSRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateQuestionRecord( szKeyName,
+ QTYPE_TKEY,
+ DNS_CLASS_IN,
+ &pDNSQuestionRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSStdAddQuestionSection( pDNSRequest, pDNSQuestionRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateTKeyRecord( szKeyName,
+ pKeyData,
+ ( int16 ) dwKeyLen, &pDNSTKeyRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSStdAddAdditionalSection( pDNSRequest, pDNSTKeyRecord );
+ BAIL_ON_ERROR( dwError );
+
+ *ppDNSRequest = pDNSRequest;
+
+ return dwError;
+
+ error:
+
+ *ppDNSRequest = NULL;
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSVerifyResponseMessage_GSSSuccess( PCtxtHandle pGSSContext,
+ DNS_RR_RECORD * pClientTKeyRecord,
+ DNS_RESPONSE * pDNSResponse )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pTKeyRecord = NULL;
+ DNS_RR_RECORD *pTSIGRecord = NULL;
+ int16 wRCode = 0;
+
+ dwError = DNSResponseGetRCode( pDNSResponse, &wRCode );
+ BAIL_ON_ERROR( dwError );
+
+ if ( wRCode != 0 ) {
+ dwError = ERROR_BAD_RESPONSE;
+ BAIL_ON_ERROR( dwError );
+
+ }
+
+ dwError = DNSResponseGetTKeyRecord( pDNSResponse, &pTKeyRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCompareTKeyRecord( pClientTKeyRecord, pTKeyRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSResponseGetTSIGRecord( pDNSResponse, &pTSIGRecord );
+ BAIL_ON_ERROR( dwError );
+
+/*
+ dwMajorStatus = GSS_VerifyMIC(
+ pDNSResponse->pDNSResponseBuffer,
+ pDNSResponse->dwNumBytes,
+ pDNSRRRecord->RData.TSIGRData.pMAC,
+ pDNSRRRecord->RData.TSIGRData.wMaxSize
+ )
+ BAIL_ON_ERROR(dwMajorStatus);*/
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSVerifyResponseMessage_GSSContinue( PCtxtHandle pGSSContext,
+ DNS_RR_RECORD * pClientTKeyRecord,
+ DNS_RESPONSE * pDNSResponse,
+ uint8 ** ppServerKeyData,
+ int16 * pwServerKeyDataSize )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pTKeyRecord = NULL;
+ int16 wRCode = 0;
+ uint8 *pServerKeyData = NULL;
+ int16 wServerKeyDataSize = 0;
+
+
+ dwError = DNSResponseGetRCode( pDNSResponse, &wRCode );
+ BAIL_ON_ERROR( dwError );
+ if ( wRCode != 0 ) {
+ dwError = ERROR_BAD_RESPONSE;
+ BAIL_ON_ERROR( dwError );
+
+ }
+
+ dwError = DNSResponseGetTKeyRecord( pDNSResponse, &pTKeyRecord );
+ BAIL_ON_ERROR( dwError );
+
+
+ dwError = DNSCompareTKeyRecord( pClientTKeyRecord, pTKeyRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSGetTKeyData( pTKeyRecord,
+ &pServerKeyData, &wServerKeyDataSize );
+ BAIL_ON_ERROR( dwError );
+
+ *ppServerKeyData = pServerKeyData;
+ *pwServerKeyDataSize = wServerKeyDataSize;
+
+ return dwError;
+
+ error:
+
+ *ppServerKeyData = NULL;
+ *pwServerKeyDataSize = 0;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSResponseGetRCode( DNS_RESPONSE * pDNSResponse, int16 * pwRCode )
+{
+ int32 dwError = 0;
+ int16 wnParameter = 0;
+ uint8 uChar = 0;
+
+ wnParameter = htons( pDNSResponse->wParameter );
+
+ /* Byte 0 is the most significate byte
+ Bit 12, 13, 14, 15 or Bit 4, 5, 6, 7 represent the RCode */
+
+ memcpy( &uChar, ( uint8 * ) & wnParameter + 1, 1 );
+ uChar >>= 4;
+ *pwRCode = ( int16 ) uChar;
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSResponseGetTKeyRecord( DNS_RESPONSE * pDNSResponse,
+ DNS_RR_RECORD ** ppTKeyRecord )
+{
+ int32 dwError = 0;
+ int16 wAnswers = 0;
+ DNS_RR_RECORD *pDNSRecord = NULL;
+ int32 i = 0;
+
+
+ wAnswers = pDNSResponse->wAnswers;
+ if ( !wAnswers ) {
+ dwError = ERROR_INVALID_PARAMETER;
+ BAIL_ON_ERROR( dwError );
+ }
+
+ for ( i = 0; i < wAnswers; i++ ) {
+ pDNSRecord = *( pDNSResponse->ppAnswerRRSet + i );
+ if ( pDNSRecord->RRHeader.wType == QTYPE_TKEY ) {
+ *ppTKeyRecord = pDNSRecord;
+ return dwError;
+ }
+ }
+ dwError = ERROR_RECORD_NOT_FOUND;
+
+ error:
+ *ppTKeyRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSResponseGetTSIGRecord( DNS_RESPONSE * pDNSResponse,
+ DNS_RR_RECORD ** ppTSIGRecord )
+{
+ int32 dwError = 0;
+ int16 wAdditionals = 0;
+ DNS_RR_RECORD *pDNSRecord = NULL;
+
+ int32 i = 0;
+
+ wAdditionals = pDNSResponse->wAdditionals;
+ if ( !wAdditionals ) {
+ dwError = ERROR_INVALID_PARAMETER;
+ BAIL_ON_ERROR( dwError );
+ }
+
+ for ( i = 0; i < wAdditionals; i++ ) {
+ pDNSRecord = *( pDNSResponse->ppAdditionalRRSet + i );
+ if ( pDNSRecord->RRHeader.wType == QTYPE_TSIG ) {
+ *ppTSIGRecord = pDNSRecord;
+ return dwError;
+ }
+ }
+ dwError = ERROR_RECORD_NOT_FOUND;
+
+ error:
+ *ppTSIGRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCompareTKeyRecord( DNS_RR_RECORD * pClientTKeyRecord,
+ DNS_RR_RECORD * pTKeyRecord )
+{
+ int32 dwError = 0;
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSNegotiateContextAndSecureUpdate( HANDLE hDNSServer,
+ char *szServiceName,
+ char *szDomainName,
+ char *szHost, int32 dwIPAddress )
+{
+ int32 dwError = 0;
+ char *pszKeyName = NULL;
+ CtxtHandle ContextHandle = 0;
+ CtxtHandle *pContextHandle = &ContextHandle;
+
+ dwError = DNSGenerateKeyName( &pszKeyName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSNegotiateSecureContext( hDNSServer, szDomainName, szHost,
+ pszKeyName, pContextHandle );
+ BAIL_ON_ERROR( dwError );
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSGetTKeyData( DNS_RR_RECORD * pTKeyRecord,
+ uint8 ** ppKeyData, int16 * pwKeyDataSize )
+{
+ int32 dwError = 0;
+ int16 wKeyDataSize = 0;
+ int16 wnKeyDataSize = 0;
+ int32 dwKeyDataSizeOffset = 0;
+ int32 dwKeyDataOffset = 0;
+ uint8 *pKeyData = NULL;
+
+ DNSRecordGenerateOffsets( pTKeyRecord );
+ dwKeyDataSizeOffset = pTKeyRecord->Offsets.TKey.wKeySizeOffset;
+ dwKeyDataOffset = pTKeyRecord->Offsets.TKey.wKeyDataOffset;
+ memcpy( &wnKeyDataSize, pTKeyRecord->pRData + dwKeyDataSizeOffset,
+ sizeof( int16 ) );
+ wKeyDataSize = ntohs( wnKeyDataSize );
+
+ dwError = DNSAllocateMemory( wKeyDataSize, ( void ** ) &pKeyData );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( pKeyData, pTKeyRecord->pRData + dwKeyDataOffset,
+ wKeyDataSize );
+
+ *ppKeyData = pKeyData;
+ *pwKeyDataSize = wKeyDataSize;
+
+ return dwError;
+
+
+ error:
+
+ *ppKeyData = NULL;
+ *pwKeyDataSize = 0;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSNegotiateSecureContext( HANDLE hDNSServer,
+ char *szDomain,
+ char *szServerName,
+ char *szKeyName, PCtxtHandle pGSSContext )
+{
+ int32 dwError = 0;
+ int32 dwMajorStatus = 0;
+ char szUpperCaseDomain[256];
+ char szTargetName[256];
+ DNS_ERROR dns_status;
+
+ gss_buffer_desc input_name;
+ gss_buffer_desc input_desc, output_desc;
+ DNS_REQUEST *pDNSRequest = NULL;
+ DNS_RESPONSE *pDNSResponse = NULL;
+ DNS_RR_RECORD *pClientTKeyRecord = NULL;
+ HANDLE hDNSTcpServer = ( HANDLE ) NULL;
+
+ uint8 *pServerKeyData = NULL;
+ int16 wServerKeyDataSize = 0;
+
+ OM_uint32 ret_flags = 0;
+
+ int32 dwMinorStatus = 0;
+ gss_name_t targ_name;
+ gss_cred_id_t creds;
+
+ krb5_principal host_principal;
+ krb5_context ctx = NULL;
+
+ gss_OID_desc nt_host_oid_desc =
+ { 10, ( char * ) ( ( void * ) "\052\206\110\206\367\022\001\002\002\002" ) };
+ gss_OID_desc krb5_oid_desc =
+ { 9, ( char * ) ( ( void * ) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" ) };
+
+ input_desc.value = NULL;
+ input_desc.length = 0;
+
+ dns_status = DNSOpen( szServerName, DNS_TCP, &hDNSTcpServer );
+ BAIL_ON_DNS_ERROR( dns_status );
+
+
+ memset( szUpperCaseDomain, 0, sizeof( szUpperCaseDomain ) );
+ memcpy( szUpperCaseDomain, szDomain, strlen( szDomain ) );
+ strupr( szUpperCaseDomain );
+
+ dwMajorStatus = gss_acquire_cred( ( OM_uint32 * ) & dwMinorStatus,
+ GSS_C_NO_NAME,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ GSS_C_INITIATE,
+ &creds, NULL, NULL );
+ BAIL_ON_SEC_ERROR( dwMajorStatus );
+ printf( "After gss_acquire_cred %d\n", dwMajorStatus );
+
+ sprintf( szTargetName, "dns/%s@%s", szServerName, szUpperCaseDomain );
+ printf( "%s\n", szTargetName );
+
+ krb5_init_context( &ctx );
+ krb5_parse_name( ctx, szTargetName, &host_principal );
+ krb5_free_context( ctx );
+
+ input_name.value = &host_principal;
+ input_name.length = sizeof( host_principal );
+
+ dwMajorStatus = gss_import_name( ( OM_uint32 * ) & dwMinorStatus,
+ &input_name,
+ &nt_host_oid_desc, &targ_name );
+ printf( "After gss_import_name %d\n", dwMajorStatus );
+ BAIL_ON_SEC_ERROR( dwMajorStatus );
+ printf( "After gss_import_name %d\n", dwMajorStatus );
+
+ memset( pGSSContext, 0, sizeof( CtxtHandle ) );
+ *pGSSContext = GSS_C_NO_CONTEXT;
+
+ do {
+
+ dwMajorStatus = gss_init_sec_context( ( OM_uint32 * ) &
+ dwMinorStatus, creds,
+ pGSSContext, targ_name,
+ &krb5_oid_desc,
+ GSS_C_REPLAY_FLAG |
+ GSS_C_MUTUAL_FLAG |
+ GSS_C_SEQUENCE_FLAG |
+ GSS_C_CONF_FLAG |
+ GSS_C_INTEG_FLAG |
+ GSS_C_DELEG_FLAG, 0,
+ NULL, &input_desc, NULL,
+ &output_desc,
+ &ret_flags, NULL );
+ display_status( "gss_init_context", dwMajorStatus,
+ dwMinorStatus );
+ BAIL_ON_SEC_ERROR( dwMajorStatus );
+ printf( "After gss_init_sec_context %d\n", dwMajorStatus );
+
+ switch ( dwMajorStatus ) {
+
+ case GSS_S_COMPLETE:
+ if ( output_desc.length != 0 ) {
+
+ dwError = DNSBuildTKeyQueryRequest( szKeyName,
+ output_desc.
+ value,
+ output_desc.
+ length,
+ &pDNSRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSStdSendStdRequest2( hDNSTcpServer,
+ pDNSRequest );
+ BAIL_ON_ERROR( dwError );
+
+
+ dwError =
+ DNSStdReceiveStdResponse
+ ( hDNSTcpServer, &pDNSResponse );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSVerifyResponseMessage_GSSSuccess
+ ( pGSSContext, pClientTKeyRecord,
+ pDNSResponse );
+ BAIL_ON_ERROR( dwError );
+ }
+ break;
+
+
+ case GSS_S_CONTINUE_NEEDED:
+ if ( output_desc.length != 0 ) {
+
+ dwError = DNSBuildTKeyQueryRequest( szKeyName,
+ output_desc.
+ value,
+ output_desc.
+ length,
+ &pDNSRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSStdSendStdRequest2( hDNSTcpServer,
+ pDNSRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSStdReceiveStdResponse
+ ( hDNSTcpServer, &pDNSResponse );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSVerifyResponseMessage_GSSContinue
+ ( pGSSContext, pClientTKeyRecord,
+ pDNSResponse, &pServerKeyData,
+ &wServerKeyDataSize );
+ BAIL_ON_ERROR( dwError );
+
+ input_desc.value = pServerKeyData;
+ input_desc.length = wServerKeyDataSize;
+ }
+ break;
+
+ default:
+ BAIL_ON_ERROR( dwError );
+ }
+
+ } while ( dwMajorStatus == GSS_S_CONTINUE_NEEDED );
+
+ /* If we arrive here, we have a valid security context */
+
+ sec_error:
+ error:
+
+ return dwError;
+
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static void display_status_1( const char *m, OM_uint32 code, int type )
+{
+ OM_uint32 maj_stat, min_stat;
+ gss_buffer_desc msg;
+ OM_uint32 msg_ctx;
+
+ msg_ctx = 0;
+ while ( 1 ) {
+ maj_stat = gss_display_status( &min_stat, code,
+ type, GSS_C_NULL_OID,
+ &msg_ctx, &msg );
+ fprintf( stdout, "GSS-API error %s: %s\n", m,
+ ( char * ) msg.value );
+ ( void ) gss_release_buffer( &min_stat, &msg );
+
+ if ( !msg_ctx )
+ break;
+ }
+}
+
+/*********************************************************************
+*********************************************************************/
+
+void display_status( const char *msg, OM_uint32 maj_stat, OM_uint32 min_stat )
+{
+ display_status_1( msg, maj_stat, GSS_C_GSS_CODE );
+ display_status_1( msg, min_stat, GSS_C_MECH_CODE );
+}
diff --git a/source3/libaddns/dnsrecord.c b/source3/libaddns/dnsrecord.c
new file mode 100644
index 0000000000..704d747ee9
--- /dev/null
+++ b/source3/libaddns/dnsrecord.c
@@ -0,0 +1,548 @@
+/*
+ Linux DNS client library implementation
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateDeleteRecord( char *szHost, int16 wClass,
+ int16 wType, DNS_RR_RECORD ** ppDNSRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( szHost, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRRRecord->RRHeader.dwTTL = 0;
+ pDNSRRRecord->RRHeader.wClass = wClass;
+ pDNSRRRecord->RRHeader.wType = wType;
+ pDNSRRRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRRRecord->RRHeader.wRDataSize = 0;
+
+ *ppDNSRecord = pDNSRRRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pDNSRRRecord );
+ }
+
+ *ppDNSRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateARecord( char *szHost, int16 wClass,
+ int16 wType, int32 dwIP, DNS_RR_RECORD ** ppDNSRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ uint8 *pRData = NULL;
+ int32 dwnIP = 0;
+
+ dwError = DNSDomainNameFromString( szHost, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRRRecord->RRHeader.wType = wType;
+ pDNSRRRecord->RRHeader.pDomainName = pDomainName;
+
+ pDNSRRRecord->RRHeader.wClass = wClass;
+ pDNSRRRecord->RRHeader.wRDataSize = 0;
+ pDNSRRRecord->RRHeader.dwTTL = 0;
+
+ if ( wClass != DNS_CLASS_ANY ) {
+ pDNSRRRecord->RRHeader.dwTTL = DNS_ONE_DAY_IN_SECS;
+ pDNSRRRecord->RRHeader.wRDataSize = sizeof( int32 );
+ dwError =
+ DNSAllocateMemory( sizeof( int32 ),
+ ( void ** ) &pRData );
+ dwnIP = htonl( dwIP );
+ memcpy( pRData, &dwnIP, sizeof( int32 ) );
+ pDNSRRRecord->pRData = pRData;
+ }
+
+ *ppDNSRecord = pDNSRRRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pDNSRRRecord );
+ }
+
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pRData );
+ }
+ *ppDNSRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateTKeyRecord( char *szKeyName, uint8 * pKeyData,
+ int16 wKeySize, DNS_RR_RECORD ** ppDNSRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRecord = NULL;
+ DNS_DOMAIN_NAME *pAlgorithmName = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ time_t t;
+
+ int32 dwRDataSize = 0;
+ int32 dwnInception, dwInception = 0;
+ int32 dwnExpiration, dwExpiration = 0;
+ int16 wnMode, wMode = 0;
+ int16 wnError, wError = 0;
+ int16 wnKeySize = 0;
+ int16 wnOtherSize, wOtherSize = 0;
+
+ int32 dwAlgorithmLen = 0;
+ int32 dwCopied = 0;
+ int32 dwOffset = 0;
+
+ uint8 *pRData = NULL;
+
+ char szTemp[20];
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSDomainNameFromString( szKeyName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ strncpy( szTemp, "gss.microsoft.com", sizeof( szTemp ) );
+ dwError = DNSDomainNameFromString( szTemp, &pAlgorithmName );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRecord->RRHeader.dwTTL = 0;
+ pDNSRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRecord->RRHeader.wClass = DNS_CLASS_ANY;
+ pDNSRecord->RRHeader.wType = QTYPE_TKEY;
+
+ time( &t );
+ dwExpiration = ( int32 ) t + DNS_ONE_DAY_IN_SECS;
+ dwInception = ( int32 ) t;
+ wError = 0;
+ wMode = 3;
+
+ dwError = DNSGetDomainNameLength( pAlgorithmName, &dwAlgorithmLen );
+ BAIL_ON_ERROR( dwError );
+
+ dwRDataSize = dwAlgorithmLen +
+ sizeof( dwExpiration ) + sizeof( dwInception ) +
+ sizeof( wError ) + sizeof( wMode ) + +sizeof( wError ) +
+ sizeof( wKeySize ) + wKeySize + sizeof( wOtherSize ) +
+ wOtherSize;
+
+ dwError = DNSAllocateMemory( dwRDataSize, ( void ** ) &pRData );
+ BAIL_ON_ERROR( dwError );
+
+ dwnInception = htonl( dwInception );
+ dwnExpiration = htonl( dwExpiration );
+ wnMode = htons( wMode );
+ wnError = htons( wError );
+ wnKeySize = htons( wKeySize );
+ wnOtherSize = htons( wOtherSize );
+
+ dwError = DNSCopyDomainName( pRData, pAlgorithmName, &dwCopied );
+ BAIL_ON_ERROR( dwError );
+ dwOffset += dwCopied;
+
+ memcpy( pRData + dwOffset, &dwnInception, sizeof( int32 ) );
+ dwOffset += sizeof( int32 );
+
+ memcpy( pRData + dwOffset, &dwnExpiration, sizeof( int32 ) );
+ dwOffset += sizeof( int32 );
+
+ memcpy( pRData + dwOffset, &wnMode, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &wnError, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &wnKeySize, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, pKeyData, wKeySize );
+ dwOffset += wKeySize;
+
+ memcpy( pRData + dwOffset, &wnOtherSize, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ pDNSRecord->RRHeader.wRDataSize = ( int16 ) dwRDataSize;
+
+ pDNSRecord->pRData = pRData;
+ *ppDNSRecord = pDNSRecord;
+
+ return dwError;
+
+ error:
+
+
+ if ( pDNSRecord ) {
+ DNSFreeMemory( pDNSRecord );
+ }
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+
+ if ( pAlgorithmName ) {
+ DNSFreeDomainName( pAlgorithmName );
+ }
+
+ *ppDNSRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateTSIGRecord( char *szKeyName, int32 dwTimeSigned,
+ int16 wFudge, int16 wOriginalID, uint8 * pMac,
+ int16 wMacSize, DNS_RR_RECORD ** ppDNSRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRecord = NULL;
+ DNS_DOMAIN_NAME *pAlgorithmName = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ time_t t;
+
+ int32 dwRDataSize = 0;
+
+ int16 wnFudge = 0;
+ int16 wnError = 0, wError = 0;
+ int16 wnMacSize = 0;
+ int16 wnOriginalID = 0;
+ int16 wnOtherLen = 0, wOtherLen = 0;
+
+ int32 dwAlgorithmLen = 0;
+ int32 dwCopied = 0;
+ int32 dwOffset = 0;
+
+ uint8 *pRData = NULL;
+
+ int32 dwnTimeSigned = 0;
+ int16 wnTimePrefix = 0;
+ int16 wTimePrefix = 0;
+
+ char szTemp[20];
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSDomainNameFromString( szKeyName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ strncpy( szTemp, "gss.microsoft.com", sizeof( szTemp ) );
+ dwError = DNSDomainNameFromString( szTemp, &pAlgorithmName );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRecord->RRHeader.dwTTL = 0;
+ pDNSRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRecord->RRHeader.wClass = DNS_CLASS_ANY;
+ pDNSRecord->RRHeader.wType = QTYPE_TSIG;
+
+ /* This needs to be a 48bit value - 6 octets. */
+
+ time( &t );
+
+ dwError = DNSGetDomainNameLength( pAlgorithmName, &dwAlgorithmLen );
+ BAIL_ON_ERROR( dwError );
+
+ dwRDataSize = dwAlgorithmLen + 6 + sizeof( wFudge ) + sizeof( wMacSize ) +
+ wMacSize + sizeof( wOriginalID ) + sizeof( wError ) +
+ sizeof( wOtherLen );
+
+ dwError = DNSAllocateMemory( dwRDataSize, ( void ** ) &pRData );
+ BAIL_ON_ERROR( dwError );
+
+ /* Convert t to 48 bit network order */
+
+ wnTimePrefix = htons( wTimePrefix );
+ dwnTimeSigned = htonl( dwTimeSigned );
+ wnFudge = htons( wFudge );
+ wnMacSize = htons( wMacSize );
+ wnOriginalID = htons( wOriginalID );
+ wnError = htons( wError );
+ wnOtherLen = htons( wOtherLen );
+
+ dwError = DNSCopyDomainName( pRData, pAlgorithmName, &dwCopied );
+ BAIL_ON_ERROR( dwError );
+ dwOffset += dwCopied;
+
+ memcpy( pRData + dwOffset, &wnTimePrefix, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &dwnTimeSigned, sizeof( int32 ) );
+ dwOffset += sizeof( int32 );
+
+ memcpy( pRData + dwOffset, &wnFudge, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+
+ memcpy( pRData + dwOffset, &wnMacSize, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, pMac, wMacSize );
+ dwOffset += wMacSize;
+
+ memcpy( pRData + dwOffset, &wnOriginalID, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &wnError, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &wnOtherLen, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ pDNSRecord->RRHeader.wRDataSize = ( int16 ) dwRDataSize;
+
+ pDNSRecord->pRData = pRData;
+ *ppDNSRecord = pDNSRecord;
+
+ return dwError;
+
+ error:
+
+
+ if ( pDNSRecord ) {
+ DNSFreeMemory( pDNSRecord );
+ }
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+
+ if ( pAlgorithmName ) {
+ DNSFreeDomainName( pAlgorithmName );
+ }
+
+ *ppDNSRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateQuestionRecord( char *pszQName, int16 wQType,
+ int16 wQClass,
+ DNS_QUESTION_RECORD ** ppDNSQuestionRecord )
+{
+ int32 dwError = 0;
+ DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( pszQName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_QUESTION_RECORD ),
+ ( void ** ) &pDNSQuestionRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSQuestionRecord->pDomainName = pDomainName;
+ pDNSQuestionRecord->wQueryClass = wQClass;
+ pDNSQuestionRecord->wQueryType = wQType;
+
+ *ppDNSQuestionRecord = pDNSQuestionRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSQuestionRecord ) {
+ DNSFreeMemory( pDNSQuestionRecord );
+ }
+ *ppDNSQuestionRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateZoneRecord( char *pszZName, DNS_ZONE_RECORD ** ppDNSZoneRecord )
+{
+ int32 dwError = 0;
+ DNS_ZONE_RECORD *pDNSZoneRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( pszZName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_ZONE_RECORD ),
+ ( void ** ) &pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSZoneRecord->pDomainName = pDomainName;
+ pDNSZoneRecord->wZoneClass = DNS_CLASS_IN;
+ pDNSZoneRecord->wZoneType = QTYPE_SOA;
+
+ *ppDNSZoneRecord = pDNSZoneRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSZoneRecord ) {
+ DNSFreeMemory( pDNSZoneRecord );
+ }
+ *ppDNSZoneRecord = NULL;
+ return dwError;
+}
+
+int32 DNSFreeZoneRecord( DNS_ZONE_RECORD * pDNSZoneRecord )
+{
+ int32 dwError = 0;
+
+ return dwError;
+
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateNameInUseRecord( char *pszName, int32 qtype,
+ struct in_addr * ip,
+ DNS_RR_RECORD * *ppDNSRRRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( pszName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRRRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRRRecord->RRHeader.dwTTL = 0;
+ pDNSRRRecord->RRHeader.wType = qtype;
+
+ if ( !ip ) {
+ pDNSRRRecord->RRHeader.wClass = DNS_CLASS_ANY;
+ pDNSRRRecord->RRHeader.wRDataSize = 0;
+ } else {
+ pDNSRRRecord->RRHeader.wClass = DNS_CLASS_IN;
+ pDNSRRRecord->RRHeader.wRDataSize = 4;
+ dwError =
+ DNSAllocateMemory( 4,
+ ( void ** ) &pDNSRRRecord->
+ pRData );
+ BAIL_ON_ERROR( dwError );
+ memcpy( pDNSRRRecord->pRData, &ip->s_addr, 4 );
+ }
+
+ *ppDNSRRRecord = pDNSRRRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pDNSRRRecord );
+ }
+ *ppDNSRRRecord = NULL;
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateNameNotInUseRecord( char *pszName, int32 qtype,
+ DNS_RR_RECORD * *ppDNSRRRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( pszName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRRRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRRRecord->RRHeader.wClass = DNS_CLASS_NONE;
+ pDNSRRRecord->RRHeader.wType = qtype;
+ pDNSRRRecord->RRHeader.dwTTL = 0;
+ pDNSRRRecord->RRHeader.wRDataSize = 0;
+
+ *ppDNSRRRecord = pDNSRRRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pDNSRRRecord );
+ }
+ *ppDNSRRRecord = NULL;
+ return dwError;
+
+}
+
diff --git a/source3/libaddns/dnsrequest.c b/source3/libaddns/dnsrequest.c
new file mode 100644
index 0000000000..3dd402981f
--- /dev/null
+++ b/source3/libaddns/dnsrequest.c
@@ -0,0 +1,478 @@
+/*
+ Linux DNS client library implementation
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdMarshallQuestionSection( HANDLE hSendBuffer,
+ DNS_QUESTION_RECORD ** ppDNSQuestionRecords,
+ int16 wQuestions )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ int32 dwRead = 0;
+ DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL;
+ int16 wnQueryType = 0;
+ int16 wnQueryClass = 0;
+
+ for ( i = 0; i < wQuestions; i++ ) {
+
+ pDNSQuestionRecord = *( ppDNSQuestionRecords + i );
+ dwError =
+ DNSMarshallDomainName( hSendBuffer,
+ pDNSQuestionRecord->
+ pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ wnQueryType = htons( pDNSQuestionRecord->wQueryType );
+ dwError =
+ DNSMarshallBuffer( hSendBuffer,
+ ( uint8 * ) & wnQueryType,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ wnQueryClass = htons( pDNSQuestionRecord->wQueryClass );
+ dwError =
+ DNSMarshallBuffer( hSendBuffer,
+ ( uint8 * ) & wnQueryClass,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSQuestionRecord++;
+ }
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdMarshallAnswerSection( HANDLE hSendBuffer,
+ DNS_RR_RECORD ** ppDNSAnswerRRRecords,
+ int16 wAnswers )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSAnswerRRRecord = NULL;
+
+
+ for ( i = 0; i < wAnswers; i++ ) {
+
+ pDNSAnswerRRRecord = *( ppDNSAnswerRRRecords + i );
+
+ dwError =
+ DNSMarshallRRHeader( hSendBuffer,
+ pDNSAnswerRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSMarshallRData( hSendBuffer, pDNSAnswerRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSAnswerRRRecord++;
+
+ }
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdMarshallAuthoritySection( HANDLE hSendBuffer,
+ DNS_RR_RECORD ** ppDNSAuthorityRRRecords,
+ int16 wAuthoritys )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+
+ DNS_RR_RECORD *pDNSAuthorityRRRecord = NULL;
+
+ for ( i = 0; i < wAuthoritys; i++ ) {
+
+ pDNSAuthorityRRRecord = *( ppDNSAuthorityRRRecords + i );
+
+ dwError =
+ DNSMarshallRRHeader( hSendBuffer,
+ pDNSAuthorityRRRecord );
+
+ dwError = DNSMarshallRData( hSendBuffer,
+ pDNSAuthorityRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ }
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdMarshallAdditionalSection( HANDLE hSendBuffer,
+ DNS_RR_RECORD ** ppDNSAdditionalsRRRecords,
+ int16 wAdditionals )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSAdditionalRRRecord = NULL;
+
+ for ( i = 0; i < wAdditionals; i++ ) {
+
+ pDNSAdditionalRRRecord = *( ppDNSAdditionalsRRRecords + i );
+
+ dwError =
+ DNSMarshallRRHeader( hSendBuffer,
+ pDNSAdditionalRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSMarshallRData( hSendBuffer,
+ pDNSAdditionalRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ }
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSBuildRequestMessage( DNS_REQUEST * pDNSRequest, HANDLE * phSendBuffer )
+{
+ int32 dwError = 0;
+ char DNSMessageHeader[12];
+ int16 wnIdentification = 0;
+ int16 wnParameter = 0;
+ int16 wnQuestions = 0;
+ int16 wnAnswers = 0;
+ int16 wnAuthoritys = 0;
+ int16 wnAdditionals = 0;
+ int32 dwRead = 0;
+ HANDLE hSendBuffer = ( HANDLE ) NULL;
+
+ dwError = DNSCreateSendBuffer( &hSendBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ wnIdentification = htons( pDNSRequest->wIdentification );
+ memcpy( DNSMessageHeader, ( char * ) &wnIdentification, 2 );
+
+ wnParameter = htons( pDNSRequest->wParameter );
+ memcpy( DNSMessageHeader + 2, ( char * ) &wnParameter, 2 );
+
+ wnQuestions = htons( pDNSRequest->wQuestions );
+ memcpy( DNSMessageHeader + 4, ( char * ) &wnQuestions, 2 );
+
+ wnAnswers = htons( pDNSRequest->wAnswers );
+ memcpy( DNSMessageHeader + 6, ( char * ) &wnAnswers, 2 );
+
+ wnAuthoritys = htons( pDNSRequest->wAuthoritys );
+ memcpy( DNSMessageHeader + 8, ( char * ) &wnAuthoritys, 2 );
+
+ wnAdditionals = htons( pDNSRequest->wAdditionals );
+ memcpy( DNSMessageHeader + 10, ( char * ) &wnAdditionals, 2 );
+
+ dwError =
+ DNSMarshallBuffer( hSendBuffer, ( uint8 * ) DNSMessageHeader,
+ 12, &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ if ( pDNSRequest->wQuestions ) {
+ dwError =
+ DNSStdMarshallQuestionSection( hSendBuffer,
+ pDNSRequest->
+ ppQuestionRRSet,
+ pDNSRequest->
+ wQuestions );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( pDNSRequest->wAnswers ) {
+ dwError =
+ DNSStdMarshallAnswerSection( hSendBuffer,
+ pDNSRequest->
+ ppAnswerRRSet,
+ pDNSRequest->wAnswers );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( pDNSRequest->wAuthoritys ) {
+ dwError =
+ DNSStdMarshallAuthoritySection( hSendBuffer,
+ pDNSRequest->
+ ppAuthorityRRSet,
+ pDNSRequest->
+ wAuthoritys );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( pDNSRequest->wAdditionals ) {
+ dwError =
+ DNSStdMarshallAdditionalSection( hSendBuffer,
+ pDNSRequest->
+ ppAdditionalRRSet,
+ pDNSRequest->
+ wAdditionals );
+ BAIL_ON_ERROR( dwError );
+ }
+#if 0
+ DNSDumpSendBufferContext( hSendBuffer );
+#endif
+ *phSendBuffer = hSendBuffer;
+
+ return dwError;
+
+ error:
+
+ if ( hSendBuffer ) {
+ DNSFreeSendBufferContext( hSendBuffer );
+ }
+
+ *phSendBuffer = ( HANDLE ) NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSStdSendStdRequest2( HANDLE hDNSServer, DNS_REQUEST * pDNSRequest )
+{
+ int32 dwError = 0;
+ int32 dwBytesSent = 0;
+ HANDLE hSendBuffer = ( HANDLE ) NULL;
+
+ dwError = DNSBuildRequestMessage( pDNSRequest, &hSendBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSSendBufferContext( hDNSServer, hSendBuffer, &dwBytesSent );
+ BAIL_ON_ERROR( dwError );
+
+ error:
+
+ if ( hSendBuffer ) {
+ DNSFreeSendBufferContext( hSendBuffer );
+ }
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSMarshallDomainName( HANDLE hSendBuffer, DNS_DOMAIN_NAME * pDomainName )
+{
+ int32 dwError = 0;
+ DNS_DOMAIN_LABEL *pTemp = NULL;
+ int32 dwLen = 0;
+ int32 dwSent = 0;
+ char uEndChar = 0;
+
+ pTemp = pDomainName->pLabelList;
+ while ( pTemp ) {
+ dwLen = ( int32 ) strlen( pTemp->pszLabel );
+ dwError =
+ DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & dwLen,
+ sizeof( char ), &dwSent );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSMarshallBuffer( hSendBuffer,
+ ( uint8 * ) pTemp->pszLabel, dwLen,
+ &dwSent );
+ BAIL_ON_ERROR( dwError );
+ pTemp = pTemp->pNext;
+ }
+ DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & uEndChar,
+ sizeof( char ), &dwSent );
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSMarshallRRHeader( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord )
+{
+ int32 dwError = 0;
+ int32 dwRead = 0;
+ int16 wnType = 0;
+ int16 wnClass = 0;
+ int16 wnRDataSize = 0;
+ int32 dwnTTL = 0;
+
+ dwError =
+ DNSMarshallDomainName( hSendBuffer,
+ pDNSRecord->RRHeader.pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ wnType = htons( pDNSRecord->RRHeader.wType );
+ dwError =
+ DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & wnType,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ wnClass = htons( pDNSRecord->RRHeader.wClass );
+ dwError =
+ DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & wnClass,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwnTTL = htonl( pDNSRecord->RRHeader.dwTTL );
+ dwError =
+ DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & dwnTTL,
+ sizeof( int32 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ wnRDataSize = htons( pDNSRecord->RRHeader.wRDataSize );
+ dwError =
+ DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & wnRDataSize,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSMarshallRData( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord )
+{
+ int32 dwError = 0;
+ int32 dwWritten = 0;
+
+ dwError =
+ DNSMarshallBuffer( hSendBuffer, pDNSRecord->pRData,
+ pDNSRecord->RRHeader.wRDataSize,
+ &dwWritten );
+ BAIL_ON_ERROR( dwError );
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSStdAddQuestionSection( DNS_REQUEST * pDNSRequest,
+ DNS_QUESTION_RECORD * pDNSQuestion )
+{
+ int32 dwNumQuestions = 0;
+ int32 dwError = 0;
+
+ dwNumQuestions = pDNSRequest->wQuestions;
+
+ dwError = DNSReallocMemory( ( uint8 * ) pDNSRequest->ppQuestionRRSet,
+ ( void ** ) &pDNSRequest->ppQuestionRRSet,
+ ( dwNumQuestions +
+ 1 ) * sizeof( DNS_QUESTION_RECORD * )
+ );
+ BAIL_ON_ERROR( dwError );
+
+ *( pDNSRequest->ppQuestionRRSet + dwNumQuestions ) = pDNSQuestion;
+
+ pDNSRequest->wQuestions += 1;
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSStdAddAdditionalSection( DNS_REQUEST * pDNSRequest,
+ DNS_RR_RECORD * pDNSRecord )
+{
+ int32 dwNumAdditionals = 0;
+ int32 dwError = 0;
+
+ dwNumAdditionals = pDNSRequest->wAdditionals;
+ dwError = DNSReallocMemory( pDNSRequest->ppAdditionalRRSet,
+ ( void ** ) &pDNSRequest->
+ ppAdditionalRRSet,
+ ( dwNumAdditionals +
+ 1 ) * sizeof( DNS_RR_RECORD * ) );
+ BAIL_ON_ERROR( dwError );
+
+ *( pDNSRequest->ppAdditionalRRSet + dwNumAdditionals ) = pDNSRecord;
+
+ pDNSRequest->wAdditionals += 1;
+
+ error:
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSStdCreateStdRequest( DNS_REQUEST ** ppDNSRequest )
+{
+ int32 dwError = 0;
+ DNS_REQUEST *pDNSRequest = NULL;
+
+#if 0
+ int16 wRecursionDesired = RECURSION_DESIRED;
+ int16 wParameter = QR_QUERY;
+ int16 wOpcode = OPCODE_QUERY;
+#endif
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_REQUEST ),
+ ( void ** ) &pDNSRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSGenerateIdentifier( &pDNSRequest->wIdentification );
+ BAIL_ON_ERROR( dwError );
+
+/*
+ wOpcode <<= 1;
+ wRecursionDesired <<= 7;
+ wParameter |= wOpcode;
+ wParameter |= wRecursionDesired;
+*/
+ pDNSRequest->wParameter = 0x00;
+
+ *ppDNSRequest = pDNSRequest;
+
+ return dwError;
+
+ error:
+
+ *ppDNSRequest = NULL;
+ return dwError;
+}
diff --git a/source3/libaddns/dnsresponse.c b/source3/libaddns/dnsresponse.c
new file mode 100644
index 0000000000..65a8853049
--- /dev/null
+++ b/source3/libaddns/dnsresponse.c
@@ -0,0 +1,589 @@
+/*
+ Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdAllocateResponse( DNS_RESPONSE ** ppDNSResponse )
+{
+ int32 dwError = 0;
+ DNS_RESPONSE *pDNSResponse = NULL;
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RESPONSE ),
+ ( void ** ) &pDNSResponse );
+ BAIL_ON_ERROR( dwError );
+
+ *ppDNSResponse = pDNSResponse;
+
+ return dwError;
+
+ error:
+
+ *ppDNSResponse = NULL;
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdUnmarshallQuestionSection( HANDLE hReceiveBuffer,
+ int16 wQuestions,
+ DNS_QUESTION_RECORD *
+ **pppDNSQuestionRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ int32 dwRead = 0;
+ DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL;
+ DNS_QUESTION_RECORD **ppDNSQuestionRecords = NULL;
+ int16 wnQueryClass = 0;
+ int16 wnQueryType = 0;
+
+
+ dwError =
+ DNSAllocateMemory( wQuestions *
+ sizeof( DNS_QUESTION_RECORD * ),
+ ( void ** ) &ppDNSQuestionRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wQuestions; i++ ) {
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_QUESTION_RECORD ),
+ ( void ** ) &pDNSQuestionRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallDomainName( hReceiveBuffer,
+ &pDNSQuestionRecord->
+ pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallBuffer( hReceiveBuffer,
+ ( uint8 * ) & wnQueryType,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pDNSQuestionRecord->wQueryType = ntohs( wnQueryType );
+
+ dwError =
+ DNSUnmarshallBuffer( hReceiveBuffer,
+ ( uint8 * ) & wnQueryClass,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pDNSQuestionRecord->wQueryClass = ntohs( wnQueryClass );
+
+ *( ppDNSQuestionRecords + i ) = pDNSQuestionRecord;
+ }
+
+ *pppDNSQuestionRecords = ppDNSQuestionRecords;
+ return dwError;
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdUnmarshallAnswerSection( HANDLE hReceiveBuffer,
+ int16 wAnswers,
+ DNS_RR_RECORD * **pppDNSAnswerRRRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_RR_RECORD **ppDNSAnswerRRRecords = NULL;
+ DNS_RR_HEADER RRHeader = { 0 };
+ DNS_RR_HEADER *pRRHeader = &RRHeader;
+ uint8 *pRData = NULL;
+ int32 dwRead = 0;
+
+ dwError = DNSAllocateMemory( wAnswers * sizeof( DNS_RR_RECORD * ),
+ ( void ** ) &ppDNSAnswerRRRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wAnswers; i++ ) {
+
+ memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) );
+ dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader );
+ BAIL_ON_ERROR( dwError );
+
+
+ dwError =
+ DNSUnmarshallRData( hReceiveBuffer,
+ pRRHeader->wRDataSize, &pRData,
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( &pDNSRRRecord->RRHeader, pRRHeader,
+ sizeof( DNS_RR_HEADER ) );
+ pDNSRRRecord->pRData = pRData;
+
+ *( ppDNSAnswerRRRecords + i ) = pDNSRRRecord;
+ }
+
+ *pppDNSAnswerRRRecords = ppDNSAnswerRRRecords;
+
+ return dwError;
+
+ error:
+
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdUnmarshallAuthoritySection( HANDLE hReceiveBuffer,
+ int16 wAuthoritys,
+ DNS_RR_RECORD * **pppDNSAuthorityRRRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_RR_RECORD **ppDNSAuthorityRRRecords = NULL;
+ DNS_RR_HEADER RRHeader = { 0 };
+ DNS_RR_HEADER *pRRHeader = &RRHeader;
+ uint8 *pRData = NULL;
+ int32 dwRead = 0;
+
+ dwError = DNSAllocateMemory( wAuthoritys * sizeof( DNS_RR_RECORD * ),
+ ( void ** ) &ppDNSAuthorityRRRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wAuthoritys; i++ ) {
+
+ memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) );
+ dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallRData( hReceiveBuffer,
+ pRRHeader->wRDataSize, &pRData,
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( &pDNSRRRecord->RRHeader, pRRHeader,
+ sizeof( DNS_RR_HEADER ) );
+ pDNSRRRecord->pRData = pRData;
+
+ *( ppDNSAuthorityRRRecords + i ) = pDNSRRRecord;
+ }
+
+ *pppDNSAuthorityRRRecords = ppDNSAuthorityRRRecords;
+
+ return dwError;
+
+ error:
+
+ return dwError;
+
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSStdUnmarshallAdditionalSection( HANDLE hReceiveBuffer,
+ int16 wAdditionals,
+ DNS_RR_RECORD *
+ **pppDNSAdditionalsRRRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_RR_RECORD **ppDNSAdditionalRRRecords = NULL;
+ DNS_RR_HEADER RRHeader = { 0 };
+ DNS_RR_HEADER *pRRHeader = &RRHeader;
+ uint8 *pRData = NULL;
+ int32 dwRead = 0;
+
+ dwError = DNSAllocateMemory( wAdditionals * sizeof( DNS_RR_RECORD * ),
+ ( void ** ) &ppDNSAdditionalRRRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wAdditionals; i++ ) {
+
+ memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) );
+ dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallRData( hReceiveBuffer,
+ pRRHeader->wRDataSize, &pRData,
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( &pDNSRRRecord->RRHeader, pRRHeader,
+ sizeof( DNS_RR_HEADER ) );
+ pDNSRRRecord->pRData = pRData;
+
+
+ *( ppDNSAdditionalRRRecords + i ) = pDNSRRRecord;
+ }
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSStdReceiveStdResponse( HANDLE hDNSHandle, DNS_RESPONSE ** ppDNSResponse )
+{
+ DNS_RESPONSE *pDNSResponse = NULL;
+ int32 dwError = 0;
+ int16 wnIdentification, wIdentification = 0;
+ int16 wnParameter, wParameter = 0;
+ int16 wnQuestions, wQuestions = 0;
+ int16 wnAnswers, wAnswers = 0;
+ int16 wnAdditionals, wAdditionals = 0;
+ int16 wnAuthoritys, wAuthoritys = 0;
+ int32 dwRead = 0;
+ DNS_RR_RECORD **ppDNSAnswerRecords = NULL;
+ DNS_RR_RECORD **ppDNSAdditionalRecords = NULL;
+ DNS_RR_RECORD **ppDNSAuthorityRecords = NULL;
+ DNS_QUESTION_RECORD **ppDNSQuestionRecords = NULL;
+ HANDLE hRecvBuffer = ( HANDLE ) NULL;
+
+ dwError = DNSCreateReceiveBuffer( &hRecvBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSReceiveBufferContext( hDNSHandle, hRecvBuffer, &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+#if 0
+ dwError = DNSDumpRecvBufferContext( hRecvBuffer );
+ BAIL_ON_ERROR( dwError );
+#endif
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer,
+ ( uint8 * ) & wnIdentification,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wIdentification = ntohs( wnIdentification );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnParameter,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wParameter = ntohs( wnParameter );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnQuestions,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wQuestions = ntohs( wnQuestions );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAnswers,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wAnswers = ntohs( wnAnswers );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAuthoritys,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wAuthoritys = ntohs( wnAuthoritys );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAdditionals,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wAdditionals = ntohs( wnAdditionals );
+
+
+ if ( wQuestions ) {
+ dwError =
+ DNSStdUnmarshallQuestionSection( hRecvBuffer,
+ wQuestions,
+ &ppDNSQuestionRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( wAnswers ) {
+ dwError =
+ DNSStdUnmarshallAnswerSection( hRecvBuffer, wAnswers,
+ &ppDNSAnswerRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( wAuthoritys ) {
+ dwError =
+ DNSStdUnmarshallAuthoritySection( hRecvBuffer,
+ wAuthoritys,
+ &ppDNSAuthorityRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( wAdditionals ) {
+ dwError =
+ DNSStdUnmarshallAdditionalSection( hRecvBuffer,
+ wAdditionals,
+ &ppDNSAdditionalRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ dwError = DNSStdAllocateResponse( &pDNSResponse );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSResponse->wIdentification = wIdentification;
+ pDNSResponse->wParameter = wParameter;
+ pDNSResponse->wQuestions = wQuestions;
+ pDNSResponse->wAnswers = wAnswers;
+ pDNSResponse->wAuthoritys = wAuthoritys;
+ pDNSResponse->wAdditionals = wAdditionals;
+
+ pDNSResponse->ppQuestionRRSet = ppDNSQuestionRecords;
+ pDNSResponse->ppAnswerRRSet = ppDNSAnswerRecords;
+ pDNSResponse->ppAuthorityRRSet = ppDNSAuthorityRecords;
+ pDNSResponse->ppAdditionalRRSet = ppDNSAdditionalRecords;
+
+ *ppDNSResponse = pDNSResponse;
+
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUnmarshallDomainName( HANDLE hRecvBuffer, DNS_DOMAIN_NAME ** ppDomainName )
+{
+ int32 dwError = 0;
+ DNS_DOMAIN_LABEL *pLabel = NULL;
+ DNS_DOMAIN_LABEL *pLabelList = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ char *pszLabel = NULL;
+ char szLabel[65];
+ uint8 uLen = 0;
+ int32 dwRead = 0;
+ uint8 uLen1, uLen2 = 0;
+ int16 wnOffset, wOffset = 0;
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, &uLen1, sizeof( char ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ if ( uLen1 & 0xC0 ) {
+
+ uLen1 |= 0x3F;
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, &uLen2,
+ sizeof( char ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( ( uint8 * ) & wnOffset, &uLen1, sizeof( char ) );
+ memcpy( ( uint8 * ) & wnOffset + 1, &uLen2, sizeof( char ) );
+ wOffset = ntohs( wnOffset );
+
+ dwError =
+ DNSUnmarshallDomainNameAtOffset( hRecvBuffer, wOffset,
+ &pDomainName );
+ BAIL_ON_ERROR( dwError );
+ *ppDomainName = pDomainName;
+
+ return dwError;
+
+ } else {
+
+ dwError = DNSReceiveBufferMoveBackIndex( hRecvBuffer, 1 );
+ BAIL_ON_ERROR( dwError );
+
+ while ( 1 ) {
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, &uLen,
+ sizeof( char ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ if ( uLen == 0 ) {
+ break;
+ }
+
+ memset( szLabel, 0, 65 );
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer,
+ ( uint8 * ) szLabel,
+ uLen, &dwRead );
+
+ dwError = DNSAllocateString( szLabel, &pszLabel );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ),
+ ( void ** ) &pLabel );
+ BAIL_ON_ERROR( dwError );
+
+ pLabel->pszLabel = pszLabel;
+ dwError =
+ DNSAppendLabel( pLabelList, pLabel,
+ &pLabelList );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ }
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ),
+ ( void ** ) &pDomainName );
+ BAIL_ON_ERROR( dwError );
+ pDomainName->pLabelList = pLabelList;
+
+ *ppDomainName = pDomainName;
+
+ return dwError;
+
+ error:
+
+ *ppDomainName = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUnmarshallRRHeader( HANDLE hRecvBuffer, DNS_RR_HEADER * pRRHeader )
+{
+ int32 dwError = 0;
+ int32 dwRead = 0;
+ int16 wnType = 0;
+ int16 wnClass = 0;
+ int16 wnRDataSize = 0;
+ int32 dwnTTL = 0;
+
+ dwError =
+ DNSUnmarshallDomainName( hRecvBuffer,
+ &pRRHeader->pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnType,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pRRHeader->wType = ntohs( wnType );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnClass,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pRRHeader->wClass = ntohs( wnClass );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & dwnTTL,
+ sizeof( int32 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pRRHeader->dwTTL = ntohl( dwnTTL );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnRDataSize,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pRRHeader->wRDataSize = htons( wnRDataSize );
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUnmarshallRData( HANDLE hRecvBuffer,
+ int32 dwSize, uint8 ** ppRData, int32 * pdwRead )
+{
+ int32 dwError = 0;
+ uint8 *pMemory = NULL;
+
+ dwError = DNSAllocateMemory( dwSize, ( void ** ) &pMemory );
+ BAIL_ON_ERROR( dwError );
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) pMemory, dwSize,
+ pdwRead );
+ BAIL_ON_ERROR( dwError );
+
+ *ppRData = pMemory;
+
+ return dwError;
+
+ error:
+
+ if ( pMemory ) {
+ DNSFreeMemory( pMemory );
+ }
+
+ *ppRData = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateGetResponseCode( DNS_UPDATE_RESPONSE * pDNSUpdateResponse,
+ int32 * pdwResponseCode )
+{
+ int32 dwError = 0;
+
+ *pdwResponseCode =
+ MapDNSResponseCodes( pDNSUpdateResponse->wParameter );
+
+ return dwError;
+}
+
diff --git a/source3/libaddns/dnssign.c b/source3/libaddns/dnssign.c
new file mode 100644
index 0000000000..b7989c6b1d
--- /dev/null
+++ b/source3/libaddns/dnssign.c
@@ -0,0 +1,52 @@
+/*
+ Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSStdValidateAndGetTSIGRecord( CtxtHandle * gss_context,
+ DNS_RESPONSE * pDNSResponse,
+ DNS_RR_RECORD ** ppDNSTSIGRecord )
+{
+ int32 dwError = 0;
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateValidateAndGetTSIGRecord( CtxtHandle * gss_context,
+ DNS_UPDATE_RESPONSE * pDNSUpdateResponse,
+ DNS_RR_RECORD ** ppDNSTSIGRecord )
+{
+ int32 dwError = 0;
+
+ return dwError;
+}
diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c
new file mode 100644
index 0000000000..0af30cc1be
--- /dev/null
+++ b/source3/libaddns/dnssock.c
@@ -0,0 +1,766 @@
+/*
+ Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+
+/********************************************************************
+********************************************************************/
+
+static DNS_ERROR DNSTCPOpen( char *nameserver, HANDLE * phDNSServer )
+{
+ DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER;
+ int sockServer;
+ unsigned long ulAddress;
+ struct hostent *pHost;
+ struct sockaddr_in s_in;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) {
+ return ERROR_DNS_NO_MEMORY;
+ }
+
+ if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) {
+ if ( (pHost = gethostbyname( nameserver )) == NULL ) {
+ dwError = ERROR_DNS_INVALID_NAME_SERVER;
+ BAIL_ON_DNS_ERROR( dwError );
+ }
+ memcpy( &ulAddress, pHost->h_addr, pHost->h_length );
+ }
+
+ if ( (sockServer = socket( PF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET ) {
+ dwError = ERROR_DNS_NO_MEMORY;
+ BAIL_ON_DNS_ERROR( dwError );
+ }
+
+ s_in.sin_family = AF_INET;
+ s_in.sin_addr.s_addr = ulAddress;
+ s_in.sin_port = htons( DNS_TCP_PORT );
+
+ if ( (connect( sockServer, &s_in, sizeof( s_in ))) == SOCKET_ERROR ) {
+ dwError = ERROR_DNS_CONNECTION_FAILED;
+ BAIL_ON_DNS_ERROR( dwError );
+ }
+
+ pDNSContext->s = sockServer;
+ pDNSContext->hType = DNS_TCP;
+
+ *phDNSServer = ( HANDLE ) pDNSContext;
+
+ dwError = ERROR_DNS_SUCCESS;
+
+ return dwError;
+
+error:
+ TALLOC_FREE( pDNSContext );
+ *phDNSServer = ( HANDLE ) NULL;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static DNS_ERROR DNSUDPOpen( char *nameserver, HANDLE * phDNSServer )
+{
+ DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER;
+ int SendSocket;
+ unsigned long ulAddress;
+ struct hostent *pHost;
+ struct sockaddr_in RecvAddr;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) {
+ return ERROR_DNS_NO_MEMORY;
+ }
+
+ if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) {
+ if ( (pHost = gethostbyname( nameserver )) == NULL ) {
+ dwError = ERROR_DNS_INVALID_NAME_SERVER;
+ BAIL_ON_DNS_ERROR( dwError );
+ }
+ memcpy( &ulAddress, pHost->h_addr, pHost->h_length );
+ }
+
+ /* Create a socket for sending data */
+
+ SendSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
+
+ /* Set up the RecvAddr structure with the IP address of
+ the receiver (in this example case "123.456.789.1")
+ and the specified port number. */
+
+ RecvAddr.sin_family = AF_INET;
+ RecvAddr.sin_port = htons( DNS_UDP_PORT );
+ RecvAddr.sin_addr.s_addr = ulAddress;
+
+ pDNSContext->s = SendSocket;
+ pDNSContext->hType = DNS_UDP;
+ memcpy( &pDNSContext->RecvAddr, &RecvAddr, sizeof( struct sockaddr_in ) );
+
+ *phDNSServer = ( HANDLE ) pDNSContext;
+
+ dwError = ERROR_DNS_SUCCESS;
+
+ return dwError;
+
+error:
+ TALLOC_FREE( pDNSContext );
+ *phDNSServer = ( HANDLE ) NULL;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+DNS_ERROR DNSOpen( char *nameserver, int32 dwType, HANDLE * phDNSServer )
+{
+ switch ( dwType ) {
+ case DNS_TCP:
+ return DNSTCPOpen( nameserver, phDNSServer );
+ case DNS_UDP:
+ return DNSUDPOpen( nameserver, phDNSServer );
+ }
+
+ return ERROR_DNS_INVALID_PARAMETER;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSSendTCPRequest( HANDLE hDNSHandle,
+ uint8 * pDNSSendBuffer,
+ int32 dwBufferSize, int32 * pdwBytesSent )
+{
+ int32 dwError = 0;
+ int32 dwBytesSent = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+
+ dwBytesSent = send( pDNSContext->s, pDNSSendBuffer, dwBufferSize, 0 );
+ if ( dwBytesSent == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ *pdwBytesSent = dwBytesSent;
+
+ return dwError;
+
+ error:
+ *pdwBytesSent = 0;
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSSendUDPRequest( HANDLE hDNSHandle,
+ uint8 * pDNSSendBuffer,
+ int32 dwBufferSize, int32 * pdwBytesSent )
+{
+ int32 dwError = 0;
+ int32 dwBytesSent = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+
+ dwBytesSent = sendto( pDNSContext->s,
+ pDNSSendBuffer,
+ dwBufferSize,
+ 0,
+ ( struct sockaddr * ) & pDNSContext->RecvAddr,
+ sizeof( pDNSContext->RecvAddr )
+ );
+ if ( dwBytesSent == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ } else {
+ *pdwBytesSent = dwBytesSent;
+ }
+
+ return dwError;
+
+ error:
+ *pdwBytesSent = 0;
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSSelect( HANDLE hDNSHandle )
+{
+ int32 dwError = 0;
+ fd_set rfds;
+ struct timeval tv;
+ int32 dwNumSockets = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+ FD_ZERO( &rfds );
+ FD_SET( pDNSContext->s, &rfds );
+
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+ dwNumSockets = select( pDNSContext->s + 1, &rfds, NULL, NULL, &tv );
+ if ( dwNumSockets == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( !dwNumSockets ) {
+#ifndef WIN32
+ dwError = ETIMEDOUT;
+#elif
+ dwError = WSAETIMEDOUT;
+#endif
+ }
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSTCPReceiveBufferContext( HANDLE hDNSHandle,
+ HANDLE hDNSRecvBuffer, int32 * pdwBytesRead )
+{
+ int32 dwError = 0;
+ int32 dwRead = 0;
+ int16 wBytesToRead = 0;
+ int16 wnBytesToRead = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+ pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer;
+
+ dwError = DNSSelect( hDNSHandle );
+ BAIL_ON_ERROR( dwError );
+
+ dwRead = recv( pDNSContext->s, ( char * ) &wnBytesToRead,
+ sizeof( int16 ), 0 );
+ if ( dwRead == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ wBytesToRead = ntohs( wnBytesToRead );
+
+ dwError = DNSSelect( hDNSHandle );
+ BAIL_ON_ERROR( dwError );
+
+ dwRead = recv( pDNSContext->s,
+ ( char * ) pDNSRecvContext->pRecvBuffer, wBytesToRead,
+ 0 );
+ if ( dwRead == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ pDNSRecvContext->dwBytesRecvd = dwRead;
+
+ *pdwBytesRead = ( int32 ) dwRead;
+
+ return dwError;
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSUDPReceiveBufferContext( HANDLE hDNSHandle,
+ HANDLE hDNSRecvBuffer, int32 * pdwBytesRead )
+{
+ int32 dwError = 0;
+ int32 dwRead = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+ pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer;
+
+ dwError = DNSSelect( hDNSHandle );
+ BAIL_ON_ERROR( dwError );
+
+ dwRead = recv( pDNSContext->s,
+ ( char * ) pDNSRecvContext->pRecvBuffer, 512, 0 );
+ if ( dwRead == SOCKET_ERROR ) {
+ dwError = WSAGetLastError( );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ pDNSRecvContext->dwBytesRecvd = dwRead;
+
+ *pdwBytesRead = ( int32 ) dwRead;
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSReceiveBufferContext( HANDLE hDNSHandle,
+ HANDLE hDNSRecvBuffer, int32 * pdwBytesRead )
+{
+ int32 dwError = 0;
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle;
+
+ switch ( pDNSContext->hType ) {
+ case DNS_TCP:
+ dwError =
+ DNSTCPReceiveBufferContext( hDNSHandle,
+ hDNSRecvBuffer,
+ pdwBytesRead );
+ break;
+ case DNS_UDP:
+ dwError =
+ DNSUDPReceiveBufferContext( hDNSHandle,
+ hDNSRecvBuffer,
+ pdwBytesRead );
+ break;
+ }
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSCreateSendBuffer( HANDLE * phDNSSendBuffer )
+{
+ int32 dwError = 0;
+ DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL;
+ uint8 *pSendBuffer = NULL;
+
+ dwError = DNSAllocateMemory( sizeof( DNS_SENDBUFFER_CONTEXT ),
+ ( void ** ) &pDNSContext );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( SENDBUFFER_SIZE,
+ ( void ** ) &pSendBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSContext->pSendBuffer = pSendBuffer;
+ pDNSContext->dwBufferSize = SENDBUFFER_SIZE;
+
+ /* We will offset into the buffer by 2 bytes
+ If we are doing a TCP write; we will fill in these
+ two bytes and send + 2 bytes
+ If we are doing a UDP write; we will start our send
+ +2 bytes and only send dwWritten; */
+
+ pDNSContext->dwBufferOffset += 2;
+
+ *phDNSSendBuffer = ( HANDLE ) pDNSContext;
+
+ return dwError;
+
+ error:
+
+ if ( pSendBuffer ) {
+ DNSFreeMemory( pSendBuffer );
+ }
+ if ( pDNSContext ) {
+ DNSFreeMemory( pDNSContext );
+ }
+ *phDNSSendBuffer = ( HANDLE ) NULL;
+
+ return dwError;
+}
+
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSMarshallBuffer( HANDLE hDNSSendBuffer,
+ uint8 * pDNSSendBuffer,
+ int32 dwBufferSize, int32 * pdwBytesWritten )
+{
+ int32 dwError = 0;
+ uint8 *pTemp = NULL;
+ DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL;
+
+/* BugBug - we need to check for amount of space remaining in the
+SendBuffer Context - if its insufficent, we want to realloc the
+Buffer and copy the context; Right now the assumption is we have a big
+enough buffer */
+
+ pDNSContext = ( DNS_SENDBUFFER_CONTEXT * ) hDNSSendBuffer;
+
+ pTemp = pDNSContext->pSendBuffer + pDNSContext->dwBufferOffset;
+
+ memcpy( pTemp, pDNSSendBuffer, dwBufferSize );
+
+ pDNSContext->dwBytesWritten += dwBufferSize;
+ pDNSContext->dwBufferOffset += dwBufferSize;
+
+ *pdwBytesWritten = dwBufferSize;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSTCPSendBufferContext( HANDLE hDNSServer,
+ HANDLE hSendBuffer, int32 * pdwBytesSent )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+ int32 dwError = 0;
+ int16 wBytesWritten = 0;
+ int16 wnBytesWritten = 0;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ wBytesWritten = ( int16 ) pSendBufferContext->dwBytesWritten;
+ wnBytesWritten = htons( wBytesWritten );
+
+ memcpy( pSendBufferContext->pSendBuffer, &wnBytesWritten,
+ sizeof( int16 ) );
+
+ dwError = DNSSendTCPRequest( hDNSServer,
+ pSendBufferContext->pSendBuffer,
+ pSendBufferContext->dwBytesWritten + 2,
+ pdwBytesSent );
+ BAIL_ON_ERROR( dwError );
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSUDPSendBufferContext( HANDLE hDNSServer,
+ HANDLE hSendBuffer, int32 * pdwBytesSent )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+ int32 dwError = 0;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ /* Now remember to send 2 bytes ahead of pSendBuffer; because
+ we ignore the 2 bytes size field. */
+
+ dwError = DNSSendUDPRequest( hDNSServer,
+ pSendBufferContext->pSendBuffer + 2,
+ pSendBufferContext->dwBytesWritten,
+ pdwBytesSent );
+ BAIL_ON_ERROR( dwError );
+
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSSendBufferContext( HANDLE hDNSServer,
+ HANDLE hSendBuffer, int32 * pdwBytesSent )
+{
+ DNS_CONNECTION_CONTEXT *pDNSContext = NULL;
+ int32 dwError = 0;
+
+ pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSServer;
+
+ switch ( pDNSContext->hType ) {
+ case DNS_TCP:
+ dwError = DNSTCPSendBufferContext( hDNSServer,
+ hSendBuffer,
+ pdwBytesSent );
+ BAIL_ON_ERROR( dwError );
+ break;
+
+ case DNS_UDP:
+ dwError = DNSUDPSendBufferContext( hDNSServer,
+ hSendBuffer,
+ pdwBytesSent );
+ BAIL_ON_ERROR( dwError );
+ break;
+ }
+ error:
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSDumpSendBufferContext( HANDLE hSendBuffer )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+ int32 dwError = 0;
+ int32 dwCurLine = 0;
+ int32 i = 0;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+ printf( "\n" );
+ printf( "Buffer Size is: %d\n", pSendBufferContext->dwBytesWritten );
+ while ( i < pSendBufferContext->dwBytesWritten ) {
+ if ( ( i / 16 ) > dwCurLine ) {
+ printf( "\n" );
+ dwCurLine++;
+ }
+ if ( ( i % 8 ) == 0 ) {
+ printf( " " );
+ }
+ printf( "%.2x ", pSendBufferContext->pSendBuffer[i] );
+ i++;
+ }
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSDumpRecvBufferContext( HANDLE hRecvBuffer )
+{
+ DNS_RECEIVEBUFFER_CONTEXT *pRecvBufferContext = NULL;
+ int32 dwError = 0;
+ int32 dwCurLine = 0;
+ int32 i = 0;
+
+ pRecvBufferContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer;
+
+ printf( "\n" );
+ printf( "Buffer Size is: %d\n", pRecvBufferContext->dwBytesRecvd );
+
+ while ( i < pRecvBufferContext->dwBytesRecvd ) {
+ if ( ( i / 16 ) > dwCurLine ) {
+ printf( "\n" );
+ dwCurLine++;
+ }
+ if ( ( i % 8 ) == 0 ) {
+ printf( " " );
+ }
+ printf( "%.2x ", pRecvBufferContext->pRecvBuffer[i] );
+ i++;
+ }
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSCreateReceiveBuffer( HANDLE * phDNSRecvBuffer )
+{
+ int32 dwError = 0;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL;
+ uint8 *pRecvBuffer = NULL;
+
+ dwError = DNSAllocateMemory( sizeof( DNS_RECEIVEBUFFER_CONTEXT ),
+ ( void ** ) &pDNSContext );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( RECVBUFFER_SIZE,
+ ( void ** ) &pRecvBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSContext->pRecvBuffer = pRecvBuffer;
+ pDNSContext->dwBufferSize = RECVBUFFER_SIZE;
+
+ *phDNSRecvBuffer = ( HANDLE ) pDNSContext;
+
+ return dwError;
+
+ error:
+
+ if ( pRecvBuffer ) {
+ DNSFreeMemory( pRecvBuffer );
+ }
+ if ( pDNSContext ) {
+ DNSFreeMemory( pDNSContext );
+ }
+ *phDNSRecvBuffer = ( HANDLE ) NULL;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSUnmarshallBuffer( HANDLE hDNSRecvBuffer,
+ uint8 * pDNSRecvBuffer,
+ int32 dwBufferSize, int32 * pdwBytesRead )
+{
+ int32 dwError = 0;
+ uint8 *pTemp = NULL;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL;
+
+/* BugBug - we need to check for amount of space remaining in the
+SendBuffer Context - if its insufficent, we want to realloc the
+Buffer and copy the context; Right now the assumption is we have a big
+enough buffer */
+
+ pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer;
+
+ pTemp = pDNSContext->pRecvBuffer + pDNSContext->dwBytesRead;
+
+ memcpy( pDNSRecvBuffer, pTemp, dwBufferSize );
+
+ pDNSContext->dwBytesRead += dwBufferSize;
+
+ *pdwBytesRead = dwBufferSize;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer,
+ int16 wOffset,
+ DNS_DOMAIN_NAME ** ppDomainName )
+{
+ int32 dwError = 0;
+ DNS_DOMAIN_LABEL *pLabel = NULL;
+ DNS_DOMAIN_LABEL *pLabelList = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ char *pszLabel = NULL;
+ char szLabel[65];
+ uint8 uLen = 0;
+ int32 dwCurrent = 0;
+ DNS_RECEIVEBUFFER_CONTEXT *pRecvContext = NULL;
+
+ pRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer;
+ dwCurrent = wOffset;
+
+ while ( 1 ) {
+
+ memcpy( &uLen, pRecvContext->pRecvBuffer + dwCurrent,
+ sizeof( char ) );
+ dwCurrent++;
+
+ if ( uLen == 0 ) {
+ break;
+ }
+
+ memset( szLabel, 0, 65 );
+ memcpy( szLabel, pRecvContext->pRecvBuffer + dwCurrent,
+ uLen );
+ dwCurrent += uLen;
+
+ dwError = DNSAllocateString( szLabel, &pszLabel );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ),
+ ( void ** ) &pLabel );
+ BAIL_ON_ERROR( dwError );
+
+ pLabel->pszLabel = pszLabel;
+ dwError = DNSAppendLabel( pLabelList, pLabel, &pLabelList );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ),
+ ( void ** ) &pDomainName );
+ BAIL_ON_ERROR( dwError );
+ pDomainName->pLabelList = pLabelList;
+
+ *ppDomainName = pDomainName;
+
+ return dwError;
+
+ error:
+
+ *ppDomainName = NULL;
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSReceiveBufferMoveBackIndex( HANDLE hRecvBuffer, int16 wOffset )
+{
+ int32 dwError = 0;
+ DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL;
+
+ pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer;
+ pDNSContext->dwBytesRead -= wOffset;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+void DNSFreeSendBufferContext( HANDLE hSendBuffer )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ if ( pSendBufferContext->pSendBuffer ) {
+ DNSFreeMemory( pSendBufferContext->pSendBuffer );
+ }
+ if ( pSendBufferContext ) {
+ DNSFreeMemory( pSendBufferContext );
+ }
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSGetSendBufferContextSize( HANDLE hSendBuffer )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ return ( pSendBufferContext->dwBytesWritten );
+
+}
+
+/********************************************************************
+********************************************************************/
+
+uint8 *DNSGetSendBufferContextBuffer( HANDLE hSendBuffer )
+{
+ DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL;
+
+ pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer;
+
+ return ( pSendBufferContext->pSendBuffer );
+}
+
diff --git a/source3/libaddns/dnsupdate.c b/source3/libaddns/dnsupdate.c
new file mode 100644
index 0000000000..8cf497a653
--- /dev/null
+++ b/source3/libaddns/dnsupdate.c
@@ -0,0 +1,644 @@
+/*
+ Public Interface file for Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSSendUpdate1( HANDLE hDNSServer, char *szDomainName,
+ char *szHost, struct in_addr *iplist,
+ int num_ips,
+ DNS_UPDATE_RESPONSE * *ppDNSUpdateResponse )
+{
+ int32 dwError = 0;
+ DNS_UPDATE_REQUEST *pDNSUpdateRequest = NULL;
+ DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL;
+ DNS_ZONE_RECORD *pDNSZoneRecord = NULL;
+ DNS_RR_RECORD *pDNSPRRecord = NULL;
+ int i;
+
+ dwError = DNSUpdateCreateUpdateRequest( &pDNSUpdateRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateZoneRecord( szDomainName, &pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateAddZoneSection( pDNSUpdateRequest, pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ /* Add the CNAME not in user record */
+
+ pDNSPRRecord = NULL;
+ dwError =
+ DNSCreateNameNotInUseRecord( szHost, QTYPE_CNAME,
+ &pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ /* Add a Prerequisite for each IP address to see if everything is already setup */
+
+ for ( i = 0; i < num_ips; i++ ) {
+ DNS_RR_RECORD *pDNSPrereq = NULL;
+
+ dwError =
+ DNSCreateNameInUseRecord( szHost, QTYPE_A, &iplist[i],
+ &pDNSPrereq );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateAddPRSection( pDNSUpdateRequest,
+ pDNSPrereq );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ dwError =
+ DNSUpdateSendUpdateRequest2( hDNSServer, pDNSUpdateRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateReceiveUpdateResponse( hDNSServer,
+ &pDNSUpdateResponse );
+ BAIL_ON_ERROR( dwError );
+
+ *ppDNSUpdateResponse = pDNSUpdateResponse;
+
+ return dwError;
+
+ error:
+
+ if ( pDNSZoneRecord ) {
+ DNSFreeZoneRecord( pDNSZoneRecord );
+ }
+
+ if ( pDNSUpdateRequest ) {
+ DNSUpdateFreeRequest( pDNSUpdateRequest );
+ }
+
+ *ppDNSUpdateResponse = NULL;
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSSendUpdate2( HANDLE hDNSServer, char *szDomainName,
+ char *szHost, struct in_addr *iplist,
+ int num_ips,
+ DNS_UPDATE_RESPONSE * *ppDNSUpdateResponse )
+{
+ int32 dwError = 0;
+ DNS_UPDATE_REQUEST *pDNSUpdateRequest = NULL;
+ DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL;
+ DNS_ZONE_RECORD *pDNSZoneRecord = NULL;
+ DNS_RR_RECORD *pDNSPRRecord = NULL;
+ int i;
+
+ dwError = DNSUpdateCreateUpdateRequest( &pDNSUpdateRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateZoneRecord( szDomainName, &pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateAddZoneSection( pDNSUpdateRequest, pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ /* Add the CNAME not in user record */
+
+ pDNSPRRecord = NULL;
+ dwError =
+ DNSCreateNameNotInUseRecord( szHost, QTYPE_CNAME,
+ &pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ /* Add the IN not in user record */
+
+ pDNSPRRecord = NULL;
+ dwError =
+ DNSCreateNameNotInUseRecord( szHost, QTYPE_A, &pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+
+ for ( i = 0; i < num_ips; i++ ) {
+ DNS_RR_RECORD *pDNSRRAddRecord = NULL;
+
+ dwError =
+ DNSCreateARecord( szHost, DNS_CLASS_IN, QTYPE_A,
+ ntohl( iplist[i].s_addr ),
+ &pDNSRRAddRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateAddUpdateSection( pDNSUpdateRequest,
+ pDNSRRAddRecord );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ dwError =
+ DNSUpdateSendUpdateRequest2( hDNSServer, pDNSUpdateRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateReceiveUpdateResponse( hDNSServer,
+ &pDNSUpdateResponse );
+ BAIL_ON_ERROR( dwError );
+
+ *ppDNSUpdateResponse = pDNSUpdateResponse;
+
+ return dwError;
+
+ error:
+
+ if ( pDNSZoneRecord ) {
+ DNSFreeZoneRecord( pDNSZoneRecord );
+ }
+
+ if ( pDNSUpdateRequest ) {
+ DNSUpdateFreeRequest( pDNSUpdateRequest );
+ }
+
+ *ppDNSUpdateResponse = NULL;
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int32 DNSSendUpdate3( HANDLE hDNSServer, char *szDomainName,
+ char *szHost, struct in_addr *iplist,
+ int num_ips,
+ DNS_UPDATE_RESPONSE * *ppDNSUpdateResponse )
+{
+ int32 dwError = 0;
+ DNS_UPDATE_REQUEST *pDNSUpdateRequest = NULL;
+ DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL;
+ DNS_ZONE_RECORD *pDNSZoneRecord = NULL;
+ DNS_RR_RECORD *pDNSPRRecord = NULL;
+ int i;
+ DNS_RR_RECORD *pDNSRRAddRecord = NULL;
+
+ dwError = DNSUpdateCreateUpdateRequest( &pDNSUpdateRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateZoneRecord( szDomainName, &pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateAddZoneSection( pDNSUpdateRequest, pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ /* Add the CNAME not in user record */
+
+ dwError =
+ DNSCreateNameNotInUseRecord( szHost, QTYPE_CNAME,
+ &pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ /* Delete any existing A records */
+
+ dwError =
+ DNSCreateARecord( szHost, DNS_CLASS_ANY, QTYPE_A, 0,
+ &pDNSRRAddRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateAddUpdateSection( pDNSUpdateRequest,
+ pDNSRRAddRecord );
+ BAIL_ON_ERROR( dwError );
+
+
+ for ( i = 0; i < num_ips; i++ ) {
+
+ dwError =
+ DNSCreateARecord( szHost, DNS_CLASS_IN, QTYPE_A,
+ ntohl( iplist[i].s_addr ),
+ &pDNSRRAddRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateAddUpdateSection( pDNSUpdateRequest,
+ pDNSRRAddRecord );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ dwError =
+ DNSUpdateSendUpdateRequest2( hDNSServer, pDNSUpdateRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateReceiveUpdateResponse( hDNSServer,
+ &pDNSUpdateResponse );
+ BAIL_ON_ERROR( dwError );
+
+ *ppDNSUpdateResponse = pDNSUpdateResponse;
+
+ return dwError;
+
+ error:
+
+ if ( pDNSZoneRecord ) {
+ DNSFreeZoneRecord( pDNSZoneRecord );
+ }
+
+ if ( pDNSUpdateRequest ) {
+ DNSUpdateFreeRequest( pDNSUpdateRequest );
+ }
+
+ *ppDNSUpdateResponse = NULL;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSSendUpdate( HANDLE hDNSServer, char *szDomainName, char *szHost,
+ struct in_addr * iplist, int num_ips,
+ DNS_UPDATE_RESPONSE * *ppDNSUpdateResponse )
+{
+ int32 dwError = 0;
+ int32 dwResponseCode = 0;
+ DNS_UPDATE_RESPONSE *response = NULL;
+
+ dwError = DNSSendUpdate1( hDNSServer, szDomainName, szHost,
+ iplist, num_ips, &response );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateGetResponseCode( response, &dwResponseCode );
+ BAIL_ON_ERROR( dwError );
+
+ if ( ( dwResponseCode == DNS_NO_ERROR )
+ || ( dwResponseCode == DNS_REFUSED ) ) {
+ *ppDNSUpdateResponse = response;
+ return dwError;
+ }
+
+ response = NULL;
+
+ dwError = DNSSendUpdate2( hDNSServer, szDomainName, szHost,
+ iplist, num_ips, &response );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateGetResponseCode( response, &dwResponseCode );
+ BAIL_ON_ERROR( dwError );
+
+ if ( ( dwResponseCode == DNS_NO_ERROR )
+ || ( dwResponseCode == DNS_REFUSED ) ) {
+ *ppDNSUpdateResponse = response;
+ return dwError;
+ }
+
+ response = NULL;
+
+ dwError = DNSSendUpdate3( hDNSServer, szDomainName, szHost,
+ iplist, num_ips, &response );
+
+ error:
+ *ppDNSUpdateResponse = response;
+
+ return dwError;
+}
+
+/********************************************************************
+********************************************************************/
+
+int32 DNSSendSecureUpdate( HANDLE hDNSServer,
+ PCtxtHandle pGSSContext,
+ char *pszKeyName,
+ char *szDomainName,
+ char *szHost,
+ int32 dwIP, DNS_UPDATE_RESPONSE ** ppDNSUpdateResponse )
+{
+ int32 dwError = 0;
+ DNS_UPDATE_REQUEST *pDNSUpdateRequest = NULL;
+ DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL;
+ DNS_ZONE_RECORD *pDNSZoneRecord = NULL;
+ DNS_RR_RECORD *pDNSPRRecord = NULL;
+ DNS_RR_RECORD *pDNSARecord = NULL;
+
+
+ dwError = DNSUpdateCreateUpdateRequest( &pDNSUpdateRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateZoneRecord( szDomainName, &pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateAddZoneSection( pDNSUpdateRequest,
+ pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateNameInUseRecord( szDomainName,
+ QTYPE_A, NULL, &pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateDeleteRecord( szHost,
+ DNS_CLASS_ANY,
+ QTYPE_A, &pDNSARecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateAddUpdateSection( pDNSUpdateRequest, pDNSARecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateARecord( szHost,
+ DNS_CLASS_IN,
+ QTYPE_A, dwIP, &pDNSARecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateAddUpdateSection( pDNSUpdateRequest, pDNSARecord );
+ BAIL_ON_ERROR( dwError );
+
+ /* Now Sign the Record */
+
+ dwError = DNSUpdateGenerateSignature( pGSSContext,
+ pDNSUpdateRequest, pszKeyName );
+ BAIL_ON_ERROR( dwError );
+
+
+ dwError =
+ DNSUpdateSendUpdateRequest2( hDNSServer, pDNSUpdateRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateReceiveUpdateResponse( hDNSServer,
+ &pDNSUpdateResponse );
+ BAIL_ON_ERROR( dwError );
+
+ *ppDNSUpdateResponse = pDNSUpdateResponse;
+
+ return dwError;
+
+ error:
+
+ if ( pDNSZoneRecord ) {
+ DNSFreeZoneRecord( pDNSZoneRecord );
+ }
+
+ if ( pDNSUpdateRequest ) {
+ DNSUpdateFreeRequest( pDNSUpdateRequest );
+ }
+
+ *ppDNSUpdateResponse = NULL;
+
+ return dwError;
+}
+
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateGenerateSignature( PCtxtHandle pGSSContext,
+ DNS_UPDATE_REQUEST * pDNSUpdateRequest,
+ char *pszKeyName )
+{
+ int32 dwError = 0;
+ int32 dwMinorStatus = 0;
+ HANDLE hSendBuffer = ( HANDLE ) NULL;
+ uint8 *pMessageBuffer = NULL;
+ int32 dwMessageSize = 0;
+ int32 dwMaxSignatureSize = 0;
+ uint8 *pSignature = NULL;
+ int32 dwTimeSigned = 0;
+ int16 wFudge = 0;
+ gss_buffer_desc MsgDesc, MicDesc;
+ DNS_RR_RECORD *pDNSTSIGRecord = NULL;
+
+ dwError = DNSBuildMessageBuffer( pDNSUpdateRequest,
+ pszKeyName,
+ &dwTimeSigned,
+ &wFudge,
+ &pMessageBuffer, &dwMessageSize );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSBuildSignatureBuffer( dwMaxSignatureSize, &pSignature );
+ BAIL_ON_ERROR( dwError );
+
+ MsgDesc.value = pMessageBuffer;
+ MsgDesc.length = dwMessageSize;
+
+ MicDesc.value = NULL;
+ MicDesc.length = 0;
+
+ dwError = gss_get_mic( ( OM_uint32 * ) & dwMinorStatus,
+ *pGSSContext, 0, &MsgDesc, &MicDesc );
+ display_status( "gss_init_context", dwError, dwMinorStatus );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSCreateTSIGRecord( pszKeyName,
+ dwTimeSigned,
+ wFudge,
+ pDNSUpdateRequest->wIdentification,
+ MicDesc.value,
+ MicDesc.length, &pDNSTSIGRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateAddAdditionalSection( pDNSUpdateRequest,
+ pDNSTSIGRecord );
+ BAIL_ON_ERROR( dwError );
+
+
+ error:
+
+ if ( hSendBuffer ) {
+ DNSFreeSendBufferContext( hSendBuffer );
+ }
+
+ if ( pMessageBuffer ) {
+ DNSFreeMemory( pMessageBuffer );
+ }
+ return dwError;
+
+ if ( pSignature ) {
+ DNSFreeMemory( pSignature );
+ }
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSBuildSignatureBuffer( int32 dwMaxSignatureSize, uint8 ** ppSignature )
+{
+ int32 dwError = 0;
+ uint8 *pSignature = NULL;
+
+ dwError = DNSAllocateMemory( dwMaxSignatureSize,
+ ( void ** ) &pSignature );
+ BAIL_ON_ERROR( dwError );
+
+ *ppSignature = pSignature;
+
+ return dwError;
+
+ error:
+ *ppSignature = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSBuildMessageBuffer( DNS_UPDATE_REQUEST * pDNSUpdateRequest,
+ char *szKeyName,
+ int32 * pdwTimeSigned,
+ int16 * pwFudge,
+ uint8 ** ppMessageBuffer, int32 * pdwMessageSize )
+{
+ int32 dwError = 0;
+ uint8 *pSrcBuffer = NULL;
+ int32 dwReqMsgSize = 0;
+ int32 dwAlgorithmLen = 0;
+ int32 dwNameLen = 0;
+ uint8 *pMessageBuffer = NULL;
+ int32 dwMessageSize = 0;
+ uint8 *pOffset = NULL;
+ int16 wnError, wError = 0;
+ int16 wnFudge = 0;
+ int16 wFudge = DNS_TEN_HOURS_IN_SECS;
+ int16 wnOtherLen = 0, wOtherLen = 0;
+ int32 dwBytesCopied = 0;
+ int16 wnClass = 0, wClass = DNS_CLASS_ANY;
+ int32 dwnTTL = 0, dwTTL = 0;
+ int32 dwnTimeSigned, dwTimeSigned = 0;
+ HANDLE hSendBuffer = ( HANDLE ) NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ DNS_DOMAIN_NAME *pAlgorithmName = NULL;
+ int16 wTimePrefix = 0;
+ int16 wnTimePrefix = 0;
+ char szTsig[9];
+
+ dwError = DNSDomainNameFromString( szKeyName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSGetDomainNameLength( pDomainName, &dwNameLen );
+ BAIL_ON_ERROR( dwError );
+
+ strncpy( szTsig, "gss-tsig", sizeof( szTsig ) );
+ dwError = DNSDomainNameFromString( szTsig, &pAlgorithmName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSGetDomainNameLength( pAlgorithmName, &dwAlgorithmLen );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUpdateBuildRequestMessage( pDNSUpdateRequest,
+ &hSendBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ dwReqMsgSize = DNSGetSendBufferContextSize( hSendBuffer );
+ dwMessageSize += dwReqMsgSize;
+ dwMessageSize += dwNameLen;
+ dwMessageSize += sizeof( int16 ); /* class */
+ dwMessageSize += sizeof( int32 ); /* TTL */
+ dwMessageSize += dwAlgorithmLen;
+ dwMessageSize += ( sizeof( int16 ) + sizeof( int32 ) ); /* Time Signed */
+ dwMessageSize += sizeof( int16 ); /* Fudge */
+ dwMessageSize += sizeof( int16 ); /* wError */
+ dwMessageSize += sizeof( int16 ); /* Other Len */
+ dwMessageSize += wOtherLen;
+
+ dwError =
+ DNSAllocateMemory( dwMessageSize,
+ ( void ** ) &pMessageBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ pOffset = pMessageBuffer;
+ pSrcBuffer = DNSGetSendBufferContextBuffer( hSendBuffer );
+ memcpy( pOffset, pSrcBuffer, dwReqMsgSize );
+ pOffset += dwReqMsgSize;
+
+ dwError =
+ DNSCopyDomainName( pOffset, pAlgorithmName, &dwBytesCopied );
+ BAIL_ON_ERROR( dwError );
+ pOffset += dwBytesCopied;
+
+ wnClass = htons( wClass );
+ memcpy( pOffset, &wnClass, sizeof( int16 ) );
+ pOffset += sizeof( int16 );
+
+ dwnTTL = htonl( dwTTL );
+ memcpy( pOffset, &dwnTTL, sizeof( int32 ) );
+ pOffset += sizeof( int32 );
+
+
+ wnTimePrefix = htons( wTimePrefix );
+ memcpy( pOffset, &wnTimePrefix, sizeof( int16 ) );
+ pOffset += sizeof( int16 );
+
+ time( (time_t*)&dwTimeSigned );
+ dwnTimeSigned = htonl( dwTimeSigned );
+ memcpy( pOffset, &dwnTimeSigned, sizeof( int32 ) );
+ pOffset += sizeof( int32 );
+
+ wnFudge = htons( wFudge );
+ memcpy( pOffset, &wnFudge, sizeof( int16 ) );
+ pOffset += sizeof( int16 );
+
+ wnError = htons( wError );
+ memcpy( pOffset, &wnError, sizeof( int16 ) );
+ pOffset += sizeof( int16 );
+
+ wnOtherLen = htons( wOtherLen );
+ memcpy( pOffset, &wnOtherLen, sizeof( int16 ) );
+ pOffset += sizeof( int16 );
+
+ *ppMessageBuffer = pMessageBuffer;
+ *pdwMessageSize = dwMessageSize;
+
+ *pdwTimeSigned = dwTimeSigned;
+ *pwFudge = wFudge;
+
+ return dwError;
+
+ error:
+
+ if ( pMessageBuffer ) {
+ DNSFreeMemory( pMessageBuffer );
+ }
+
+ *ppMessageBuffer = NULL;
+ *pdwMessageSize = 0;
+ *pdwTimeSigned = dwTimeSigned;
+ *pwFudge = wFudge;
+ return dwError;
+
+}
diff --git a/source3/libaddns/dnsuprequest.c b/source3/libaddns/dnsuprequest.c
new file mode 100644
index 0000000000..d8188d5f58
--- /dev/null
+++ b/source3/libaddns/dnsuprequest.c
@@ -0,0 +1,428 @@
+/*
+ Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSUpdateMarshallZoneSection( HANDLE hSendBuffer,
+ DNS_ZONE_RECORD ** ppDNSZoneRecords,
+ int16 wZones )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ int32 dwRead = 0;
+ DNS_ZONE_RECORD *pDNSZoneRecord = NULL;
+ int16 wnZoneType = 0;
+ int16 wnZoneClass = 0;
+
+ for ( i = 0; i < wZones; i++ ) {
+
+ pDNSZoneRecord = *( ppDNSZoneRecords + i );
+ dwError =
+ DNSMarshallDomainName( hSendBuffer,
+ pDNSZoneRecord->pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ wnZoneType = htons( pDNSZoneRecord->wZoneType );
+ dwError =
+ DNSMarshallBuffer( hSendBuffer,
+ ( uint8 * ) & wnZoneType,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ wnZoneClass = htons( pDNSZoneRecord->wZoneClass );
+ dwError =
+ DNSMarshallBuffer( hSendBuffer,
+ ( uint8 * ) & wnZoneClass,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSZoneRecord++;
+ }
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSUpdateMarshallPRSection( HANDLE hSendBuffer,
+ DNS_RR_RECORD ** ppDNSPRRRRecords, int16 wPRs )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSPRRRRecord = NULL;
+
+
+ for ( i = 0; i < wPRs; i++ ) {
+
+ pDNSPRRRRecord = *( ppDNSPRRRRecords + i );
+
+ dwError = DNSMarshallRRHeader( hSendBuffer, pDNSPRRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ if ( pDNSPRRRRecord->RRHeader.wRDataSize ) {
+ dwError =
+ DNSMarshallRData( hSendBuffer,
+ pDNSPRRRRecord );
+ BAIL_ON_ERROR( dwError );
+ }
+ }
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSUpdateMarshallUpdateSection( HANDLE hSendBuffer,
+ DNS_RR_RECORD ** ppDNSUpdateRRRecords,
+ int16 wZones )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSUpdateRRRecord = NULL;
+
+ for ( i = 0; i < wZones; i++ ) {
+
+ pDNSUpdateRRRecord = *( ppDNSUpdateRRRecords + i );
+
+ dwError =
+ DNSMarshallRRHeader( hSendBuffer,
+ pDNSUpdateRRRecord );
+
+ if ( pDNSUpdateRRRecord->RRHeader.wRDataSize ) {
+ dwError = DNSMarshallRData( hSendBuffer,
+ pDNSUpdateRRRecord );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ }
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSUpdateMarshallAdditionalSection( HANDLE hSendBuffer,
+ DNS_RR_RECORD **
+ ppDNSAdditionalsRRRecords,
+ int16 wAdditionals )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSAdditionalRRRecord = NULL;
+
+ for ( i = 0; i < wAdditionals; i++ ) {
+
+ pDNSAdditionalRRRecord = *( ppDNSAdditionalsRRRecords + i );
+
+ dwError =
+ DNSMarshallRRHeader( hSendBuffer,
+ pDNSAdditionalRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ if ( pDNSAdditionalRRRecord->RRHeader.wRDataSize ) {
+ dwError = DNSMarshallRData( hSendBuffer,
+ pDNSAdditionalRRRecord );
+ BAIL_ON_ERROR( dwError );
+ }
+ }
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateSendUpdateRequest2( HANDLE hDNSServer,
+ DNS_UPDATE_REQUEST * pDNSRequest )
+{
+ int32 dwError = 0;
+ int32 dwBytesSent = 0;
+ HANDLE hSendBuffer = ( HANDLE ) NULL;
+
+ dwError = DNSUpdateBuildRequestMessage( pDNSRequest, &hSendBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSSendBufferContext( hDNSServer, hSendBuffer, &dwBytesSent );
+ BAIL_ON_ERROR( dwError );
+
+ error:
+
+ if ( hSendBuffer ) {
+ DNSFreeSendBufferContext( hSendBuffer );
+ }
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateBuildRequestMessage( DNS_UPDATE_REQUEST * pDNSRequest,
+ HANDLE * phSendBuffer )
+{
+ int32 dwError = 0;
+ char DNSMessageHeader[12];
+ int16 wnIdentification = 0;
+ int16 wnParameter = 0;
+ int16 wnZones = 0;
+ int16 wnPRs = 0;
+ int16 wnUpdates = 0;
+ int16 wnAdditionals = 0;
+ int32 dwRead = 0;
+ HANDLE hSendBuffer = ( HANDLE ) NULL;
+
+ dwError = DNSCreateSendBuffer( &hSendBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ wnIdentification = htons( pDNSRequest->wIdentification );
+ memcpy( DNSMessageHeader, ( char * ) &wnIdentification, 2 );
+
+ wnParameter = htons( pDNSRequest->wParameter );
+ memcpy( DNSMessageHeader + 2, ( char * ) &wnParameter, 2 );
+
+ wnZones = htons( pDNSRequest->wZones );
+ memcpy( DNSMessageHeader + 4, ( char * ) &wnZones, 2 );
+
+ wnPRs = htons( pDNSRequest->wPRs );
+ memcpy( DNSMessageHeader + 6, ( char * ) &wnPRs, 2 );
+
+ wnUpdates = htons( pDNSRequest->wUpdates );
+ memcpy( DNSMessageHeader + 8, ( char * ) &wnUpdates, 2 );
+
+ wnAdditionals = htons( pDNSRequest->wAdditionals );
+ memcpy( DNSMessageHeader + 10, ( char * ) &wnAdditionals, 2 );
+
+ dwError =
+ DNSMarshallBuffer( hSendBuffer, ( uint8 * ) DNSMessageHeader,
+ 12, &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ if ( pDNSRequest->wZones ) {
+ dwError =
+ DNSUpdateMarshallZoneSection( hSendBuffer,
+ pDNSRequest->
+ ppZoneRRSet,
+ pDNSRequest->wZones );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( pDNSRequest->wPRs ) {
+ dwError =
+ DNSUpdateMarshallPRSection( hSendBuffer,
+ pDNSRequest->ppPRRRSet,
+ pDNSRequest->wPRs );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( pDNSRequest->wUpdates ) {
+ dwError =
+ DNSUpdateMarshallUpdateSection( hSendBuffer,
+ pDNSRequest->
+ ppUpdateRRSet,
+ pDNSRequest->
+ wUpdates );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( pDNSRequest->wAdditionals ) {
+ dwError =
+ DNSUpdateMarshallAdditionalSection( hSendBuffer,
+ pDNSRequest->
+ ppAdditionalRRSet,
+ pDNSRequest->
+ wAdditionals );
+ BAIL_ON_ERROR( dwError );
+ }
+#if 0
+ DNSDumpSendBufferContext( hSendBuffer );
+#endif
+
+ *phSendBuffer = hSendBuffer;
+
+ return dwError;
+
+ error:
+
+ if ( hSendBuffer ) {
+ DNSFreeSendBufferContext( hSendBuffer );
+ }
+
+ *phSendBuffer = ( HANDLE ) NULL;
+ return dwError;
+}
+
+
+/*********************************************************************
+*********************************************************************/
+
+void DNSUpdateFreeRequest( DNS_UPDATE_REQUEST * pDNSRequest )
+{
+ return;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateAddZoneSection( DNS_UPDATE_REQUEST * pDNSRequest,
+ DNS_ZONE_RECORD * pDNSZone )
+{
+ int32 dwNumZones = 0;
+ int32 dwError = 0;
+
+ dwNumZones = pDNSRequest->wZones;
+
+ dwError = DNSReallocMemory( ( uint8 * ) pDNSRequest->ppZoneRRSet,
+ ( void ** ) &pDNSRequest->ppZoneRRSet,
+ ( dwNumZones +
+ 1 ) * sizeof( DNS_ZONE_RECORD * )
+ );
+ BAIL_ON_ERROR( dwError );
+
+ *( pDNSRequest->ppZoneRRSet + dwNumZones ) = pDNSZone;
+
+ pDNSRequest->wZones += 1;
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateAddAdditionalSection( DNS_UPDATE_REQUEST * pDNSRequest,
+ DNS_RR_RECORD * pDNSRecord )
+{
+ int32 dwNumAdditionals = 0;
+ int32 dwError = 0;
+
+ dwNumAdditionals = pDNSRequest->wAdditionals;
+ dwError = DNSReallocMemory( pDNSRequest->ppAdditionalRRSet,
+ ( void ** ) &pDNSRequest->
+ ppAdditionalRRSet,
+ ( dwNumAdditionals +
+ 1 ) * sizeof( DNS_RR_RECORD * ) );
+ BAIL_ON_ERROR( dwError );
+
+ *( pDNSRequest->ppAdditionalRRSet + dwNumAdditionals ) = pDNSRecord;
+
+ pDNSRequest->wAdditionals += 1;
+
+ error:
+ return dwError;
+}
+
+int32 DNSUpdateAddPRSection( DNS_UPDATE_REQUEST * pDNSRequest,
+ DNS_RR_RECORD * pDNSRecord )
+{
+ int32 dwNumPRs = 0;
+ int32 dwError = 0;
+
+ dwNumPRs = pDNSRequest->wPRs;
+ dwError = DNSReallocMemory( pDNSRequest->ppPRRRSet,
+ ( void ** ) &pDNSRequest->ppPRRRSet,
+ ( dwNumPRs +
+ 1 ) * sizeof( DNS_RR_RECORD * ) );
+ BAIL_ON_ERROR( dwError );
+
+ *( pDNSRequest->ppPRRRSet + dwNumPRs ) = pDNSRecord;
+
+ pDNSRequest->wPRs += 1;
+
+ error:
+ return dwError;
+}
+
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateAddUpdateSection( DNS_UPDATE_REQUEST * pDNSRequest,
+ DNS_RR_RECORD * pDNSRecord )
+{
+ int32 dwError = 0;
+ int16 wNumUpdates = 0;
+
+ wNumUpdates = pDNSRequest->wUpdates;
+ dwError = DNSReallocMemory( pDNSRequest->ppUpdateRRSet,
+ ( void ** ) &pDNSRequest->ppUpdateRRSet,
+ ( wNumUpdates +
+ 1 ) * sizeof( DNS_RR_RECORD * ) );
+ BAIL_ON_ERROR( dwError );
+
+ *( pDNSRequest->ppUpdateRRSet + wNumUpdates ) = pDNSRecord;
+
+ pDNSRequest->wUpdates += 1;
+
+ error:
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateCreateUpdateRequest( DNS_UPDATE_REQUEST ** ppDNSRequest )
+{
+ int32 dwError = 0;
+ DNS_UPDATE_REQUEST *pDNSRequest = NULL;
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_UPDATE_REQUEST ),
+ ( void ** ) &pDNSRequest );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSGenerateIdentifier( &pDNSRequest->wIdentification );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRequest->wParameter = 0x2800;
+
+ *ppDNSRequest = pDNSRequest;
+
+ return dwError;
+
+ error:
+
+ if ( pDNSRequest ) {
+ DNSUpdateFreeRequest( pDNSRequest );
+ }
+ *ppDNSRequest = NULL;
+ return dwError;
+}
diff --git a/source3/libaddns/dnsupresp.c b/source3/libaddns/dnsupresp.c
new file mode 100644
index 0000000000..c5f7642acd
--- /dev/null
+++ b/source3/libaddns/dnsupresp.c
@@ -0,0 +1,397 @@
+/*
+ Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSUpdateAllocateResponse( DNS_UPDATE_RESPONSE ** ppDNSResponse )
+{
+ int32 dwError = 0;
+ DNS_UPDATE_RESPONSE *pDNSResponse = NULL;
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_UPDATE_RESPONSE ),
+ ( void ** ) &pDNSResponse );
+ BAIL_ON_ERROR( dwError );
+
+ *ppDNSResponse = pDNSResponse;
+
+ return dwError;
+
+ error:
+
+ *ppDNSResponse = NULL;
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSUpdateUnmarshallAdditionalSection( HANDLE hReceiveBuffer,
+ int16 wAdditionals,
+ DNS_RR_RECORD *
+ **pppDNSAdditionalsRRRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_RR_RECORD **ppDNSAdditionalRRRecords = NULL;
+ DNS_RR_HEADER RRHeader = { 0 };
+ DNS_RR_HEADER *pRRHeader = &RRHeader;
+ uint8 *pRRData = NULL;
+ int32 dwRead = 0;
+
+ dwError = DNSAllocateMemory( wAdditionals * sizeof( DNS_RR_RECORD * ),
+ ( void ** ) &ppDNSAdditionalRRRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wAdditionals; i++ ) {
+
+ memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) );
+ dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallRData( hReceiveBuffer,
+ pRRHeader->wRDataSize, &pRRData,
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( &pDNSRRRecord->RRHeader, pRRHeader,
+ sizeof( DNS_RR_HEADER ) );
+ pDNSRRRecord->pRData = pRRData;
+
+ *( ppDNSAdditionalRRRecords + i ) = pDNSRRRecord;
+ }
+
+ error:
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSUpdateUnmarshallPRSection( HANDLE hReceiveBuffer,
+ int16 wPRs,
+ DNS_RR_RECORD * **pppDNSPRRRRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_RR_RECORD **ppDNSPRRRRecords = NULL;
+ DNS_RR_HEADER RRHeader = { 0 };
+ DNS_RR_HEADER *pRRHeader = &RRHeader;
+ uint8 *pRRData = NULL;
+ int32 dwRead = 0;
+
+ dwError = DNSAllocateMemory( wPRs * sizeof( DNS_RR_RECORD * ),
+ ( void ** ) &ppDNSPRRRRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wPRs; i++ ) {
+
+ memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) );
+ dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallRData( hReceiveBuffer,
+ pRRHeader->wRDataSize, &pRRData,
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( &pDNSRRRecord->RRHeader, pRRHeader,
+ sizeof( DNS_RR_HEADER ) );
+ pDNSRRRecord->pRData = pRRData;
+
+ *( ppDNSPRRRRecords + i ) = pDNSRRRecord;
+ }
+
+ *pppDNSPRRRRecords = ppDNSPRRRRecords;
+
+ return dwError;
+
+ error:
+
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSUpdateUnmarshallUpdateSection( HANDLE hReceiveBuffer,
+ int16 wUpdates,
+ DNS_RR_RECORD * **pppDNSUpdateRRRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_RR_RECORD **ppDNSUpdateRRRecords = NULL;
+ DNS_RR_HEADER RRHeader = { 0 };
+ DNS_RR_HEADER *pRRHeader = &RRHeader;
+ uint8 *pRRData = NULL;
+ int32 dwRead = 0;
+
+ dwError = DNSAllocateMemory( wUpdates * sizeof( DNS_RR_RECORD * ),
+ ( void ** ) &ppDNSUpdateRRRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wUpdates; i++ ) {
+
+ memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) );
+ dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallRData( hReceiveBuffer,
+ pRRHeader->wRDataSize, &pRRData,
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ memcpy( &pDNSRRRecord->RRHeader, pRRHeader,
+ sizeof( DNS_RR_HEADER ) );
+ pDNSRRRecord->pRData = pRRData;
+
+ *( ppDNSUpdateRRRecords + i ) = pDNSRRRecord;
+ }
+
+ *pppDNSUpdateRRRecords = ppDNSUpdateRRRecords;
+
+ return dwError;
+
+ error:
+
+ return dwError;
+
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSUpdateUnmarshallZoneSection( HANDLE hReceiveBuffer,
+ int16 wZones,
+ DNS_ZONE_RECORD * **pppDNSZoneRecords )
+{
+ int32 dwError = 0;
+ int32 i = 0;
+ int32 dwRead = 0;
+ DNS_ZONE_RECORD *pDNSZoneRecord = NULL;
+ DNS_ZONE_RECORD **ppDNSZoneRecords = NULL;
+ int16 wnZoneClass = 0;
+ int16 wnZoneType = 0;
+
+
+ dwError = DNSAllocateMemory( wZones * sizeof( DNS_ZONE_RECORD * ),
+ ( void ** ) &ppDNSZoneRecords );
+ BAIL_ON_ERROR( dwError );
+
+ for ( i = 0; i < wZones; i++ ) {
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_ZONE_RECORD ),
+ ( void ** ) &pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallDomainName( hReceiveBuffer,
+ &pDNSZoneRecord->
+ pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSUnmarshallBuffer( hReceiveBuffer,
+ ( uint8 * ) & wnZoneType,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pDNSZoneRecord->wZoneType = ntohs( wnZoneType );
+
+ dwError =
+ DNSUnmarshallBuffer( hReceiveBuffer,
+ ( uint8 * ) & wnZoneClass,
+ ( int32 ) sizeof( int16 ),
+ &dwRead );
+ BAIL_ON_ERROR( dwError );
+ pDNSZoneRecord->wZoneClass = ntohs( wnZoneClass );
+
+ *( ppDNSZoneRecords + i ) = pDNSZoneRecord;
+ }
+
+ *pppDNSZoneRecords = ppDNSZoneRecords;
+ return dwError;
+
+ error:
+
+ return dwError;
+}
+
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSUpdateReceiveUpdateResponse( HANDLE hDNSHandle,
+ DNS_UPDATE_RESPONSE ** ppDNSResponse )
+{
+ DNS_UPDATE_RESPONSE *pDNSResponse = NULL;
+ int32 dwError = 0;
+ int16 wnIdentification, wIdentification = 0;
+ int16 wnParameter, wParameter = 0;
+ int16 wnZones, wZones = 0;
+ int16 wnPRs, wPRs = 0;
+ int16 wnAdditionals, wAdditionals = 0;
+ int16 wnUpdates, wUpdates = 0;
+ int32 dwRead = 0;
+ DNS_RR_RECORD **ppDNSPRRecords = NULL;
+ DNS_RR_RECORD **ppDNSAdditionalRecords = NULL;
+ DNS_RR_RECORD **ppDNSUpdateRecords = NULL;
+ DNS_ZONE_RECORD **ppDNSZoneRecords = NULL;
+ HANDLE hRecvBuffer = ( HANDLE ) NULL;
+
+ dwError = DNSCreateReceiveBuffer( &hRecvBuffer );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSReceiveBufferContext( hDNSHandle, hRecvBuffer, &dwRead );
+ BAIL_ON_ERROR( dwError );
+
+#if 0
+ dwError = DNSDumpRecvBufferContext( hRecvBuffer );
+ BAIL_ON_ERROR( dwError );
+#endif
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer,
+ ( uint8 * ) & wnIdentification,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wIdentification = ntohs( wnIdentification );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnParameter,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wParameter = ntohs( wnParameter );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnZones,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wZones = ntohs( wnZones );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnPRs,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wPRs = ntohs( wnPRs );
+
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnUpdates,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wUpdates = ntohs( wnUpdates );
+
+ dwError =
+ DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAdditionals,
+ sizeof( int16 ), &dwRead );
+ BAIL_ON_ERROR( dwError );
+ wAdditionals = ntohs( wnAdditionals );
+
+
+ if ( wZones ) {
+ dwError =
+ DNSUpdateUnmarshallZoneSection( hRecvBuffer, wZones,
+ &ppDNSZoneRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( wPRs ) {
+ dwError =
+ DNSUpdateUnmarshallPRSection( hRecvBuffer, wPRs,
+ &ppDNSPRRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( wUpdates ) {
+ dwError =
+ DNSUpdateUnmarshallUpdateSection( hRecvBuffer,
+ wUpdates,
+ &ppDNSUpdateRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ if ( wAdditionals ) {
+ dwError =
+ DNSUpdateUnmarshallAdditionalSection( hRecvBuffer,
+ wAdditionals,
+ &ppDNSAdditionalRecords );
+ BAIL_ON_ERROR( dwError );
+ }
+
+ dwError = DNSUpdateAllocateResponse( &pDNSResponse );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSResponse->wIdentification = wIdentification;
+ pDNSResponse->wParameter = wParameter;
+ pDNSResponse->wZones = wZones;
+ pDNSResponse->wPRs = wPRs;
+ pDNSResponse->wUpdates = wUpdates;
+ pDNSResponse->wAdditionals = wAdditionals;
+
+ pDNSResponse->ppZoneRRSet = ppDNSZoneRecords;
+ pDNSResponse->ppPRRRSet = ppDNSPRRecords;
+ pDNSResponse->ppUpdateRRSet = ppDNSUpdateRecords;
+ pDNSResponse->ppAdditionalRRSet = ppDNSAdditionalRecords;
+
+ *ppDNSResponse = pDNSResponse;
+
+
+ error:
+
+ return dwError;
+}
+
diff --git a/source3/libaddns/dnsutils.c b/source3/libaddns/dnsutils.c
new file mode 100644
index 0000000000..6071d35d53
--- /dev/null
+++ b/source3/libaddns/dnsutils.c
@@ -0,0 +1,596 @@
+/*
+ Linux DNS client library implementation
+
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+#include <ctype.h>
+
+#define TRUE 1
+#define FALSE 0
+
+#define STATE_BEGIN 0
+#define STATE_LABEL 1
+#define STATE_FINISH 2
+
+#define TOKEN_LABEL 1
+#define TOKEN_SEPARATOR 2
+#define TOKEN_EOS 3
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 getToken( char *pszString, char *pszToken, int32 * pdwToken,
+ int32 * pdwPosition )
+{
+ int32 dwError = 0;
+ char c = 0;
+ int32 dwToken = 0;
+ int32 i = 0;
+ int32 dwState = 0;
+ int32 dwPosition = 0;
+
+ dwPosition = *pdwPosition;
+ dwState = STATE_BEGIN;
+ while ( dwState != STATE_FINISH ) {
+ c = pszString[dwPosition];
+ if ( c == '\0' ) {
+ if ( dwState == STATE_LABEL ) {
+ dwToken = TOKEN_LABEL;
+ dwState = STATE_FINISH;
+ continue;
+ } else if ( dwState == STATE_BEGIN ) {
+ dwToken = TOKEN_EOS;
+ dwState = STATE_FINISH;
+ continue;
+ }
+ } else if ( isalnum( c ) || c == '-' ) {
+ pszToken[i++] = c;
+ dwPosition++;
+ dwState = STATE_LABEL;
+ continue;
+ } else if ( c == '.' ) {
+ if ( dwState == STATE_LABEL ) {
+ dwToken = TOKEN_LABEL;
+ dwState = STATE_FINISH;
+ continue;
+ } else if ( dwState == STATE_BEGIN ) {
+ dwToken = TOKEN_SEPARATOR;
+ dwPosition++;
+ dwState = STATE_FINISH;
+ continue;
+ }
+ } else {
+ if ( dwState == STATE_LABEL ) {
+ dwToken = TOKEN_LABEL;
+ dwState = STATE_FINISH;
+ } else if ( dwState == 0 ) {
+ dwError = ERROR_INVALID_PARAMETER;
+ dwState = STATE_FINISH;
+ }
+ }
+ }
+ *pdwPosition = dwPosition;
+ *pdwToken = dwToken;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSMakeLabel( char *szLabel, DNS_DOMAIN_LABEL ** ppLabel )
+{
+ DNS_DOMAIN_LABEL *pLabel = NULL;
+ char *pszLabel = NULL;
+ int32 dwError = 0;
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ),
+ ( void ** ) &pLabel );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSAllocateString( szLabel, &pszLabel );
+ BAIL_ON_ERROR( dwError );
+
+ pLabel->pszLabel = pszLabel;
+ pLabel->dwLength = ( int32 ) strlen( pszLabel );
+ *ppLabel = pLabel;
+ return dwError;
+
+ error:
+
+ if ( pLabel ) {
+ DNSFreeMemory( pLabel );
+ }
+ *ppLabel = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static void DNSFreeLabel( DNS_DOMAIN_LABEL * pLabel )
+{
+ if ( pLabel ) {
+ DNSFreeMemory( pLabel );
+ }
+ return;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+void DNSFreeLabelList(DNS_DOMAIN_LABEL *pLabelList)
+{
+ DNS_DOMAIN_LABEL *pTemp = NULL;
+ while(pLabelList) {
+ pTemp = pLabelList;
+ pLabelList = pLabelList->pNext;
+ DNSFreeLabel(pTemp);
+ }
+
+ return;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+void DNSFreeDomainName(DNS_DOMAIN_NAME *pDomainName)
+{
+ DNSFreeLabelList(pDomainName->pLabelList);
+ DNSFreeMemory(pDomainName);
+
+ return;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 LabelList( char *pszString, int32 * pdwPosition, DNS_DOMAIN_LABEL ** ppList )
+{
+ int32 dwError = 0;
+ DNS_DOMAIN_LABEL *pList = NULL;
+ DNS_DOMAIN_LABEL *pLabel = NULL;
+ int32 dwToken = 0;
+ char szToken[64];
+
+ memset( szToken, 0, 64 );
+ dwError = getToken( pszString, szToken, &dwToken, pdwPosition );
+ BAIL_ON_ERROR( dwError );
+ if ( dwToken != TOKEN_LABEL ) {
+ dwError = ERROR_INVALID_PARAMETER;
+ BAIL_ON_ERROR( dwError );
+ }
+
+ dwError = DNSMakeLabel( szToken, &pLabel );
+ BAIL_ON_ERROR( dwError );
+
+ memset( szToken, 0, 64 );
+ dwError = getToken( pszString, szToken, &dwToken, pdwPosition );
+ BAIL_ON_ERROR( dwError );
+ if ( dwToken == TOKEN_EOS ) {
+ *ppList = pLabel;
+ return dwError;
+ } else if ( dwToken == TOKEN_SEPARATOR ) {
+ dwError = LabelList( pszString, pdwPosition, &pList );
+ BAIL_ON_ERROR( dwError );
+
+ pLabel->pNext = pList;
+ *ppList = pLabel;
+ }
+
+ return dwError;
+
+ error:
+ if ( pLabel ) {
+ DNSFreeLabel( pLabel );
+ }
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static int32 DNSGetDomainNameOffset( uint8 * pBuffer )
+{
+ uint8 uLen = 0;
+ uint8 uLen1;
+ int32 dwOffset = 0;
+
+ uLen1 = *pBuffer;
+ if ( uLen1 & 0xC0 ) {
+ dwOffset += 2;
+
+ } else {
+
+ while ( 1 ) {
+
+ uLen = *pBuffer;
+ pBuffer++;
+ dwOffset++;
+ if ( uLen == 0 ) {
+ break;
+ }
+ dwOffset += uLen;
+ pBuffer += uLen;
+ }
+ }
+ return ( dwOffset );
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSGenerateIdentifier( int16 * pwIdentifier )
+{
+ int32 dwError = 0;
+
+ *pwIdentifier = random( );
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSGetDomainNameLength( DNS_DOMAIN_NAME * pDomainName, int32 * pdwLength )
+{
+ int32 dwError = 0;
+ int32 dwLength = 0;
+ DNS_DOMAIN_LABEL *pDomainLabel = NULL;
+
+ if ( !pDomainName ) {
+ dwError = ERROR_INVALID_PARAMETER;
+ BAIL_ON_ERROR( dwError );
+ }
+ pDomainLabel = pDomainName->pLabelList;
+
+ while ( pDomainLabel ) {
+ dwLength += pDomainLabel->dwLength;
+ dwLength += 1;
+ pDomainLabel = pDomainLabel->pNext;
+ }
+ dwLength += 1;
+ *pdwLength = dwLength;
+
+ return dwError;
+ error:
+
+ *pdwLength = 0;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCopyDomainName( uint8 * pBuffer,
+ DNS_DOMAIN_NAME * pDomainName, int32 * pdwCopied )
+{
+ int32 dwError = 0;
+ DNS_DOMAIN_LABEL *pDomainLabel = NULL;
+ uint8 uChar = 0;
+ int32 dwCopied = 0;
+
+ if ( !pDomainName ) {
+ dwError = ERROR_INVALID_PARAMETER;
+ BAIL_ON_ERROR( dwError );
+ }
+
+ pDomainLabel = pDomainName->pLabelList;
+ while ( pDomainLabel ) {
+ uChar = ( uint8 ) pDomainLabel->dwLength;
+ memcpy( pBuffer + dwCopied, &uChar, sizeof( uint8 ) );
+ dwCopied += sizeof( uint8 );
+ memcpy( pBuffer + dwCopied, pDomainLabel->pszLabel,
+ pDomainLabel->dwLength );
+ dwCopied += pDomainLabel->dwLength;
+ pDomainLabel = pDomainLabel->pNext;
+ }
+ uChar = 0;
+ memcpy( pBuffer + dwCopied, &uChar, sizeof( uint8 ) );
+ dwCopied += sizeof( uint8 );
+
+ *pdwCopied = dwCopied;
+ return dwError;
+
+ error:
+ *pdwCopied = 0;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSGenerateKeyName( char **ppszKeyName )
+{
+ int32 dwError = 0;
+ char *pszKeyName = NULL;
+ char szTemp[256];
+ char szBuffer[256];
+ unsigned char uuid[16];
+
+ memset( szTemp, 0, 256 );
+ memset( szBuffer, 0, 256 );
+ memset( uuid, 0, 16 );
+
+ uuid_generate( uuid );
+
+ uuid_unparse( uuid, szBuffer );
+
+ strcpy( szTemp, szBuffer );
+ dwError = DNSAllocateString( szTemp, &pszKeyName );
+ BAIL_ON_ERROR( dwError );
+
+ *ppszKeyName = pszKeyName;
+
+ return dwError;
+
+ error:
+
+ *ppszKeyName = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSDomainNameFromString( char *pszDomainName,
+ DNS_DOMAIN_NAME ** ppDomainName )
+{
+ int32 dwError = 0;
+ int32 dwPosition = 0;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ DNS_DOMAIN_LABEL *pLabelList = NULL;
+
+ if ( !pszDomainName || !*pszDomainName ) {
+ dwError = ERROR_INVALID_PARAMETER;
+ return dwError;
+ }
+
+ dwError = LabelList( pszDomainName, &dwPosition, &pLabelList );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ),
+ ( void ** ) &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ pDomainName->pLabelList = pLabelList;
+
+ *ppDomainName = pDomainName;
+
+ return dwError;
+
+ error:
+
+ if ( pLabelList ) {
+ DNSFreeLabelList( pLabelList );
+ }
+ *ppDomainName = NULL;
+
+ return dwError;
+}
+
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSAppendLabel( DNS_DOMAIN_LABEL * pLabelList,
+ DNS_DOMAIN_LABEL * pLabel,
+ DNS_DOMAIN_LABEL ** ppNewLabelList )
+{
+ DNS_DOMAIN_LABEL **ppLabelList = NULL;
+ int32 dwError = 0;
+
+ if ( pLabelList == NULL ) {
+ *ppNewLabelList = pLabel;
+ return dwError;
+ }
+
+ ppLabelList = &pLabelList;
+
+ while ( ( *ppLabelList )->pNext ) {
+ ppLabelList = &( ( *ppLabelList )->pNext );
+ }
+
+ ( *ppLabelList )->pNext = pLabel;
+ *ppNewLabelList = pLabelList;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 GetLastError( )
+{
+ return ( errno );
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 WSAGetLastError( void )
+{
+ return ( errno );
+}
+
+/*********************************************************************
+*********************************************************************/
+
+void DNSRecordGenerateOffsets( DNS_RR_RECORD * pDNSRecord )
+{
+ int32 dwOffset = 0;
+ uint8 *pRData = NULL;
+ int16 wKeySize, wnKeySize = 0;
+
+ pRData = pDNSRecord->pRData;
+ switch ( pDNSRecord->RRHeader.wType ) {
+ case QTYPE_TKEY:
+ pDNSRecord->Offsets.TKey.wAlgorithmOffset =
+ ( int16 ) dwOffset;
+ dwOffset += DNSGetDomainNameOffset( pRData );
+ pDNSRecord->Offsets.TKey.wInceptionOffset =
+ ( int16 ) dwOffset;
+ dwOffset += sizeof( int32 );
+ pDNSRecord->Offsets.TKey.wExpirationOffset =
+ ( int16 ) dwOffset;
+ dwOffset += sizeof( int32 );
+ pDNSRecord->Offsets.TKey.wModeOffset = ( int16 ) dwOffset;
+ dwOffset += sizeof( int16 );
+ pDNSRecord->Offsets.TKey.wErrorOffset = ( int16 ) dwOffset;
+ dwOffset += sizeof( int16 );
+ pDNSRecord->Offsets.TKey.wKeySizeOffset = ( int16 ) dwOffset;
+ dwOffset += sizeof( int16 );
+ pDNSRecord->Offsets.TKey.wKeyDataOffset = ( int16 ) dwOffset;
+
+ memcpy( &wnKeySize,
+ pRData + pDNSRecord->Offsets.TKey.wKeySizeOffset,
+ sizeof( int16 ) );
+ wKeySize = ntohs( wnKeySize );
+
+ dwOffset += wKeySize;
+ pDNSRecord->Offsets.TKey.wOtherSizeOffset =
+ ( int16 ) dwOffset;
+ dwOffset += sizeof( int16 );
+ pDNSRecord->Offsets.TKey.wOtherDataOffset =
+ ( int16 ) dwOffset;
+ break;
+
+ case QTYPE_TSIG:
+ break;
+ }
+ return;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 MapDNSResponseCodes( int16 wResponseCode )
+{
+ int16 wnResponseCode = 0;
+ uint8 *pByte = NULL;
+
+ wnResponseCode = htons( wResponseCode );
+ pByte = ( uint8 * ) & wnResponseCode;
+
+#if 0
+ printf( "Byte 0 - %.2x\n", pByte[0] );
+ printf( "Byte 1 - %.2x\n", pByte[1] );
+#endif
+ /* Bit 3, 2, 1, 0 of Byte 2 represent the RCode */
+
+ return ( ( int32 ) pByte[1] );
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSAllocateMemory(int32 dwSize, void * * ppMemory)
+{
+
+ int32 dwError = 0;
+ void * pMemory = NULL;
+
+ pMemory = malloc(dwSize);
+ if (!pMemory){
+ dwError = ERROR_OUTOFMEMORY;
+ *ppMemory = NULL;
+ }else {
+ memset(pMemory,0, dwSize);
+ *ppMemory = pMemory;
+ }
+ return (dwError);
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSReallocMemory(void * pMemory, void * * ppNewMemory, int32 dwSize)
+{
+ int32 dwError = 0;
+ void * pNewMemory = NULL;
+
+ if (pMemory == NULL) {
+ pNewMemory = malloc(dwSize);
+ memset(pNewMemory, 0, dwSize);
+ }else {
+ pNewMemory = realloc(pMemory, dwSize);
+ }
+ if (!pNewMemory){
+ dwError = ERROR_OUTOFMEMORY;
+ *ppNewMemory = NULL;
+ }else {
+ *ppNewMemory = pNewMemory;
+ }
+
+ return(dwError);
+}
+
+/*********************************************************************
+*********************************************************************/
+
+void DNSFreeMemory( void * pMemory )
+{
+ free(pMemory);
+ return;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSAllocateString(char *pszInputString, char **ppszOutputString)
+{
+ int32 dwError = 0;
+ int32 dwLen = 0;
+ char * pszOutputString = NULL;
+
+ if (!pszInputString || !*pszInputString){
+ dwError = ERROR_INVALID_PARAMETER;
+ BAIL_ON_ERROR(dwError);
+ }
+ dwLen = (int32)strlen(pszInputString);
+ dwError = DNSAllocateMemory(dwLen+1, (void * *)&pszOutputString);
+ BAIL_ON_ERROR(dwError);
+
+ strcpy(pszOutputString, pszInputString);
+
+ *ppszOutputString = pszOutputString;
+
+ return(dwError);
+error:
+ *ppszOutputString = pszOutputString;
+ return(dwError);
+}
+
+/*********************************************************************
+*********************************************************************/
+
+void DNSFreeString(char * pszString)
+{
+ return;
+}
+
+
+
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 52426c31ae..4f1f0146a7 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -2691,18 +2691,18 @@ char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name )
status = ads_find_machine_acct(ads, (void **)(void *)&res, global_myname());
if (!ADS_ERR_OK(status)) {
- DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n",
+ DEBUG(0,("ads_get_upn: Failed to find account for %s\n",
global_myname()));
goto out;
}
if ( (count = ads_count_replies(ads, res)) != 1 ) {
- DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count));
+ DEBUG(1,("ads_get_upn: %d entries returned!\n", count));
goto out;
}
if ( (name = ads_pull_string(ads, ctx, res, "userPrincipalName")) == NULL ) {
- DEBUG(0,("ads_get_dnshostname: No userPrincipalName attribute!\n"));
+ DEBUG(2,("ads_get_upn: No userPrincipalName attribute!\n"));
}
out:
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 2fbe088653..e6ad7c21b3 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -55,6 +55,9 @@ int net_ads_usage(int argc, const char **argv)
d_printf(" Issue LDAP search queries using a general filter, by DN, or by SID\n");
d_printf("keytab\n");
d_printf(" Manage a local keytab file based on the machine account in AD\n");
+ d_printf("dns\n");
+ d_printf(" Issue a dynamic DNS update request the server's hostname\n");
+ d_printf(" (using the machine credentials)\n");
return -1;
}
@@ -1136,7 +1139,89 @@ static BOOL net_derive_salting_principal( TALLOC_CTX *ctx, ADS_STRUCT *ads )
return kerberos_secrets_store_des_salt( salt );
}
-/*********************************************************
+/*******************************************************************
+ Send a DNS update request
+*******************************************************************/
+
+#if defined(WITH_DNS_UPDATES)
+static BOOL net_update_dns( TALLOC_CTX *ctx, ADS_STRUCT *ads )
+{
+ int num_addrs;
+ struct in_addr *iplist = NULL;
+ struct dns_rr_ns *nameservers = NULL;
+ int ns_count = 0;
+ int ret = 0;
+ NTSTATUS dns_status;
+ fstring machine_name;
+ fstring dns_server;
+ const char *dnsdomain;
+ ADS_STRUCT *ads_s = NULL;
+
+ name_to_fqdn( machine_name, global_myname() );
+ strlower_m( machine_name );
+
+ if ( (dnsdomain = strchr_m( machine_name, '.')) == NULL ) {
+ d_printf("No DNS domain configured for %s. Unable to perform DNS Update.\n",
+ machine_name);
+ goto done;
+ }
+ dnsdomain++;
+
+ dns_status = ads_dns_lookup_ns( ctx, dnsdomain, &nameservers, &ns_count );
+ if ( !NT_STATUS_IS_OK(dns_status) || (ns_count == 0)) {
+ DEBUG(3,("net_ads_join: Failed to find name server for the %s realm\n",
+ ads->config.realm));
+ goto done;
+ }
+
+ /* Get our ip address (not the 127.0.0.x address but a real ip address) */
+
+ num_addrs = get_my_ip_address( &iplist );
+ if ( num_addrs <= 0 ) {
+ DEBUG(4,("net_ads_join: Failed to find my non-loopback IP addresses!\n"));
+ ret = -1;
+ goto done;
+ }
+
+ /* Drop the user creds */
+
+ ads_kdestroy( NULL );
+
+ ads_s = ads_init( ads->server.realm, ads->server.workgroup, ads->server.ldap_server );
+ if ( !ads_s ) {
+ DEBUG(1,("net_ads_join: ads_init() failed!\n"));
+ ret = -1;
+ goto done;
+ }
+
+ /* kinit with the machine password */
+
+ asprintf( &ads_s->auth.user_name, "%s$", global_myname() );
+ ads_s->auth.password = secrets_fetch_machine_password( lp_workgroup(), NULL, NULL );
+ ads_s->auth.realm = SMB_STRDUP( lp_realm() );
+ ads_kinit_password( ads_s );
+
+ /* Now perform the dns update - we'll try non-secure and if we fail, we'll
+ follow it up with a secure update */
+
+ fstrcpy( dns_server, nameservers[0].hostname );
+
+ ret = DoDNSUpdate(dns_server, dnsdomain, machine_name, iplist, num_addrs );
+ if ( ret ) {
+ DEBUG(1, ("Error creating dns update!\n"));
+ }
+
+done:
+ SAFE_FREE( iplist );
+ if ( ads_s )
+ ads_destroy( &ads_s );
+
+ return (ret == 0);
+}
+#endif
+
+
+/*******************************************************************
utility function to parse an integer parameter from
"parameter = value"
**********************************************************/
@@ -1174,6 +1259,7 @@ int net_ads_join(int argc, const char **argv)
ADS_STRUCT *ads = NULL;
ADS_STATUS status;
NTSTATUS nt_status;
+ char *machine_account = NULL;
const char *short_domain_name = NULL;
char *tmp_password, *password;
struct cldap_netlogon_reply cldap_reply;
@@ -1352,8 +1438,19 @@ int net_ads_join(int argc, const char **argv)
DEBUG(1,("Error creating host keytab!\n"));
}
+#if defined(WITH_DNS_UPDATES)
+ /* We enter this block with user creds */
+
+ if ( !net_update_dns( ctx, ads ) ) {
+ d_fprintf( stderr, "DNS update failed!\n" );
+ }
+
+ /* exit from this block using machine creds */
+#endif
+
d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->config.realm);
+ SAFE_FREE(machine_account);
TALLOC_FREE( ctx );
ads_destroy(&ads);
@@ -1361,11 +1458,85 @@ int net_ads_join(int argc, const char **argv)
fail:
/* issue an overall failure message at the end. */
- d_printf("Failed to join domain: %s\n",
- get_friendly_nt_error_msg(nt_status));
+ d_printf("Failed to join domain: %s\n", get_friendly_nt_error_msg(nt_status));
+
+ SAFE_FREE(machine_account);
+ TALLOC_FREE( ctx );
+ ads_destroy(&ads);
+
+ return -1;
+
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static int net_ads_dns_usage(int argc, const char **argv)
+{
+#if defined(WITH_DNS_UPDATES)
+ d_printf("net ads dns <command>\n");
+ d_printf("Valid commands:\n");
+ d_printf(" register Issue a dynamic DNS update request for our hostname\n");
+
+ return 0;
+#else
+ d_fprintf(stderr, "DNS update support not enabled at compile time!\n");
+ return -1;
+#endif
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static int net_ads_dns(int argc, const char **argv)
+{
+#if defined(WITH_DNS_UPDATES)
+ ADS_STRUCT *ads;
+ ADS_STATUS status;
+ TALLOC_CTX *ctx;
+ BOOL register_dns = False;
+ int i;
+
+ status = ads_startup(True, &ads);
+ if ( !ADS_ERR_OK(status) ) {
+ DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status)));
+ return -1;
+ }
+
+ if (!(ctx = talloc_init("net_ads_dns"))) {
+ DEBUG(0, ("Could not initialise talloc context\n"));
+ return -1;
+ }
+
+ /* process additional command line args */
+
+ for ( i=0; i<argc; i++ ) {
+ if ( strequal(argv[i], "register") ) {
+ register_dns = True;
+ }
+ else {
+ d_fprintf(stderr, "Bad option: %s\n", argv[i]);
+ return -1;
+ }
+ }
+
+ if ( !net_update_dns( ctx, ads ) ) {
+ d_fprintf( stderr, "DNS update failed!\n" );
+ ads_destroy( &ads );
+ TALLOC_FREE( ctx );
+ return -1;
+ }
+
+ d_fprintf( stderr, "Successfully registered hostname with DNS\n" );
+
ads_destroy(&ads);
TALLOC_FREE( ctx );
+
+ return 0;
+#else
+ d_fprintf(stderr, "DNS update support not enabled at compile time!\n");
return -1;
+#endif
}
/*******************************************************************
@@ -2026,6 +2197,7 @@ int net_ads_help(int argc, const char **argv)
{"SEARCH", net_ads_search_usage},
{"INFO", net_ads_info},
{"JOIN", net_ads_join_usage},
+ {"DNS", net_ads_dns_usage},
{"LEAVE", net_ads_leave},
{"STATUS", net_ads_status},
{"PASSWORD", net_ads_password},
@@ -2046,6 +2218,7 @@ int net_ads(int argc, const char **argv)
{"STATUS", net_ads_status},
{"USER", net_ads_user},
{"GROUP", net_ads_group},
+ {"DNS", net_ads_dns},
{"PASSWORD", net_ads_password},
{"CHANGETRUSTPW", net_ads_changetrustpw},
{"PRINTER", net_ads_printer},
diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c
new file mode 100644
index 0000000000..873eda377e
--- /dev/null
+++ b/source3/utils/net_dns.c
@@ -0,0 +1,99 @@
+
+/*
+ Samba Unix/Linux Dynamic DNS Update
+ net ads commands
+
+ Copyright (C) Krishna Ganugapati (krishnag@centeris.com) 2006
+ Copyright (C) Gerald Carter 2006
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "utils/net.h"
+#include "dns.h"
+
+#if defined(WITH_DNS_UPDATES)
+
+/*********************************************************************
+*********************************************************************/
+
+int DoDNSUpdate( char *pszServerName, char *pszDomainName,
+ char *pszHostName, struct in_addr *iplist, int num_addrs )
+{
+ int32 dwError = 0;
+ DNS_ERROR dns_status;
+ HANDLE hDNSServer = ( HANDLE ) NULL;
+ int32 dwResponseCode = 0;
+ DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL;
+#if 0
+ DNS_UPDATE_RESPONSE *pDNSSecureUpdateResponse = NULL;
+#endif
+
+ if ( (num_addrs <= 0) || !iplist ) {
+ return -1;
+ }
+
+ dns_status = DNSOpen( pszServerName, DNS_TCP, &hDNSServer );
+ BAIL_ON_DNS_ERROR( dns_status );
+
+ dwError = DNSSendUpdate( hDNSServer, pszDomainName, pszHostName,
+ iplist, num_addrs, &pDNSUpdateResponse );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSUpdateGetResponseCode( pDNSUpdateResponse,
+ &dwResponseCode );
+ if ( dwResponseCode == DNS_REFUSED ) {
+ dwError = -1;
+ }
+ BAIL_ON_ERROR( dwError );
+
+cleanup:
+ return dwError;
+
+error:
+ goto cleanup;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int get_my_ip_address( struct in_addr **ips )
+{
+ struct iface_struct nics[MAX_INTERFACES];
+ int i, n;
+ struct in_addr loopback_ip = *interpret_addr2("127.0.0.1");
+ struct in_addr *list;
+ int count = 0;
+
+ /* find the first non-loopback address from our list of interfaces */
+
+ n = get_interfaces(nics, MAX_INTERFACES);
+
+ if ( (list = SMB_MALLOC_ARRAY( struct in_addr, n )) == NULL ) {
+ return -1;
+ }
+
+ for ( i=0; i<n; i++ ) {
+ if ( nics[i].ip.s_addr != loopback_ip.s_addr ) {
+ memcpy( &list[count++], &nics[i].ip, sizeof( struct in_addr ) );
+ }
+ }
+ *ips = list;
+
+ return count;
+}
+
+#endif /* defined(WITH_DNS_UPDATES) */