[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Sep 5 22:12:01 UTC 2023


The branch, master has been updated
       via  f3c632e74ba testprogs: Add net offlinejoin composeodj tests
       via  e92e4b95442 testprogs: Cleanup machine account in net offlinejoin tests
       via  c14a4f51443 s3:net: Allow to load ODJ blob from stdin
       via  b2399b6994c s3:net: Load ODJ blob from file only if "loadfile" parameter is present
       via  4a1f2071a60 s3:net: Add "net offlinejoin composeodj" command
       via  a8bd8f22aac s3:libnetapi: Implement NetComposeOfflineDomainJoin_l()
       via  7cabbec2eaf s3:libnetapi: Add NetComposeOfflineDomainJoin() to API.
       via  532701e3cce s3:libnetapi: Add NetComposeOfflineDomainJoin() boilerplate
       via  740e704bd68 s3:libnetapi: Add NetComposeOfflineDomainJoin() to IDL
       via  bdab834dfad s3:libnetapi: Add some comments to document ODJ blob charset conversions
       via  e4afb211fe3 s3:libnetapi: Return error from RequestOfflineJoin
       via  d3f3c40141d pidl/tests: Add tests for hang with nested struct.
       via  3f3fccab05d pidl/lib: Add recursion detection logic to prevent looping.
      from  171171565f1 .gitlab-ci: Do builds under /builds as this is never an overlayfs

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f3c632e74ba100b455eeac66e8914b11d1d9b0a0
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Mon Sep 4 16:49:52 2023 +0200

    testprogs: Add net offlinejoin composeodj tests
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Tue Sep  5 22:11:46 UTC 2023 on atb-devel-224

commit e92e4b9544231c15eaf0bdbba4505345cd0f6ab5
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Mon Sep 4 16:18:35 2023 +0200

    testprogs: Cleanup machine account in net offlinejoin tests
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit c14a4f51443f67bc46a670a342eed8cb9e81f37d
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Wed Aug 30 20:53:18 2023 +0200

    s3:net: Allow to load ODJ blob from stdin
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b2399b6994c89404f245e1a97ba1c1cf13d7fc86
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Wed Aug 30 20:25:17 2023 +0200

    s3:net: Load ODJ blob from file only if "loadfile" parameter is present
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4a1f2071a6028a761bbe7efee20e9654851b51f0
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Thu Aug 31 12:46:52 2023 +0200

    s3:net: Add "net offlinejoin composeodj" command
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a8bd8f22aac2c223e85e318dba7af8b64052b053
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Thu Aug 31 12:45:42 2023 +0200

    s3:libnetapi: Implement NetComposeOfflineDomainJoin_l()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7cabbec2eaf5aefd3751c635c12556eca590f506
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Thu Aug 31 12:44:26 2023 +0200

    s3:libnetapi: Add NetComposeOfflineDomainJoin() to API.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 532701e3cce9d15e95166ee7c24cd1e4af51fcc4
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Thu Aug 31 12:43:22 2023 +0200

    s3:libnetapi: Add NetComposeOfflineDomainJoin() boilerplate
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 740e704bd68a6b618b62336ba1583c0edeb82d6f
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Thu Aug 31 12:39:04 2023 +0200

    s3:libnetapi: Add NetComposeOfflineDomainJoin() to IDL
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit bdab834dfad55776155915f7ec410b5a192406fa
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Mon Sep 4 10:47:06 2023 +0200

    s3:libnetapi: Add some comments to document ODJ blob charset conversions
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e4afb211fe32f2aa92cc903df948874046f60305
Author: Samuel Cabrero <scabrero at samba.org>
Date:   Wed Aug 30 19:59:04 2023 +0200

    s3:libnetapi: Return error from RequestOfflineJoin
    
    The error code must be returned to caller even if the error string is not set.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13577
    
    Signed-off-by: Samuel Cabrero <scabrero at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d3f3c40141d9d9da776f00cbb85b7f5203f6f1ab
Author: Noel Power <noel.power at suse.com>
Date:   Mon Aug 25 11:53:30 2014 +0100

    pidl/tests: Add tests for hang with nested struct.
    
    make sure hang test calls Parse::Pidl::Typelist::LoadIdl which triggers
    part of the hang
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3f3fccab05d8e8dee0127968c49482600d5cf39e
Author: Noel Power <noel.power at suse.com>
Date:   Tue Dec 2 17:26:41 2014 +0000

    pidl/lib: Add recursion detection logic to prevent looping.
    
    Under some circumstances 'can_contain_deferred' & 'align_type functions' can
    loop.
    
    This prevents a hang when processing sample idl like
    
    interface hang
    {
    	typedef [public] struct {
    		wsp_cbasestoragevariant variant[NUM_ENTRIES];
    	} vt_variant_wrap;
    
    	typedef [public,nodiscriminant,switch_type(uint16)] union {
    		[case(VT_I1)] int8 vt_i1;
    		[case(VT_VARIANT)] vt_variant_wrap vt_variant_wrap;
    	} variant_types;
    
    	typedef [public] struct {
    		[switch_is(vtype)] variant_types vvalue;
    	} wsp_cbasestoragevariant;
    };
    
    which will hang with the following command
    
       pidl --header --ndr-parser -- foo.idl
    
    Signed-off-by: Noel Power <noel.power at suse.com>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 pidl/lib/Parse/Pidl/NDR.pm             |  83 ++++++---
 pidl/tests/header.pl                   |  21 ++-
 source3/lib/netapi/joindomain.c        | 206 +++++++++++++++++++++-
 source3/lib/netapi/libnetapi.c         |  67 +++++++
 source3/lib/netapi/libnetapi.h         |  17 ++
 source3/lib/netapi/netapi.h            |  43 +++++
 source3/librpc/idl/libnetapi.idl       |  20 +++
 source3/utils/net_offlinejoin.c        | 312 ++++++++++++++++++++++++++++++++-
 source3/utils/net_proto.h              |   2 +
 testprogs/blackbox/test_net_offline.sh |  94 ++++++++++
 10 files changed, 836 insertions(+), 29 deletions(-)


Changeset truncated at 500 lines:

diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm
index 7a91dc0d84e..6cd71622328 100644
--- a/pidl/lib/Parse/Pidl/NDR.pm
+++ b/pidl/lib/Parse/Pidl/NDR.pm
@@ -394,10 +394,10 @@ sub GetTypedefLevelTable($$$$)
 
 #####################################################################
 # see if a type contains any deferred data 
-sub can_contain_deferred($)
+sub can_contain_deferred
 {
-	sub can_contain_deferred($);
-	my ($type) = @_;
+	sub can_contain_deferred;
+	my ($type, @types_visited) = @_;
 
 	return 1 unless (hasType($type)); # assume the worst
 
@@ -405,15 +405,29 @@ sub can_contain_deferred($)
 
 	return 0 if (Parse::Pidl::Typelist::is_scalar($type));
 
-	return can_contain_deferred($type->{DATA}) if ($type->{TYPE} eq "TYPEDEF");
+	foreach (@types_visited) {
+		if ($_ == $type) {
+			# we have already encountered this
+			# type, avoid recursion loop here
+			# and return
+			return 0;
+		}
+	}
+
+	return can_contain_deferred($type->{DATA},
+		@types_visited) if ($type->{TYPE} eq "TYPEDEF");
 
 	return 0 unless defined($type->{ELEMENTS});
 
 	foreach (@{$type->{ELEMENTS}}) {
 		return 1 if ($_->{POINTERS});
-		return 1 if (can_contain_deferred ($_->{TYPE}));
+		push(@types_visited,$type);
+		if (can_contain_deferred ($_->{TYPE}, at types_visited)) {
+			pop(@types_visited);
+			return 1;
+		}
+		pop(@types_visited);
 	}
-	
 	return 0;
 }
 
@@ -436,14 +450,13 @@ sub pointer_type($)
 
 #####################################################################
 # work out the correct alignment for a structure or union
-sub find_largest_alignment($)
+sub find_largest_alignment
 {
-	my $s = shift;
+	my ($s, @types_visited) = @_;
 
 	my $align = 1;
 	for my $e (@{$s->{ELEMENTS}}) {
 		my $a = 1;
-
 		if ($e->{POINTERS}) {
 			# this is a hack for NDR64
 			# the NDR layer translates this into
@@ -452,9 +465,10 @@ sub find_largest_alignment($)
 		} elsif (has_property($e, "subcontext")) { 
 			$a = 1;
 		} elsif (has_property($e, "transmit_as")) {
-			$a = align_type($e->{PROPERTIES}->{transmit_as});
+			$a = align_type($e->{PROPERTIES}->{transmit_as},
+				@types_visited);
 		} else {
-			$a = align_type($e->{TYPE}); 
+			$a = align_type($e->{TYPE}, @types_visited);
 		}
 
 		$align = $a if ($align < $a);
@@ -465,11 +479,10 @@ sub find_largest_alignment($)
 
 #####################################################################
 # align a type
-sub align_type($)
+sub align_type
 {
-	sub align_type($);
-	my ($e) = @_;
-
+	sub align_type;
+	my ($e, @types_visited) = @_;
 	if (ref($e) eq "HASH" and $e->{TYPE} eq "SCALAR") {
 		my $ret = $scalar_alignment->{$e->{NAME}};
 		if (not defined $ret) {
@@ -486,21 +499,51 @@ sub align_type($)
 		# warning($e, "assuming alignment of unknown type '$e' is 4");
 	    return 4;
 	}
-
 	my $dt = getType($e);
 
+	foreach (@types_visited) {
+		if ($_ == $dt) {
+			# Chapt 14 of the DCE 1.1: Remote Procedure Call
+			# specification (available from pubs.opengroup.org)
+			# states:
+			# "The alignment of a structure in the octet stream is
+			# the largest of the alignments of the fields it
+			# contains. These fields may also be constructed types.
+			# The same alignment rules apply recursively to
+			# nested constructed types. "
+			#
+			# in the worst case scenario
+			# struct c1 {
+			#   membertypea mema;
+			#   membertypeb memb;
+			#   struct c1 memc;
+			# }
+			# the nested struct c1 memc when encountered
+			# returns 0 ensuring the alignment will be calculated
+			# based on the other fields
+			return 0;
+		}
+	}
+
+
 	if ($dt->{TYPE} eq "TYPEDEF") {
-		return align_type($dt->{DATA});
+		return align_type($dt->{DATA}, @types_visited);
 	} elsif ($dt->{TYPE} eq "CONFORMANCE") {
 		return $dt->{DATA}->{ALIGN};
 	} elsif ($dt->{TYPE} eq "ENUM") {
-		return align_type(Parse::Pidl::Typelist::enum_type_fn($dt));
+		return align_type(Parse::Pidl::Typelist::enum_type_fn($dt),
+			@types_visited);
 	} elsif ($dt->{TYPE} eq "BITMAP") {
-		return align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt));
+		return align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt),
+			@types_visited);
 	} elsif (($dt->{TYPE} eq "STRUCT") or ($dt->{TYPE} eq "UNION")) {
 		# Struct/union without body: assume 4
 		return 4 unless (defined($dt->{ELEMENTS}));
-		return find_largest_alignment($dt);
+		my $res;
+		push(@types_visited, $dt);
+		$res = find_largest_alignment($dt, @types_visited);
+		pop(@types_visited);
+		return $res
 	} elsif (($dt->{TYPE} eq "PIPE")) {
 		return 5;
 	}
diff --git a/pidl/tests/header.pl b/pidl/tests/header.pl
index db594844446..dc8bbd7a293 100755
--- a/pidl/tests/header.pl
+++ b/pidl/tests/header.pl
@@ -4,7 +4,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 27;
+use Test::More tests => 30;
 use FindBin qw($RealBin);
 use lib "$RealBin";
 use Util;
@@ -23,6 +23,16 @@ sub parse_idl($)
 	return Parse::Pidl::Samba4::Header::Parse($ndr);
 }
 
