summaryrefslogtreecommitdiff
path: root/source3/libnet
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2021-02-15 20:57:56 +0100
committerGünther Deschner <gd@samba.org>2021-07-14 16:49:30 +0000
commit1581d63bfe09dcd0fd9d7a2e07686a071e5dc3e3 (patch)
treee5c358b3adf09cc1f4c6125c2c782574b1064b1e /source3/libnet
parent997fbcbc902d945eb5261ddc6667f830fbcd5931 (diff)
downloadsamba-1581d63bfe09dcd0fd9d7a2e07686a071e5dc3e3.tar.gz
s3-libnet_join: add support for libnet_DomainOfflineJoin
libnet_DomainOfflineJoin will consume the provided offline domain join blob and lay out libnet_Join information to properly store join metadata in the local database. Guenther Signed-off-by: Guenther Deschner <gd@samba.org> Reviewed-by: Alexander Bokovoy <ab@samba.org>
Diffstat (limited to 'source3/libnet')
-rw-r--r--source3/libnet/libnet_join.c100
1 files changed, 99 insertions, 1 deletions
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 553ab05b32c..ce837e730e2 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -45,6 +45,8 @@
#include "auth/credentials/credentials.h"
#include "krb5_env.h"
#include "libsmb/dsgetdcname.h"
+#include "rpc_client/util_netlogon.h"
+#include "libnet/libnet_join_offline.h"
/****************************************************************
****************************************************************/
@@ -936,6 +938,14 @@ static ADS_STATUS libnet_join_post_processing_ads_modify(TALLOC_CTX *mem_ctx,
ADS_STATUS status;
bool need_etype_update = false;
+ if (r->in.request_offline_join) {
+ /*
+ * When in the "request offline join" path we can no longer
+ * modify the AD account as we are operating w/o network - gd
+ */
+ return ADS_SUCCESS;
+ }
+
if (!r->in.ads) {
status = libnet_join_connect_ads_user(mem_ctx, r);
if (!ADS_ERR_OK(status)) {
@@ -2271,6 +2281,14 @@ static WERROR libnet_join_pre_processing(TALLOC_CTX *mem_ctx,
return WERR_INVALID_PARAMETER;
}
+ if (r->in.request_offline_join) {
+ /*
+ * When in the "request offline join" path we do not have admin
+ * credentials available so we can skip the next steps - gd
+ */
+ return WERR_OK;
+ }
+
if (!r->in.admin_domain) {
char *admin_domain = NULL;
char *admin_account = NULL;
@@ -2806,6 +2824,74 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
/****************************************************************
****************************************************************/
+static WERROR libnet_DomainOfflineJoin(TALLOC_CTX *mem_ctx,
+ struct libnet_JoinCtx *r)
+{
+ NTSTATUS status;
+ WERROR werr;
+ struct ODJ_WIN7BLOB win7blob;
+ const char *dc_name;
+
+ if (!r->in.request_offline_join) {
+ return WERR_NERR_DEFAULTJOINREQUIRED;
+ }
+
+ if (r->in.odj_provision_data == NULL) {
+ return WERR_INVALID_PARAMETER;
+ }
+
+ werr = libnet_odj_find_win7blob(r->in.odj_provision_data, &win7blob);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ r->out.netbios_domain_name = talloc_strdup(mem_ctx,
+ win7blob.DnsDomainInfo.Name.string);
+ W_ERROR_HAVE_NO_MEMORY(r->out.netbios_domain_name);
+
+ r->out.dns_domain_name = talloc_strdup(mem_ctx,
+ win7blob.DnsDomainInfo.DnsDomainName.string);
+ W_ERROR_HAVE_NO_MEMORY(r->out.dns_domain_name);
+
+ r->out.forest_name = talloc_strdup(mem_ctx,
+ win7blob.DnsDomainInfo.DnsForestName.string);
+ W_ERROR_HAVE_NO_MEMORY(r->out.forest_name);
+
+ r->out.domain_guid = win7blob.DnsDomainInfo.DomainGuid;
+ r->out.domain_sid = dom_sid_dup(mem_ctx,
+ win7blob.DnsDomainInfo.Sid);
+ W_ERROR_HAVE_NO_MEMORY(r->out.domain_sid);
+
+ dc_name = strip_hostname(win7blob.DcInfo.dc_address);
+ if (dc_name == NULL) {
+ return WERR_DOMAIN_CONTROLLER_NOT_FOUND;
+ }
+ r->in.dc_name = talloc_strdup(mem_ctx, dc_name);
+ W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
+
+ r->out.domain_is_ad = true;
+
+ /* we cannot use talloc_steal but have to deep copy the struct here */
+ status = copy_netr_DsRGetDCNameInfo(mem_ctx, &win7blob.DcInfo,
+ &r->out.dcinfo);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ntstatus_to_werror(status);
+ }
+
+ return WERR_OK;
+#if 0
+ /* the following fields are currently not filled in */
+
+ const char * dn;
+ uint32_t set_encryption_types;
+ const char * krb5_salt;
+ uint32_t account_rid;
+#endif
+}
+
+/****************************************************************
+****************************************************************/
+
static WERROR libnet_join_rollback(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
@@ -2853,7 +2939,11 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
}
if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
- werr = libnet_DomainJoin(mem_ctx, r);
+ if (r->in.request_offline_join) {
+ werr = libnet_DomainOfflineJoin(mem_ctx, r);
+ } else {
+ werr = libnet_DomainJoin(mem_ctx, r);
+ }
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -2872,6 +2962,14 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
}
if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
+ if (r->in.request_offline_join) {
+ /*
+ * When we are serving an offline domain join request we
+ * have no network so we are done here - gd.
+ */
+ goto done;
+ }
+
werr = libnet_join_post_verify(mem_ctx, r);
if (!W_ERROR_IS_OK(werr)) {
libnet_join_rollback(mem_ctx, r);