#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 "libads/dns.h"
+#include "../lib/addns/dnsquery.h"
#include "../libds/common/flags.h"
#include "librpc/gen_ndr/libnet_join.h"
#include "libnet/libnet_join.h"
#include "secrets.h"
#include "krb5_env.h"
#include "../libcli/security/security.h"
+#include "libsmb/libsmb.h"
+#include "lib/param/loadparm.h"
#ifdef HAVE_ADS
struct NETLOGON_SAM_LOGON_RESPONSE_EX reply;
print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
- if ( !ads_cldap_netlogon_5(talloc_tos(), addr, ads->server.realm, &reply ) ) {
+
+ if ( !ads_cldap_netlogon_5(talloc_tos(), &ads->ldap.ss, ads->server.realm, &reply ) ) {
d_fprintf(stderr, _("CLDAP query failed!\n"));
return -1;
}
}
if (!ads->config.realm) {
- ads->config.realm = CONST_DISCARD(char *, c->opt_target_workgroup);
+ ads->config.realm = discard_const_p(char, c->opt_target_workgroup);
ads->ldap.port = 389;
}
static int net_ads_workgroup(struct net_context *c, int argc, const char **argv)
{
ADS_STRUCT *ads;
- char addr[INET6_ADDRSTRLEN];
struct NETLOGON_SAM_LOGON_RESPONSE_EX reply;
if (c->display_usage) {
}
if (!ads->config.realm) {
- ads->config.realm = CONST_DISCARD(char *, c->opt_target_workgroup);
+ ads->config.realm = discard_const_p(char, c->opt_target_workgroup);
ads->ldap.port = 389;
}
- print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
- if ( !ads_cldap_netlogon_5(talloc_tos(), addr, ads->server.realm, &reply ) ) {
+ if ( !ads_cldap_netlogon_5(talloc_tos(), &ads->ldap.ss, ads->server.realm, &reply ) ) {
d_fprintf(stderr, _("CLDAP query failed!\n"));
ads_destroy(&ads);
return -1;
}
if (!values) /* must be new field, indicate string field */
return true;
- if (StrCaseCmp(field, "sAMAccountName") == 0) {
+ if (strcasecmp_m(field, "sAMAccountName") == 0) {
disp_fields[0] = SMB_STRDUP((char *) values[0]);
}
- if (StrCaseCmp(field, "description") == 0)
+ if (strcasecmp_m(field, "description") == 0)
disp_fields[1] = SMB_STRDUP((char *) values[0]);
return true;
}
return -1;
}
- rc = ads_find_machine_acct(ads, &res, global_myname());
+ rc = ads_find_machine_acct(ads, &res, lp_netbios_name());
if (!ADS_ERR_OK(rc)) {
d_fprintf(stderr, _("ads_find_machine_acct: %s\n"), ads_errstr(rc));
ads_destroy(&ads);
}
if (ads_count_replies(ads, res) == 0) {
- d_fprintf(stderr, _("No machine account for '%s' found\n"), global_myname());
+ d_fprintf(stderr, _("No machine account for '%s' found\n"), lp_netbios_name());
ads_destroy(&ads);
return -1;
}
goto done;
}
- /* Based on what we requseted, we shouldn't get here, but if
+ /* Based on what we requested, we shouldn't get here, but if
we did, it means the secrets were removed, and therefore
we have left the domain */
d_fprintf(stderr, _("Machine '%s' Left domain '%s'\n"),
return WERR_INVALID_DOMAIN_ROLE;
}
- if (strlen(global_myname()) > 15) {
+ if (strlen(lp_netbios_name()) > 15) {
d_printf(_("Our netbios name can be at most 15 chars long, "
- "\"%s\" is %u chars long\n"), global_myname(),
- (unsigned int)strlen(global_myname()));
+ "\"%s\" is %u chars long\n"), lp_netbios_name(),
+ (unsigned int)strlen(lp_netbios_name()));
return WERR_INVALID_COMPUTERNAME;
}
*******************************************************************/
#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;
+ const char *dns_hosts_file;
const char *dnsdomain = NULL;
char *root_domain = NULL;
}
dnsdomain++;
- status = ads_dns_lookup_ns( ctx, dnsdomain, &nameservers, &ns_count );
+ dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL);
+ status = ads_dns_lookup_ns(ctx, dns_hosts_file,
+ dnsdomain, &nameservers, &ns_count);
if ( !NT_STATUS_IS_OK(status) || (ns_count == 0)) {
/* Child domains often do not have NS records. Look
for the NS record for the forest root domain
/* try again for NS servers */
- status = ads_dns_lookup_ns( ctx, root_domain, &nameservers, &ns_count );
+ status = ads_dns_lookup_ns(ctx, dns_hosts_file, 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 "
}
- /* 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 );
+ status = NT_STATUS_UNSUCCESSFUL;
+
+ /* 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:
if (hostname) {
fstrcpy(machine_name, hostname);
} else {
- name_to_fqdn( machine_name, global_myname() );
+ name_to_fqdn( machine_name, lp_netbios_name() );
}
strlower_m( machine_name );
return -1;
}
-/*******************************************************************
- ********************************************************************/
+
+static void _net_ads_join_dns_updates(TALLOC_CTX *ctx, struct libnet_JoinCtx *r)
+{
+#if defined(WITH_DNS_UPDATES)
+ ADS_STRUCT *ads_dns = NULL;
+ int ret;
+ NTSTATUS status;
+
+ /*
+ * 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"));
+ return;
+ }
+
+ if (!r->out.domain_is_ad) {
+ return;
+ }
+
+ /*
+ * We enter this block with user creds.
+ * kinit with the machine password to do dns update.
+ */
+
+ ads_dns = ads_init(lp_realm(), NULL, r->in.dc_name);
+
+ if (ads_dns == NULL) {
+ d_fprintf(stderr, _("DNS update failed: out of memory!\n"));
+ goto done;
+ }
+
+ use_in_memory_ccache();
+
+ ret = asprintf(&ads_dns->auth.user_name, "%s$", lp_netbios_name());
+ if (ret == -1) {
+ d_fprintf(stderr, _("DNS update failed: out of memory\n"));
+ goto done;
+ }
+
+ ads_dns->auth.password = secrets_fetch_machine_password(
+ r->out.netbios_domain_name, NULL, NULL);
+ if (ads_dns->auth.password == NULL) {
+ d_fprintf(stderr, _("DNS update failed: out of memory\n"));
+ goto done;
+ }
+
+ ads_dns->auth.realm = SMB_STRDUP(r->out.dns_domain_name);
+ if (ads_dns->auth.realm == NULL) {
+ d_fprintf(stderr, _("DNS update failed: out of memory\n"));
+ goto done;
+ }
+
+ strupper_m(ads_dns->auth.realm);
+
+ ret = ads_kinit_password(ads_dns);
+ if (ret != 0) {
+ d_fprintf(stderr,
+ _("DNS update failed: kinit failed: %s\n"),
+ error_message(ret));
+ goto done;
+ }
+
+ status = net_update_dns(ctx, ads_dns, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf( stderr, _("DNS update failed: %s\n"),
+ nt_errstr(status));
+ }
+
+done:
+ ads_destroy(&ads_dns);
+#endif
+
+ return;
+}
+
int net_ads_join(struct net_context *c, int argc, const char **argv)
{
/* process additional command line args */
for ( i=0; i<argc; i++ ) {
- if ( !StrnCaseCmp(argv[i], "createupn", strlen("createupn")) ) {
+ if ( !strncasecmp_m(argv[i], "createupn", strlen("createupn")) ) {
createupn = true;
machineupn = get_string_param(argv[i]);
}
- else if ( !StrnCaseCmp(argv[i], "createcomputer", strlen("createcomputer")) ) {
+ else if ( !strncasecmp_m(argv[i], "createcomputer", strlen("createcomputer")) ) {
if ( (create_in_ou = get_string_param(argv[i])) == NULL ) {
d_fprintf(stderr, _("Please supply a valid OU path.\n"));
werr = WERR_INVALID_PARAM;
goto fail;
}
}
- else if ( !StrnCaseCmp(argv[i], "osName", strlen("osName")) ) {
+ else if ( !strncasecmp_m(argv[i], "osName", strlen("osName")) ) {
if ( (os_name = get_string_param(argv[i])) == NULL ) {
d_fprintf(stderr, _("Please supply a operating system name.\n"));
werr = WERR_INVALID_PARAM;
goto fail;
}
}
- else if ( !StrnCaseCmp(argv[i], "osVer", strlen("osVer")) ) {
+ else if ( !strncasecmp_m(argv[i], "osVer", strlen("osVer")) ) {
if ( (os_version = get_string_param(argv[i])) == NULL ) {
d_fprintf(stderr, _("Please supply a valid operating system version.\n"));
werr = WERR_INVALID_PARAM;
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;
}
r->out.netbios_domain_name);
}
-#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.
+ * We try doing the dns update (if it was compiled in).
+ * If the dns update fails, we still consider the join
+ * operation as succeeded if we came this far.
*/
- 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;
-
- if ( (ads_dns = ads_init( lp_realm(), NULL, NULL )) != NULL ) {
- /* kinit with the machine password */
-
- use_in_memory_ccache();
- if (asprintf( &ads_dns->auth.user_name, "%s$", global_myname()) == -1) {
- goto fail;
- }
- ads_dns->auth.password = secrets_fetch_machine_password(
- r->out.netbios_domain_name, NULL, NULL );
- ads_dns->auth.realm = SMB_STRDUP( r->out.dns_domain_name );
- strupper_m(ads_dns->auth.realm );
- ads_kinit_password( ads_dns );
- }
-
- if ( !ads_dns || !NT_STATUS_IS_OK(net_update_dns( ctx, ads_dns, NULL)) ) {
- d_fprintf( stderr, _("DNS update failed!\n") );
- }
-
- /* exit from this block using machine creds */
- ads_destroy(&ads_dns);
- }
-
-done:
-#endif
+ _net_ads_join_dns_updates(ctx, r);
TALLOC_FREE(r);
TALLOC_FREE( ctx );
if (argc > 1) {
servername = argv[1];
} else {
- servername = global_myname();
+ servername = lp_netbios_name();
}
rc = ads_find_printer_on_server(ads, &res, printername, servername);
if (argc == 2) {
servername = argv[1];
} else {
- servername = global_myname();
+ servername = lp_netbios_name();
}
/* Get printer data from SPOOLSS */
resolve_name(servername, &server_ss, 0x20, false);
- nt_status = cli_full_connection(&cli, global_myname(), servername,
+ nt_status = cli_full_connection(&cli, lp_netbios_name(), servername,
&server_ss, 0,
"IPC$", "IPC",
c->opt_user_name, c->opt_workgroup,
c->opt_password ? c->opt_password : "",
CLI_FULL_CONNECTION_USE_KERBEROS,
- Undefined);
+ SMB_SIGNING_DEFAULT);
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);
if (argc > 1) {
servername = argv[1];
} else {
- servername = global_myname();
+ servername = lp_netbios_name();
}
rc = ads_find_printer_on_server(ads, &res, argv[0], servername);
ADS_STRUCT *ads;
const char *auth_principal = c->opt_user_name;
const char *auth_password = c->opt_password;
- char *realm = NULL;
- char *new_password = NULL;
+ const char *realm = NULL;
+ const char *new_password = NULL;
char *chr, *prompt;
const char *user;
ADS_STATUS ret;
}
if (argv[1]) {
- new_password = (char *)argv[1];
+ new_password = (const char *)argv[1];
} else {
if (asprintf(&prompt, _("Enter new password for %s:"), user) == -1) {
return -1;
return -1;
}
- fstrcpy(my_name, global_myname());
+ fstrcpy(my_name, lp_netbios_name());
strlower_m(my_name);
if (asprintf(&host_principal, "%s$@%s", my_name, ads->config.realm) == -1) {
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)) {
return net_ads_noads();
}
-#endif /* WITH_ADS */
+#endif /* HAVE_ADS */