/****************************************************************
****************************************************************/
-#if 0
+
static ADS_STATUS libnet_join_connect_ads_machine(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
return libnet_join_connect_ads(mem_ctx, r, true);
}
-#endif
+
/****************************************************************
****************************************************************/
size_t num_spns = 0;
char *spn = NULL;
bool ok;
+ const char **netbios_aliases = NULL;
/* Find our DN */
}
}
+ netbios_aliases = lp_netbios_aliases();
+ if (netbios_aliases != NULL) {
+ for (; *netbios_aliases != NULL; netbios_aliases++) {
+ /*
+ * Add HOST/NETBIOSNAME
+ */
+ spn = talloc_asprintf(mem_ctx, "HOST/%s", *netbios_aliases);
+ if (spn == NULL) {
+ TALLOC_FREE(spn);
+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+ }
+ if (!strupper_m(spn)) {
+ TALLOC_FREE(spn);
+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+ }
+
+ ok = ads_element_in_array(spn_array, num_spns, spn);
+ if (ok) {
+ TALLOC_FREE(spn);
+ continue;
+ }
+ ok = add_string_to_array(spn_array, spn,
+ &spn_array, &num_spns);
+ if (!ok) {
+ TALLOC_FREE(spn);
+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+ }
+ TALLOC_FREE(spn);
+
+ /*
+ * Add HOST/netbiosname.domainname
+ */
+ if (r->out.dns_domain_name == NULL) {
+ continue;
+ }
+ fstr_sprintf(my_fqdn, "%s.%s",
+ *netbios_aliases,
+ r->out.dns_domain_name);
+
+ spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn);
+ if (spn == NULL) {
+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+ }
+
+ ok = ads_element_in_array(spn_array, num_spns, spn);
+ if (ok) {
+ TALLOC_FREE(spn);
+ continue;
+ }
+ ok = add_string_to_array(spn_array, spn,
+ &spn_array, &num_spns);
+ if (!ok) {
+ TALLOC_FREE(spn);
+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+ }
+ TALLOC_FREE(spn);
+ }
+ }
+
/* make sure to NULL terminate the array */
spn_array = talloc_realloc(mem_ctx, spn_array, const char *, num_spns + 1);
if (spn_array == NULL) {
/****************************************************************
****************************************************************/
-#if 0
+
static ADS_STATUS libnet_join_set_etypes(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
return ADS_SUCCESS;
}
-#endif
+
/****************************************************************
****************************************************************/
struct libnet_JoinCtx *r)
{
ADS_STATUS status;
+ bool need_etype_update = false;
if (!r->in.ads) {
status = libnet_join_connect_ads_user(mem_ctx, r);
return status;
}
+ status = libnet_join_find_machine_acct(mem_ctx, r);
+ if (!ADS_ERR_OK(status)) {
+ return status;
+ }
+
+ if (r->in.desired_encryption_types != r->out.set_encryption_types) {
+ uint32_t func_level = 0;
+
+ status = ads_domain_func_level(r->in.ads, &func_level);
+ if (!ADS_ERR_OK(status)) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "failed to query domain controller functional level: %s",
+ ads_errstr(status));
+ return status;
+ }
+
+ if (func_level >= DS_DOMAIN_FUNCTION_2008) {
+ need_etype_update = true;
+ }
+ }
+
+ if (need_etype_update) {
+ /*
+ * We need to reconnect as machine account in order
+ * to update msDS-SupportedEncryptionTypes reliable
+ */
+
+ if (r->in.ads->auth.ccache_name != NULL) {
+ ads_kdestroy(r->in.ads->auth.ccache_name);
+ }
+
+ ads_destroy(&r->in.ads);
+
+ status = libnet_join_connect_ads_machine(mem_ctx, r);
+ if (!ADS_ERR_OK(status)) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "Failed to connect as machine account: %s",
+ ads_errstr(status));
+ return status;
+ }
+
+ status = libnet_join_set_etypes(mem_ctx, r);
+ if (!ADS_ERR_OK(status)) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "failed to set machine kerberos encryption types: %s",
+ ads_errstr(status));
+ return status;
+ }
+ }
+
if (!libnet_join_derive_salting_principal(mem_ctx, r)) {
return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
}
domain,
pass,
flags,
- SMB_SIGNING_DEFAULT);
+ SMB_SIGNING_IPC_DEFAULT);
}
/****************************************************************
machine_domain,
machine_password,
flags,
- SMB_SIGNING_DEFAULT);
+ SMB_SIGNING_IPC_DEFAULT);
if (!NT_STATUS_IS_OK(status)) {
status = cli_full_connection(&cli, NULL,
NULL,
"",
0,
- SMB_SIGNING_DEFAULT);
+ SMB_SIGNING_IPC_DEFAULT);
}
if (!NT_STATUS_IS_OK(status)) {
W_ERROR_HAVE_NO_MEMORY(wrong_conf);
}
+ /*
+ * We should generate the warning for the special case when
+ * domain is AD, "security = domain" and the realm parameter is
+ * not set.
+ */
+ if (lp_security() == SEC_DOMAIN &&
+ r->out.domain_is_ad &&
+ !valid_realm) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "Warning: when joining AD domains with security=domain, "
+ "\"realm\" should be defined in the configuration (%s) "
+ "and configuration modification was not requested",
+ wrong_conf);
+ return WERR_OK;
+ }
+
libnet_join_set_error_string(mem_ctx, r,
"Invalid configuration (%s) and configuration modification "
"was not requested", wrong_conf);
+
return WERR_CAN_NOT_COMPLETE;
}
create_local_private_krb5_conf_for_domain(
r->out.dns_domain_name, r->out.netbios_domain_name,
- NULL, smbXcli_conn_remote_sockaddr(cli->conn));
+ sitename, smbXcli_conn_remote_sockaddr(cli->conn));
if (r->out.domain_is_ad &&
!(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) {