mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
r20173: DNS update fixes:
* Fix DNS updates for multi-homed hosts * Child domains often don't have an NS record in DNS so we have to fall back to looking up the the NS records for the forest root. * Fix compile warning caused by mismatched 'struct in_addr' and 'in_addr_t' parameters called to DoDNSUpdate()
This commit is contained in:
parent
a1378979be
commit
3486acd3c3
@ -493,7 +493,7 @@ 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,
|
||||
const in_addr_t *ip_addr,
|
||||
const struct in_addr *ip_addr,
|
||||
size_t num_adds,
|
||||
struct dns_update_request **preq);
|
||||
|
||||
|
@ -356,7 +356,7 @@ 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,
|
||||
const in_addr_t *ip_addr,
|
||||
const struct in_addr *ip_addrs,
|
||||
size_t num_addrs,
|
||||
struct dns_update_request **preq)
|
||||
{
|
||||
@ -395,7 +395,7 @@ DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
|
||||
*/
|
||||
|
||||
for ( i=0; i<num_addrs; i++ ) {
|
||||
err = dns_create_a_record(req, hostname, 3600, ip_addr[i], &rec);
|
||||
err = dns_create_a_record(req, hostname, 3600, ip_addrs[i].s_addr, &rec);
|
||||
if (!ERR_DNS_IS_OK(err))
|
||||
goto error;
|
||||
|
||||
|
@ -75,6 +75,28 @@ char *ads_build_dn(const char *realm)
|
||||
return ads_build_path(realm, ".", "dc=", 0);
|
||||
}
|
||||
|
||||
/* return a DNS name in the for aa.bb.cc from the DN
|
||||
"dc=AA,dc=BB,dc=CC". caller must free
|
||||
*/
|
||||
char *ads_build_domain(const char *dn)
|
||||
{
|
||||
char *dnsdomain = NULL;
|
||||
|
||||
/* result should always be shorter than the DN */
|
||||
|
||||
if ( (dnsdomain = SMB_STRDUP( dn )) == NULL ) {
|
||||
DEBUG(0,("ads_build_domain: malloc() failed!\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strlower_m( dnsdomain );
|
||||
all_string_sub( dnsdomain, "dc=", "", 0);
|
||||
all_string_sub( dnsdomain, ",", ".", 0 );
|
||||
|
||||
return dnsdomain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef LDAP_PORT
|
||||
#define LDAP_PORT 389
|
||||
|
@ -1221,7 +1221,7 @@ static BOOL net_derive_salting_principal( TALLOC_CTX *ctx, ADS_STRUCT *ads )
|
||||
|
||||
#if defined(WITH_DNS_UPDATES)
|
||||
#include "dns.h"
|
||||
DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName,
|
||||
DNS_ERROR DoDNSUpdate(char *pszServerName,
|
||||
const char *pszDomainName,
|
||||
const char *pszHostName,
|
||||
const struct in_addr *iplist, int num_addrs );
|
||||
@ -1237,7 +1237,8 @@ static NTSTATUS net_update_dns_internal(TALLOC_CTX *ctx, ADS_STRUCT *ads,
|
||||
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
|
||||
DNS_ERROR dns_err;
|
||||
fstring dns_server;
|
||||
const char *dnsdomain;
|
||||
const char *dnsdomain = NULL;
|
||||
char *root_domain = NULL;
|
||||
|
||||
if ( (dnsdomain = strchr_m( machine_name, '.')) == NULL ) {
|
||||
d_printf("No DNS domain configured for %s. "
|
||||
@ -1249,9 +1250,52 @@ static NTSTATUS net_update_dns_internal(TALLOC_CTX *ctx, ADS_STRUCT *ads,
|
||||
|
||||
status = ads_dns_lookup_ns( ctx, dnsdomain, &nameservers, &ns_count );
|
||||
if ( !NT_STATUS_IS_OK(status) || (ns_count == 0)) {
|
||||
DEBUG(3,("net_ads_join: Failed to find name server for the %s "
|
||||
/* Child domains often do not have NS records. Look
|
||||
for the NS record for the forest root domain
|
||||
(rootDomainNamingContext in therootDSE) */
|
||||
|
||||
const char *rootname_attrs[] = { "rootDomainNamingContext", NULL };
|
||||
LDAPMessage *msg = NULL;
|
||||
char *root_dn;
|
||||
ADS_STATUS ads_status;
|
||||
|
||||
if ( !ads->ld ) {
|
||||
ads_status = ads_connect( ads );
|
||||
if ( !ADS_ERR_OK(ads_status) ) {
|
||||
DEBUG(0,("net_update_dns_internal: Failed to connect to our DC!\n"));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
ads_status = ads_do_search(ads, "", LDAP_SCOPE_BASE,
|
||||
"(objectclass=*)", rootname_attrs, &msg);
|
||||
if (!ADS_ERR_OK(ads_status)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
root_dn = ads_pull_string(ads, ctx, msg, "rootDomainNamingContext");
|
||||
if ( !root_dn ) {
|
||||
ads_msgfree( ads, msg );
|
||||
goto done;
|
||||
}
|
||||
|
||||
root_domain = ads_build_domain( root_dn );
|
||||
|
||||
/* cleanup */
|
||||
ads_msgfree( ads, msg );
|
||||
|
||||
/* try again for NS servers */
|
||||
|
||||
status = ads_dns_lookup_ns( ctx, root_domain, &nameservers, &ns_count );
|
||||
|
||||
if ( !NT_STATUS_IS_OK(status) || (ns_count == 0)) {
|
||||
DEBUG(3,("net_ads_join: Failed to find name server for the %s "
|
||||
"realm\n", ads->config.realm));
|
||||
goto done;
|
||||
goto done;
|
||||
}
|
||||
|
||||
dnsdomain = root_domain;
|
||||
|
||||
}
|
||||
|
||||
/* Now perform the dns update - we'll try non-secure and if we fail,
|
||||
@ -1259,14 +1303,17 @@ static NTSTATUS net_update_dns_internal(TALLOC_CTX *ctx, ADS_STRUCT *ads,
|
||||
|
||||
fstrcpy( dns_server, nameservers[0].hostname );
|
||||
|
||||
dns_err = DoDNSUpdate(ads, dns_server, dnsdomain, machine_name, addrs, num_addrs);
|
||||
dns_err = DoDNSUpdate(dns_server, dnsdomain, machine_name, addrs, num_addrs);
|
||||
if (!ERR_DNS_IS_OK(dns_err)) {
|
||||
status = NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
SAFE_FREE( root_domain );
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS net_update_dns(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads)
|
||||
{
|
||||
@ -1345,6 +1392,8 @@ int net_ads_join(int argc, const char **argv)
|
||||
const char *machineupn = NULL;
|
||||
const char *create_in_ou = NULL;
|
||||
int i;
|
||||
fstring dc_name;
|
||||
struct in_addr dcip;
|
||||
|
||||
nt_status = check_ads_config();
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
@ -1352,6 +1401,10 @@ int net_ads_join(int argc, const char **argv)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* find a DC to initialize the server affinity cache */
|
||||
|
||||
get_dc_name( lp_workgroup(), lp_realm(), dc_name, &dcip );
|
||||
|
||||
status = ads_startup(True, &ads);
|
||||
if (!ADS_ERR_OK(status)) {
|
||||
DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status)));
|
||||
@ -1575,15 +1628,12 @@ static int net_ads_dns_register(int argc, const char **argv)
|
||||
ADS_STRUCT *ads;
|
||||
ADS_STATUS status;
|
||||
TALLOC_CTX *ctx;
|
||||
fstring name;
|
||||
int num_addrs;
|
||||
struct in_addr *iplist = NULL;
|
||||
|
||||
#ifdef DEVELOPER
|
||||
talloc_enable_leak_report();
|
||||
#endif
|
||||
|
||||
if (argc > 2) {
|
||||
if (argc > 0) {
|
||||
d_fprintf(stderr, "net ads dns register <name> <ip>\n");
|
||||
return -1;
|
||||
}
|
||||
@ -1593,48 +1643,17 @@ static int net_ads_dns_register(int argc, const char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc > 0) {
|
||||
fstrcpy(name, argv[0]);
|
||||
} else {
|
||||
name_to_fqdn(name, global_myname());
|
||||
}
|
||||
strlower_m(name);
|
||||
|
||||
if (argc > 1) {
|
||||
if (!(iplist = SMB_MALLOC_ARRAY(struct in_addr, 1))) {
|
||||
d_fprintf(stderr, "net_ads_dns_register: malloc "
|
||||
"failed\n");
|
||||
return -1;
|
||||
}
|
||||
if (inet_aton(argv[1], iplist) == 0) {
|
||||
d_fprintf(stderr, "net_ads_dns_register: %s is not "
|
||||
"a valid IP address\n", argv[1]);
|
||||
SAFE_FREE(iplist);
|
||||
return -1;
|
||||
}
|
||||
num_addrs = 1;
|
||||
} else {
|
||||
num_addrs = get_my_ip_address( &iplist );
|
||||
if ( num_addrs <= 0 ) {
|
||||
d_fprintf(stderr, "net_ads_dns_regiser: Failed to "
|
||||
"find my non-loopback IP addresses!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
status = ads_startup_nobind(True, &ads);
|
||||
status = ads_startup(True, &ads);
|
||||
if ( !ADS_ERR_OK(status) ) {
|
||||
DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status)));
|
||||
TALLOC_FREE(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( !NT_STATUS_IS_OK(net_update_dns_internal(ctx, ads, name,
|
||||
iplist, num_addrs)) ) {
|
||||
if ( !NT_STATUS_IS_OK(net_update_dns(ctx, ads)) ) {
|
||||
d_fprintf( stderr, "DNS update failed!\n" );
|
||||
ads_destroy( &ads );
|
||||
TALLOC_FREE( ctx );
|
||||
SAFE_FREE(iplist);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1642,7 +1661,6 @@ static int net_ads_dns_register(int argc, const char **argv)
|
||||
|
||||
ads_destroy(&ads);
|
||||
TALLOC_FREE( ctx );
|
||||
SAFE_FREE(iplist);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
|
@ -30,9 +30,9 @@
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName,
|
||||
DNS_ERROR DoDNSUpdate(char *pszServerName,
|
||||
const char *pszDomainName, const char *pszHostName,
|
||||
const struct in_addr *iplist, int num_addrs )
|
||||
const struct in_addr *iplist, size_t num_addrs )
|
||||
{
|
||||
DNS_ERROR err;
|
||||
struct dns_connection *conn;
|
||||
@ -74,7 +74,7 @@ DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName,
|
||||
*/
|
||||
|
||||
err = dns_create_update_request(mem_ctx, pszDomainName, pszHostName,
|
||||
iplist[0].s_addr, &req);
|
||||
iplist, num_addrs, &req);
|
||||
if (!ERR_DNS_IS_OK(err)) goto error;
|
||||
|
||||
err = dns_update_transaction(mem_ctx, conn, req, &resp);
|
||||
@ -89,9 +89,7 @@ DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName,
|
||||
* Okay, we have to try with signing
|
||||
*/
|
||||
{
|
||||
ADS_STRUCT *ads_s;
|
||||
gss_ctx_id_t gss_context;
|
||||
int res;
|
||||
char *keyname;
|
||||
|
||||
if (!(keyname = dns_generate_keyname( mem_ctx ))) {
|
||||
@ -99,24 +97,6 @@ DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName,
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(ads_s = ads_init(ads->server.realm, ads->server.workgroup,
|
||||
ads->server.ldap_server))) {
|
||||
return ERROR_DNS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* kinit with the machine password */
|
||||
setenv(KRB5_ENV_CCNAME, "MEMORY:net_ads", 1);
|
||||
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() );
|
||||
res = ads_kinit_password( ads_s );
|
||||
ads_destroy(&ads_s);
|
||||
if (res) {
|
||||
err = ERROR_DNS_GSS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
|
||||
keyname, &gss_context, DNS_SRV_ANY );
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user