diff options
Diffstat (limited to 'source3/utils/net_ads.c')
-rw-r--r-- | source3/utils/net_ads.c | 117 |
1 files changed, 100 insertions, 17 deletions
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index b618ab81b9..83aef18cef 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1197,29 +1197,48 @@ done: return status; } -static NTSTATUS net_update_dns(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads) +static NTSTATUS net_update_dns_ext(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads, + const char *hostname, + struct sockaddr_storage *iplist, + int num_addrs) { - int num_addrs; - struct sockaddr_storage *iplist = NULL; + struct sockaddr_storage *iplist_alloc = NULL; fstring machine_name; NTSTATUS status; - name_to_fqdn( machine_name, global_myname() ); + if (hostname) { + fstrcpy(machine_name, hostname); + } else { + name_to_fqdn( machine_name, global_myname() ); + } strlower_m( machine_name ); - /* 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_update_dns: Failed to find my non-loopback IP " - "addresses!\n")); - return NT_STATUS_INVALID_PARAMETER; + if (num_addrs == 0 || iplist == NULL) { + /* + * Get our ip address + * (not the 127.0.0.x address but a real ip address) + */ + num_addrs = get_my_ip_address(&iplist_alloc); + if ( num_addrs <= 0 ) { + DEBUG(4, ("net_update_dns_ext: Failed to find my " + "non-loopback IP addresses!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + iplist = iplist_alloc; } status = net_update_dns_internal(mem_ctx, ads, machine_name, iplist, num_addrs); - SAFE_FREE( iplist ); + + SAFE_FREE(iplist_alloc); + return status; +} + +static NTSTATUS net_update_dns(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads, const char *hostname) +{ + NTSTATUS status; + + status = net_update_dns_ext(mem_ctx, ads, hostname, NULL, 0); return status; } #endif @@ -1376,6 +1395,23 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) } #if defined(WITH_DNS_UPDATES) + /* + * In a clustered environment, don't do dynamic dns updates: + * Registering the set of ip addresses that are assigned to + * the interfaces of the node that performs the join does usually + * not have the desired effect, since the local interfaces do not + * carry the complete set of the cluster's public IP addresses. + * And it can also contain internal addresses that should not + * be visible to the outside at all. + * In order to do dns updates in a clustererd setup, use + * net ads dns register. + */ + if (lp_clustering()) { + d_fprintf(stderr, _("Not doing automatic DNS update in a" + "clustered setup.\n")); + goto done; + } + if (r->out.domain_is_ad) { /* We enter this block with user creds */ ADS_STRUCT *ads_dns = NULL; @@ -1394,7 +1430,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) ads_kinit_password( ads_dns ); } - if ( !ads_dns || !NT_STATUS_IS_OK(net_update_dns( ctx, ads_dns )) ) { + if ( !ads_dns || !NT_STATUS_IS_OK(net_update_dns( ctx, ads_dns, NULL)) ) { d_fprintf( stderr, _("DNS update failed!\n") ); } @@ -1402,6 +1438,8 @@ int net_ads_join(struct net_context *c, int argc, const char **argv) ads_destroy(&ads_dns); } #endif + +done: TALLOC_FREE(r); TALLOC_FREE( ctx ); @@ -1425,15 +1463,28 @@ static int net_ads_dns_register(struct net_context *c, int argc, const char **ar #if defined(WITH_DNS_UPDATES) ADS_STRUCT *ads; ADS_STATUS status; + NTSTATUS ntstatus; TALLOC_CTX *ctx; + const char *hostname = NULL; + const char **addrs_list = NULL; + struct sockaddr_storage *addrs = NULL; + int num_addrs = 0; + int count; #ifdef DEVELOPER talloc_enable_leak_report(); #endif - if (argc > 0 || c->display_usage) { + if (argc <= 1 && lp_clustering() && lp_cluster_addresses() == NULL) { + d_fprintf(stderr, _("Refusing DNS updates with automatic " + "detection of addresses in a clustered " + "setup.\n")); + c->display_usage = true; + } + + if (c->display_usage) { d_printf( "%s\n" - "net ads dns register\n" + "net ads dns register [hostname [IP [IP...]]]\n" " %s\n", _("Usage:"), _("Register hostname with DNS\n")); @@ -1445,6 +1496,37 @@ static int net_ads_dns_register(struct net_context *c, int argc, const char **ar return -1; } + if (argc >= 1) { + hostname = argv[0]; + } + + if (argc > 1) { + num_addrs = argc - 1; + addrs_list = &argv[1]; + } else if (lp_clustering()) { + addrs_list = lp_cluster_addresses(); + num_addrs = str_list_length(addrs_list); + } + + if (num_addrs > 0) { + addrs = talloc_zero_array(ctx, struct sockaddr_storage, num_addrs); + if (addrs == NULL) { + d_fprintf(stderr, _("Error allocating memory!\n")); + talloc_free(ctx); + return -1; + } + } + + for (count = 0; count < num_addrs; count++) { + if (!interpret_string_addr(&addrs[count], addrs_list[count], 0)) { + d_fprintf(stderr, "%s '%s'.\n", + _("Cannot interpret address"), + addrs_list[count]); + talloc_free(ctx); + return -1; + } + } + status = ads_startup(c, true, &ads); if ( !ADS_ERR_OK(status) ) { DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status))); @@ -1452,7 +1534,8 @@ static int net_ads_dns_register(struct net_context *c, int argc, const char **ar return -1; } - if ( !NT_STATUS_IS_OK(net_update_dns(ctx, ads)) ) { + ntstatus = net_update_dns_ext(ctx, ads, hostname, addrs, num_addrs); + if (!NT_STATUS_IS_OK(ntstatus)) { d_fprintf( stderr, _("DNS update failed!\n") ); ads_destroy( &ads ); TALLOC_FREE( ctx ); |