summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2021-02-09 17:15:20 +0100
committerGünther Deschner <gd@samba.org>2021-07-14 16:49:30 +0000
commit3e3269d34b28603dca50db75f6b079ff21d3e932 (patch)
treeb7508f3e08fdff9af08a859f5517fce4a693e419
parente7a8aeee4490a0d9a3324e7c1bcff491ec88a3f0 (diff)
downloadsamba-3e3269d34b28603dca50db75f6b079ff21d3e932.tar.gz
s3-libnetapi: implement NetRequestOfflineDomainJoin_l
Guenther Signed-off-by: Guenther Deschner <gd@samba.org> Reviewed-by: Alexander Bokovoy <ab@samba.org>
-rw-r--r--source3/lib/netapi/joindomain.c114
1 files changed, 113 insertions, 1 deletions
diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c
index 3ba9cce4f64..da40a887172 100644
--- a/source3/lib/netapi/joindomain.c
+++ b/source3/lib/netapi/joindomain.c
@@ -799,8 +799,120 @@ WERROR NetRequestOfflineDomainJoin_r(struct libnetapi_ctx *ctx,
/****************************************************************
****************************************************************/
+static WERROR NetRequestOfflineDomainJoin_backend(struct libnetapi_ctx *ctx,
+ const struct ODJ_WIN7BLOB *win7blob,
+ const struct ODJ_PROVISION_DATA *odj_provision_data)
+{
+ struct libnet_JoinCtx *j = NULL;
+ WERROR werr;
+
+ werr = libnet_init_JoinCtx(ctx, &j);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ j->in.domain_name = talloc_strdup(j, win7blob->lpDomain);
+ if (j->in.domain_name == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ talloc_free(discard_const_p(char *, j->in.machine_name));
+ j->in.machine_name = talloc_strdup(j, win7blob->lpMachineName);
+ if (j->in.machine_name == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ j->in.machine_password = talloc_strdup(j, win7blob->lpMachinePassword);
+ if (j->in.machine_password == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ j->in.request_offline_join = true;
+ j->in.odj_provision_data = discard_const(odj_provision_data);
+ j->in.debug = true;
+ j->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
+ WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED;
+
+ werr = libnet_Join(j, j);
+ if (!W_ERROR_IS_OK(werr) && j->out.error_string) {
+ libnetapi_set_error_string(ctx, "%s", j->out.error_string);
+ talloc_free(j);
+ return werr;
+ }
+
+ TALLOC_FREE(j);
+
+ return WERR_OK;
+}
+
WERROR NetRequestOfflineDomainJoin_l(struct libnetapi_ctx *ctx,
struct NetRequestOfflineDomainJoin *r)
{
- return WERR_NOT_SUPPORTED;
+ DATA_BLOB blob, blob_base64;
+ enum ndr_err_code ndr_err;
+ struct ODJ_PROVISION_DATA_serialized_ptr odj_provision_data;
+ bool ok;
+ struct ODJ_WIN7BLOB win7blob = { 0 };
+ WERROR werr;
+
+ if (r->in.provision_bin_data == NULL ||
+ r->in.provision_bin_data_size == 0) {
+ return W_ERROR(NERR_NoOfflineJoinInfo);
+ }
+
+ if (r->in.provision_bin_data_size < 2) {
+ return W_ERROR(NERR_BadOfflineJoinInfo);
+ }
+
+ if (r->in.provision_bin_data[0] == 0xff &&
+ r->in.provision_bin_data[1] == 0xfe) {
+ ok = convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX,
+ r->in.provision_bin_data+2,
+ r->in.provision_bin_data_size-2,
+ &blob_base64.data,
+ &blob_base64.length);
+ if (!ok) {
+ return W_ERROR(NERR_BadOfflineJoinInfo);
+ }
+ } else {
+ blob_base64 = data_blob(r->in.provision_bin_data,
+ r->in.provision_bin_data_size);
+ }
+
+ blob = base64_decode_data_blob_talloc(ctx, (const char *)blob_base64.data);
+
+ ndr_err = ndr_pull_struct_blob(&blob, ctx, &odj_provision_data,
+ (ndr_pull_flags_fn_t)ndr_pull_ODJ_PROVISION_DATA_serialized_ptr);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return W_ERROR(NERR_BadOfflineJoinInfo);
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_DEBUG(ODJ_PROVISION_DATA_serialized_ptr, &odj_provision_data);
+ }
+
+ if (odj_provision_data.s.p->ulVersion != 1) {
+ return W_ERROR(NERR_ProvisioningBlobUnsupported);
+ }
+
+ werr = libnet_odj_find_win7blob(odj_provision_data.s.p, &win7blob);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ if (!(r->in.options & NETSETUP_PROVISION_ONLINE_CALLER)) {
+ return WERR_NERR_SETUPNOTJOINED;
+ }
+
+ werr = NetRequestOfflineDomainJoin_backend(ctx,
+ &win7blob,
+ odj_provision_data.s.p);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ return W_ERROR(NERR_JoinPerformedMustRestart);
}