summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-12-14 16:27:45 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:16:29 -0500
commitd879aa8f3617b256a16889d04a39a25b27f5bb39 (patch)
treef589ce978809a185c1981d944b423d54936f3c27 /source3
parent35a3773a6df72fc4031b90fb94010193966dbdc0 (diff)
downloadsamba-d879aa8f3617b256a16889d04a39a25b27f5bb39.tar.gz
samba-d879aa8f3617b256a16889d04a39a25b27f5bb39.tar.bz2
samba-d879aa8f3617b256a16889d04a39a25b27f5bb39.zip
r20170: Fix secure DNS updates to work against
Wnidows 2000 DNS which expects the TKEY payload to be in the answer section and not in the additional set of records (like Windows 2003 and the RFC). (This used to be commit a3b6734fdad5fd92dbec075ebcd8d7044aac45c2)
Diffstat (limited to 'source3')
-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);