diff options
-rw-r--r-- | source3/libaddns/dns.h | 11 | ||||
-rw-r--r-- | source3/libaddns/dnsgss.c | 31 | ||||
-rw-r--r-- | source3/libaddns/dnsrecord.c | 18 | ||||
-rw-r--r-- | source3/utils/net_dns.c | 14 |
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); |