summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/libaddns/dns.h11
-rw-r--r--source3/libaddns/dnsgss.c31
-rw-r--r--source3/libaddns/dnsrecord.c18
-rw-r--r--source3/utils/net_dns.c14
4 files changed, 53 insertions, 21 deletions
diff --git a/source3/libaddns/dns.h b/source3/libaddns/dns.h
index a8673563ae..e8fa12c492 100644
--- a/source3/libaddns/dns.h
+++ b/source3/libaddns/dns.h
@@ -280,6 +280,8 @@ typedef int BOOL;
#endif
+enum dns_ServerType { DNS_SRV_ANY, DNS_SRV_WIN2000, DNS_SRV_WIN2003 };
+
struct dns_domain_label {
struct dns_domain_label *next;
char *label;
@@ -405,9 +407,6 @@ DNS_ERROR dns_create_name_in_use_record(TALLOC_CTX *mem_ctx,
const char *name,
const in_addr_t *ip,
struct dns_rrec **prec);
-DNS_ERROR dns_create_name_not_in_use_record(TALLOC_CTX *mem_ctx,
- const char *name, uint32 type,
- struct dns_rrec **prec);
DNS_ERROR dns_create_delete_record(TALLOC_CTX *mem_ctx, const char *name,
uint16 type, uint16 r_class,
struct dns_rrec **prec);
@@ -484,7 +483,8 @@ void display_status( const char *msg, OM_uint32 maj_stat, OM_uint32 min_stat );
DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm,
const char *servername,
const char *keyname,
- gss_ctx_id_t *gss_ctx );
+ gss_ctx_id_t *gss_ctx,
+ enum dns_ServerType srv_type );
DNS_ERROR dns_sign_update(struct dns_update_request *req,
gss_ctx_id_t gss_ctx,
const char *keyname,
@@ -493,7 +493,8 @@ DNS_ERROR dns_sign_update(struct dns_update_request *req,
DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
const char *domainname,
const char *hostname,
- in_addr_t ip_addr,
+ const in_addr_t *ip_addr,
+ size_t num_adds,
struct dns_update_request **preq);
#endif /* HAVE_GSSAPI_SUPPORT */
diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c
index 3d1a038363..5be13a3b77 100644
--- a/source3/libaddns/dnsgss.c
+++ b/source3/libaddns/dnsgss.c
@@ -45,6 +45,7 @@ static int strupr( char *szDomainName )
return ( 0 );
}
+#if 0
/*********************************************************************
*********************************************************************/
@@ -76,12 +77,14 @@ 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 );
}
+#endif
static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx,
struct dns_connection *conn,
const char *keyname,
const gss_name_t target_name,
- gss_ctx_id_t *ctx )
+ gss_ctx_id_t *ctx,
+ enum dns_ServerType srv_type )
{
struct gss_buffer_desc_struct input_desc, *input_ptr, output_desc;
OM_uint32 major, minor;
@@ -123,11 +126,21 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx,
req, keyname, "gss.microsoft.com", t,
t + 86400, DNS_TKEY_MODE_GSSAPI, 0,
output_desc.length, (uint8 *)output_desc.value,
- &rec);
+ &rec );
if (!ERR_DNS_IS_OK(err)) goto error;
- err = dns_add_rrec(req, rec, &req->num_additionals,
- &req->additionals);
+ /* Windows 2000 DNS is broken and requires the
+ TKEY payload in the Answer section instead
+ of the Additional seciton like Windows 2003 */
+
+ if ( srv_type == DNS_SRV_WIN2000 ) {
+ err = dns_add_rrec(req, rec, &req->num_answers,
+ &req->answers);
+ } else {
+ err = dns_add_rrec(req, rec, &req->num_additionals,
+ &req->additionals);
+ }
+
if (!ERR_DNS_IS_OK(err)) goto error;
err = dns_marshall_request(req, req, &buf);
@@ -163,6 +176,7 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx,
*/
if ((resp->num_additionals != 1) ||
+ (resp->num_answers == 0) ||
(resp->answers[0]->type != QTYPE_TKEY)) {
err = ERROR_DNS_INVALID_MESSAGE;
goto error;
@@ -194,7 +208,8 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx,
DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm,
const char *servername,
const char *keyname,
- gss_ctx_id_t *gss_ctx )
+ gss_ctx_id_t *gss_ctx,
+ enum dns_ServerType srv_type )
{
OM_uint32 major, minor;
@@ -250,12 +265,12 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm,
goto error;
}
- err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname, targ_name,
- gss_ctx);
+ err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname,
+ targ_name, gss_ctx, srv_type );
+ gss_release_name( &minor, &targ_name );
krb5_free_principal( krb_ctx, host_principal );
krb5_free_context( krb_ctx );
- gss_release_name( &minor, &targ_name );
error:
TALLOC_FREE(mem_ctx);
diff --git a/source3/libaddns/dnsrecord.c b/source3/libaddns/dnsrecord.c
index 6dfb8edf5c..0cf4793935 100644
--- a/source3/libaddns/dnsrecord.c
+++ b/source3/libaddns/dnsrecord.c
@@ -356,12 +356,14 @@ DNS_ERROR dns_create_probe(TALLOC_CTX *mem_ctx, const char *zone,
DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
const char *domainname,
const char *hostname,
- in_addr_t ip_addr,
+ const in_addr_t *ip_addr,
+ size_t num_addrs,
struct dns_update_request **preq)
{
struct dns_update_request *req;
struct dns_rrec *rec;
DNS_ERROR err;
+ size_t i;
err = dns_create_update(mem_ctx, domainname, &req);
if (!ERR_DNS_IS_OK(err)) return err;
@@ -389,14 +391,18 @@ DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
if (!ERR_DNS_IS_OK(err)) goto error;
/*
- * .. and add our IP
+ * .. and add our IPs
*/
- err = dns_create_a_record(req, hostname, 3600, ip_addr, &rec);
- if (!ERR_DNS_IS_OK(err)) goto error;
+ for ( i=0; i<num_addrs; i++ ) {
+ err = dns_create_a_record(req, hostname, 3600, ip_addr[i], &rec);
+ if (!ERR_DNS_IS_OK(err))
+ goto error;
- err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
- if (!ERR_DNS_IS_OK(err)) goto error;
+ err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
+ if (!ERR_DNS_IS_OK(err))
+ goto error;
+ }
*preq = req;
return ERROR_DNS_SUCCESS;
diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c
index d372211a5f..81d7dd596a 100644
--- a/source3/utils/net_dns.c
+++ b/source3/utils/net_dns.c
@@ -118,8 +118,18 @@ DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName,
}
err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
- keyname, &gss_context );
- if (!ERR_DNS_IS_OK(err)) goto error;
+ keyname, &gss_context, DNS_SRV_ANY );
+
+ /* retry using the Windows 2000 DNS hack */
+ if (!ERR_DNS_IS_OK(err)) {
+ err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
+ keyname, &gss_context,
+ DNS_SRV_WIN2000 );
+ }
+
+ if (!ERR_DNS_IS_OK(err))
+ goto error;
+
err = dns_sign_update(req, gss_context, keyname,
"gss.microsoft.com", time(NULL), 3600);