#include "includes.h"
#include "utils/net.h"
+#include "rpc_client/cli_pipe.h"
#include "librpc/gen_ndr/ndr_krb5pac.h"
-#include "../librpc/gen_ndr/cli_spoolss.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
#include "nsswitch/libwbclient/wbclient.h"
#include "ads.h"
#include "libads/cldap.h"
#include "secrets.h"
#include "krb5_env.h"
#include "../libcli/security/security.h"
+#include "libsmb/libsmb.h"
#ifdef HAVE_ADS
*******************************************************************/
#if defined(WITH_DNS_UPDATES)
-#include "dns.h"
+#include "../lib/addns/dns.h"
DNS_ERROR DoDNSUpdate(char *pszServerName,
const char *pszDomainName, const char *pszHostName,
const struct sockaddr_storage *sslist,
int num_addrs)
{
struct dns_rr_ns *nameservers = NULL;
- int ns_count = 0;
+ int ns_count = 0, i;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
DNS_ERROR dns_err;
fstring dns_server;
}
- /* Now perform the dns update - we'll try non-secure and if we fail,
- we'll follow it up with a secure update */
+ for (i=0; i < ns_count; i++) {
- fstrcpy( dns_server, nameservers[0].hostname );
+ /* Now perform the dns update - we'll try non-secure and if we fail,
+ we'll follow it up with a secure update */
+
+ fstrcpy( dns_server, nameservers[i].hostname );
+
+ dns_err = DoDNSUpdate(dns_server, dnsdomain, machine_name, addrs, num_addrs);
+ if (ERR_DNS_IS_OK(dns_err)) {
+ status = NT_STATUS_OK;
+ goto done;
+ }
+
+ if (ERR_DNS_EQUAL(dns_err, ERROR_DNS_INVALID_NAME_SERVER) ||
+ ERR_DNS_EQUAL(dns_err, ERROR_DNS_CONNECTION_FAILED) ||
+ ERR_DNS_EQUAL(dns_err, ERROR_DNS_SOCKET_ERROR)) {
+ DEBUG(1,("retrying DNS update with next nameserver after receiving %s\n",
+ dns_errstr(dns_err)));
+ continue;
+ }
- dns_err = DoDNSUpdate(dns_server, dnsdomain, machine_name, addrs, num_addrs);
- if (!ERR_DNS_IS_OK(dns_err)) {
d_printf(_("DNS Update for %s failed: %s\n"),
machine_name, dns_errstr(dns_err));
status = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
done:
return status;
}
-static NTSTATUS net_update_dns(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads, const char *hostname)
+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;
}
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
r->in.msg_ctx = c->msg_ctx;
werr = libnet_Join(ctx, r);
+ if (W_ERROR_EQUAL(werr, WERR_DCNOTFOUND) &&
+ strequal(domain, lp_realm())) {
+ r->in.domain_name = lp_workgroup();
+ werr = libnet_Join(ctx, r);
+ }
if (!W_ERROR_IS_OK(werr)) {
goto fail;
}
/* exit from this block using machine creds */
ads_destroy(&ads_dns);
}
-#endif
done:
+#endif
+
TALLOC_FREE(r);
TALLOC_FREE( ctx );
#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 > 1 || 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 [hostname]\n"
+ "net ads dns register [hostname [IP [IP...]]]\n"
" %s\n",
_("Usage:"),
_("Register hostname with DNS\n"));
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)));
return -1;
}
- if ( !NT_STATUS_IS_OK(net_update_dns(ctx, ads, argc == 1 ? argv[0] : NULL)) ) {
+ 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 );
c->opt_user_name, c->opt_workgroup,
c->opt_password ? c->opt_password : "",
CLI_FULL_CONNECTION_USE_KERBEROS,
- Undefined, NULL);
+ Undefined);
if (NT_STATUS_IS_ERR(nt_status)) {
- d_fprintf(stderr, _("Unable to open a connnection to %s to "
+ d_fprintf(stderr, _("Unable to open a connection to %s to "
"obtain data for %s\n"),
servername, printername);
ads_destroy(&ads);
nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_spoolss.syntax_id, &pipe_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
- d_fprintf(stderr, _("Unable to open a connnection to the spoolss pipe on %s\n"),
+ d_fprintf(stderr, _("Unable to open a connection to the spoolss pipe on %s\n"),
servername);
SAFE_FREE(prt_dn);
ads_destroy(&ads);
ldap_exp = argv[0];
attrs = (argv + 1);
- rc = ads_do_search_all(ads, ads->config.bind_path,
+ rc = ads_do_search_retry(ads, ads->config.bind_path,
LDAP_SCOPE_SUBTREE,
ldap_exp, attrs, &res);
if (!ADS_ERR_OK(rc)) {