+sub load_and_parse_idl($)
+{
+	my $text = shift;
+	my $ndr;
+	my $idl = Parse::Pidl::IDL::parse_string($text, "nofile");
+	Parse::Pidl::Typelist::LoadIdl($idl, "noname");
+	$ndr = Parse::Pidl::NDR::Parse($idl);
+	return Parse::Pidl::Samba4::Header::Parse($ndr);
+}
+
 like(parse_idl(""), qr/\/\* header auto-generated by pidl \*\/\n/sm, "includes work");
 like(parse_idl("interface x {}"), qr/\/\* header auto-generated by pidl \*\/\n/sm,  "simple empty interface doesn't cause overhead");
 like(parse_idl("interface p { typedef struct { int y; } x; };"),
@@ -59,6 +69,15 @@ like(parse_idl("interface p { typedef struct x { int p; } x; };"),
 like(parse_idl("cpp_quote(\"some-foo\")"),
 	qr/some-foo/sm, "cpp quote");
 
+like(load_and_parse_idl("interface hang {typedef [public] struct { wsp_cbasestoragevariant a[SINGLE]; } foo; typedef [public,nodiscriminant,switch_type(uint16)] union { [case(VT_I1)] int8 vt_i1; [case(VT_VARIANT)] foo b; } variant_types; typedef [public] struct { [switch_is(vtype)] variant_types vvalue; } bar;};"),
+     qr/struct foo.*{.*struct wsp_cbasestoragevariant \*a.*struct bar \{.*union variant_types vvalue.*;/sm,"test for hang with nested struct with union");
+
+like(load_and_parse_idl("interface hang { typedef struct { uint32 count; bar a[count];} foo ; typedef struct { foo b; } bar; };"),
+     qr/struct foo.*{.*struct bar \*a;/sm,"test for hang with nested struct");
+
+like(load_and_parse_idl("interface hang { typedef struct { bar a; } foo ; typedef struct { foo b; } bar; };"),
+     qr/struct foo.*{.*struct bar a;/sm,"test for hang with uncompilable nested struct");
+
 # Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work
 my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] };
 is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn));
diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c
index a2c66877b0c..04fc423b41f 100644
--- a/source3/lib/netapi/joindomain.c
+++ b/source3/lib/netapi/joindomain.c
@@ -33,6 +33,7 @@
 #include "../librpc/gen_ndr/ndr_ODJ.h"
 #include "lib/util/base64.h"
 #include "libnet/libnet_join_offline.h"
+#include "libcli/security/dom_sid.h"
 
 /****************************************************************
 ****************************************************************/
@@ -862,8 +863,10 @@ static WERROR NetRequestOfflineDomainJoin_backend(struct libnetapi_ctx *ctx,
 				  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);
+	if (!W_ERROR_IS_OK(werr)) {
+		if (j->out.error_string != NULL) {
+			libnetapi_set_error_string(ctx, "%s", j->out.error_string);
+		}
 		talloc_free(j);
 		return werr;
 	}
@@ -892,6 +895,10 @@ WERROR NetRequestOfflineDomainJoin_l(struct libnetapi_ctx *ctx,
 		return W_ERROR(NERR_BadOfflineJoinInfo);
 	}
 
+	/*
+	 * Windows produces and consumes UTF16/UCS2 encoded blobs. Check for the
+	 * unicode BOM mark and convert back to UNIX charset if necessary.
+	 */
 	if (r->in.provision_bin_data[0] == 0xff &&
 	    r->in.provision_bin_data[1] == 0xfe) {
 		ok = convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX,
@@ -941,3 +948,198 @@ WERROR NetRequestOfflineDomainJoin_l(struct libnetapi_ctx *ctx,
 
 	return W_ERROR(NERR_JoinPerformedMustRestart);
 }
+
+/****************************************************************
+****************************************************************/
+
+WERROR NetComposeOfflineDomainJoin_r(struct libnetapi_ctx *ctx,
+				     struct NetComposeOfflineDomainJoin *r)
+{
+	return WERR_NOT_SUPPORTED;
+}
+
+/****************************************************************
+****************************************************************/
+
+static WERROR NetComposeOfflineDomainJoin_backend(struct libnetapi_ctx *ctx,
+						  struct NetComposeOfflineDomainJoin *r,
+						  TALLOC_CTX *mem_ctx,
+						  struct ODJ_PROVISION_DATA **p)
+{
+	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, r->in.dns_domain_name);
+	if (j->in.domain_name == NULL) {
+		return WERR_NOT_ENOUGH_MEMORY;
+	}
+
+	j->in.dc_name = talloc_strdup(j, r->in.dc_name);
+	W_ERROR_HAVE_NO_MEMORY(j->in.dc_name);
+
+	j->in.machine_password = talloc_strdup(j, r->in.machine_account_password);
+	W_ERROR_HAVE_NO_MEMORY(j->in.machine_password);
+
+	j->out.account_name = talloc_strdup(j, r->in.machine_account_name);
+	W_ERROR_HAVE_NO_MEMORY(j->out.account_name);
+
+	j->out.dns_domain_name = talloc_strdup(j, r->in.dns_domain_name);
+	W_ERROR_HAVE_NO_MEMORY(j->out.dns_domain_name);
+
+	j->out.netbios_domain_name = talloc_strdup(j, r->in.netbios_domain_name);
+	W_ERROR_HAVE_NO_MEMORY(j->out.netbios_domain_name);
+
+	j->out.domain_sid = dom_sid_dup(j, (struct dom_sid *)r->in.domain_sid);
+	W_ERROR_HAVE_NO_MEMORY(j->out.domain_sid);
+
+	j->out.domain_guid = *r->in.domain_guid;
+
+	j->out.forest_name = talloc_strdup(j, r->in.forest_name);
+	W_ERROR_HAVE_NO_MEMORY(j->out.forest_name);
+
+	j->out.domain_is_ad = r->in.domain_is_ad;
+
+	j->out.dcinfo = talloc_zero(j, struct netr_DsRGetDCNameInfo);
+	W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo);
+
+	j->out.dcinfo->dc_unc = talloc_asprintf(j->out.dcinfo, "\\\\%s", r->in.dc_name);
+	W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo->dc_unc);
+
+	j->out.dcinfo->dc_address = talloc_asprintf(j->out.dcinfo, "\\\\%s", r->in.dc_address);
+	W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo->dc_address);
+
+	j->out.dcinfo->dc_address_type = DS_ADDRESS_TYPE_INET;
+
+	j->out.dcinfo->domain_guid = *r->in.domain_guid;
+
+	j->out.dcinfo->domain_name = talloc_strdup(j->out.dcinfo, r->in.dns_domain_name);
+	W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo->domain_name);
+
+	j->out.dcinfo->forest_name = talloc_strdup(j->out.dcinfo, r->in.forest_name);
+	W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo->forest_name);
+
+	werr = libnet_odj_compose_ODJ_PROVISION_DATA(mem_ctx, j, p);
+	if (!W_ERROR_IS_OK(werr)) {
+		return werr;
+	}
+
+	return WERR_OK;
+}
+
+WERROR NetComposeOfflineDomainJoin_l(struct libnetapi_ctx *ctx,
+				     struct NetComposeOfflineDomainJoin *r)
+{
+	WERROR werr;
+	enum ndr_err_code ndr_err;
+	const char *b64_bin_data_str;
+	DATA_BLOB blob;
+	struct ODJ_PROVISION_DATA_serialized_ptr odj_compose_data;
+	struct ODJ_PROVISION_DATA *p;
+	TALLOC_CTX *tmp_ctx = talloc_stackframe();
+
+	if (r->in.compose_bin_data == NULL &&
+	    r->in.compose_text_data == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+	if (r->in.compose_bin_data != NULL &&
+	    r->in.compose_text_data != NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+	if (r->in.compose_bin_data == NULL &&
+	    r->in.compose_bin_data_size != NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+	if (r->in.compose_bin_data != NULL &&
+	    r->in.compose_bin_data_size == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (r->in.dns_domain_name == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (r->in.netbios_domain_name == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (r->in.domain_sid == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (r->in.domain_guid == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (r->in.forest_name == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (r->in.machine_account_name == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (r->in.machine_account_password == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (r->in.dc_name == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	if (r->in.dc_address == NULL) {
+		werr = WERR_INVALID_PARAMETER;
+		goto out;
+	}
+
+	werr = NetComposeOfflineDomainJoin_backend(ctx, r, tmp_ctx, &p);
+	if (!W_ERROR_IS_OK(werr)) {
+		goto out;
+	}
+
+	ZERO_STRUCT(odj_compose_data);
+
+	odj_compose_data.s.p = p;
+
+	ndr_err = ndr_push_struct_blob(&blob, ctx, &odj_compose_data,
+		(ndr_push_flags_fn_t)ndr_push_ODJ_PROVISION_DATA_serialized_ptr);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		werr = W_ERROR(NERR_BadOfflineJoinInfo);
+		goto out;
+	}
+
+	if (r->out.compose_text_data != NULL) {
+		b64_bin_data_str = base64_encode_data_blob(ctx, blob);
+		if (b64_bin_data_str == NULL) {
+			werr = WERR_NOT_ENOUGH_MEMORY;
+		}
+		*r->out.compose_text_data = b64_bin_data_str;
+	}
+
+	if (r->out.compose_bin_data != NULL &&
+	    r->out.compose_bin_data_size != NULL) {
+		*r->out.compose_bin_data = blob.data;
+		*r->out.compose_bin_data_size = blob.length;
+	}
+
+	werr = WERR_OK;
+out:
+	talloc_free(tmp_ctx);
+	return werr;
+}
diff --git a/source3/lib/netapi/libnetapi.c b/source3/lib/netapi/libnetapi.c
index 2fd97bba75b..29073168ef8 100644
--- a/source3/lib/netapi/libnetapi.c
+++ b/source3/lib/netapi/libnetapi.c
@@ -392,6 +392,73 @@ NET_API_STATUS NetRequestOfflineDomainJoin(uint8_t *provision_bin_data /* [in] [
 	return (NET_API_STATUS)r.out.result;
 }
 
+/****************************************************************
+ NetComposeOfflineDomainJoin
+****************************************************************/
+NET_API_STATUS NetComposeOfflineDomainJoin(const char *dns_domain_name /* [in] [ref] */,
+					   const char *netbios_domain_name /* [in] [ref] */,
+					   struct domsid *domain_sid /* [in] [ref] */,
+					   struct GUID *domain_guid /* [in] [ref] */,
+					   const char *forest_name /* [in] [ref] */,
+					   const char *machine_account_name /* [in] [ref] */,
+					   const char *machine_account_password /* [in] [ref] */,
+					   const char *dc_name /* [in] [unique] */,
+					   const char *dc_address /* [in] [unique] */,
+					   int domain_is_ad /* [in] */,
+					   uint8_t **compose_bin_data /* [in,out] [unique] */,
+					   uint32_t *compose_bin_data_size /* [in,out] [unique] */,
+					   const char * *compose_text_data /* [in,out] [unique] */)
+{
+	struct NetComposeOfflineDomainJoin r;
+	struct libnetapi_ctx *ctx = NULL;
+	NET_API_STATUS status;
+	WERROR werr;
+	TALLOC_CTX *frame = talloc_stackframe();
+
+	ZERO_STRUCT(r);
+
+	status = libnetapi_getctx(&ctx);
+	if (status != 0) {
+		TALLOC_FREE(frame);
+		return status;
+	}
+
+	/* In parameters */
+	r.in.dns_domain_name = dns_domain_name;
+	r.in.netbios_domain_name = netbios_domain_name;
+	r.in.domain_sid = domain_sid;
+	r.in.domain_guid = domain_guid;
+	r.in.forest_name = forest_name;
+	r.in.machine_account_name = machine_account_name;
+	r.in.machine_account_password = machine_account_password;
+	r.in.dc_name = dc_name;
+	r.in.dc_address = dc_address;
+	r.in.domain_is_ad = domain_is_ad;
+	r.in.compose_bin_data = compose_bin_data;
+	r.in.compose_bin_data_size = compose_bin_data_size;
+	r.in.compose_text_data = compose_text_data;
+
+	/* Out parameters */
+	r.out.compose_bin_data = compose_bin_data;
+	r.out.compose_bin_data_size = compose_bin_data_size;
+	r.out.compose_text_data = compose_text_data;
+
+	if (DEBUGLEVEL >= 10) {
+		NDR_PRINT_IN_DEBUG(NetComposeOfflineDomainJoin, &r);
+	}
+
+	werr = NetComposeOfflineDomainJoin_l(ctx, &r);
+
+	r.out.result = W_ERROR_V(werr);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list