[Pkg-samba-maint] [Git][samba-team/samba][upstream_4.20] 21 commits: VERSION: Bump version up to Samba 4.20.1...

Michael Tokarev (@mjt) gitlab at salsa.debian.org
Wed May 8 11:27:42 BST 2024



Michael Tokarev pushed to branch upstream_4.20 at Debian Samba Team / samba


Commits:
eaefe503 by Jule Anger at 2024-03-27T18:07:29+01:00
VERSION: Bump version up to Samba 4.20.1...

and re-enable GIT_SNAPSHOT.

Signed-off-by: Jule Anger <janger at samba.org>

- - - - -
19250e13 by Noel Power at 2024-04-11T11:20:16+00:00
Add simple http_client for use in black box tests (in following commits)

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15611
Signed-off-by: Noel Power <noel.power at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
(cherry picked from commit cd6c075476c820b4fe8bdc10a24d8fc8ac74e9c9)

- - - - -
71eac5a0 by Noel Power at 2024-04-11T11:20:16+00:00
selftest: Add basic content-lenght http tests

very simple test of basic http request/response plus some checks to
ensure http response doesn't exceed the response max length set by
the client call.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15611
Signed-off-by: Noel Power <noel.power at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
(cherry picked from commit 74cdebeae3d1bc35eea96b51b9491f6c52844b10)

- - - - -
26206392 by Noel Power at 2024-04-11T11:20:16+00:00
libcli/http: Optimise reading for content-length

Instead of reading byte-by-byte we know the content length we
want to read so lets use it.

Signed-off-by: Noel Power <noel.power at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15611
(cherry picked from commit 5f03d84e3b52bf5a31a0f885cb83bdcb48ec96f7)

- - - - -
7e17e480 by Noel Power at 2024-04-11T11:20:16+00:00
tests: add test for chunked encoding with http cli library

Adds http test client to excercise the http client library
and a blackbox test to run the client. This client is built
only with selftest

also adds a knownfail for the test

Signed-off-by: Noel Power <noel.power at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15611
(cherry picked from commit 30acd609f560352d3edb0c931b9a864110025b2c)

- - - - -
a70e3a36 by Noel Power at 2024-04-11T11:20:16+00:00
libcli/http: Handle http chunked transfer encoding

Also removes the knownfail for the chunked transfer test

Signed-off-by: Noel Power <noel.power at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15611
(cherry picked from commit 03240c91fb6ffcf5afe47c14a1ba7a8bc12f2348)

- - - - -
30bf3d14 by Noel Power at 2024-04-11T11:20:16+00:00
selftest: fix potential reference before assigned error

This would only happen if the test failed (but the message would be
incorrect as 'e' the exception to be stringified doesn't exist.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15611
Signed-off-by: Noel Power <noel.power at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
(cherry picked from commit efdbf0511e0a89f865210170001fbebf17a45278)

- - - - -
2fb1bf02 by Noel Power at 2024-04-11T11:20:16+00:00
selftest: Add new test for testing non-chunk transfer encoding

And add a known fail because there is a bug :-(

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15611
Signed-off-by: Noel Power <noel.power at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
(cherry picked from commit 93709d31590d4ca25fbac813b9e499755b81ddb5)

- - - - -
077f39ba by Noel Power at 2024-04-11T12:24:08+00:00
libcli/http: Detect unsupported Transfer-encoding type

Also removes knownfail for test that now passes

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15611
Signed-off-by: Noel Power <noel.power at suse.com>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
(cherry picked from commit a18c53a9b98e2e8dea08cf0ef08efc59e58ec137)

Autobuild-User(v4-20-test): Jule Anger <janger at samba.org>
Autobuild-Date(v4-20-test): Thu Apr 11 12:24:08 UTC 2024 on atb-devel-224

- - - - -
9155d89a by Andreas Schneider at 2024-04-16T11:24:15+00:00
packaging: Provide a systemd service file for samba-bgqd

There might be scenarios where the background queue daemon should be
running all the time instead of being started on demand. This makes
especially sense for bigger printing servers with a lot of printers. It
takes ~1 sec to get a printer from cups, so a print server with 100
printers needs 100 seconds to update the printer_list.tdb. The service
will be killed because of idle in the meantime.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15600

Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Guenther Deschner <gd at samba.org>
(cherry picked from commit c97071726e163b40f0e391af70e81b3e6c1ab0eb)

- - - - -
db60a194 by Douglas Bagnall at 2024-04-16T11:24:15+00:00
s4:dns_server: less noisy, more informative debug messages

This shouldn't have been DBG_ERR, and it might as well say something
about the tombstone.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15630

Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn at samba.org>

Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
Autobuild-Date(master): Fri Apr 12 15:18:05 UTC 2024 on atb-devel-224

(cherry picked from commit dde973d170e479632d1a411279f4f0fad6608539)

- - - - -
215bb9bd by Alexander Bokovoy at 2024-04-16T12:24:55+00:00
Do not fail checksums for RFC8009 types

While Active Directory does not support yet RFC 8009 encryption and
checksum types, it is possible to verify these checksums when running
with both MIT Kerberos and Heimdal Kerberos. This matters for FreeIPA
domain controller which uses them by default.

[2023/06/16 21:51:04.923873, 10, pid=51149, effective(0, 0), real(0, 0)]
../../lib/krb5_wrap/krb5_samba.c:1496(smb_krb5_kt_open_relative)
  smb_krb5_open_keytab: resolving: FILE:/etc/samba/samba.keytab
[2023/06/16 21:51:04.924196,  2, pid=51149, effective(0, 0), real(0, 0),
class=auth] ../../auth/kerberos/kerberos_pac.c:66(check_pac_checksum)
  check_pac_checksum: Checksum Type 20 is not supported
[2023/06/16 21:51:04.924228,  5, pid=51149, effective(0, 0), real(0, 0),
class=auth] ../../auth/kerberos/kerberos_pac.c:353(kerberos_decode_pac)
  PAC Decode: Failed to verify the service signature: Invalid argument

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15635

Signed-off-by: Alexander Bokovoy <ab at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
(cherry picked from commit 8e931fce126e8c1128da893c806702731c08758a)

Autobuild-User(v4-20-test): Jule Anger <janger at samba.org>
Autobuild-Date(v4-20-test): Tue Apr 16 12:24:55 UTC 2024 on atb-devel-224

- - - - -
8857cf29 by Pavel Filipenský at 2024-04-17T13:37:12+00:00
docs-xml: Add parameter all_groupmem to idmap_ad

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15605

Signed-off-by: Pavel Filipenský <pfilipensky at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
(cherry picked from commit a485d9de2f2d6a9815dcac6addb988a8987e111c)

- - - - -
83701298 by Pavel Filipenský at 2024-04-17T13:37:12+00:00
s3:winbindd: Improve performance of lookup_groupmem() in idmap_ad

The LDAP query of lookup_groupmem() returns all group members from AD
even those with missing uidNumber.  Such group members are useless in
UNIX environment for idmap_ad backend since there is no uid mapping.

'test_user' is member of group "Domanin Users" with 200K members,
only 20K members have set uidNumber.

Without this fix:

$ time id test_user

real    1m5.946s
user    0m0.019s
sys     0m0.012s

With this fix:

$ time id test_user

real    0m3.544s
user    0m0.004s
sys     0m0.007s

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15605

Signed-off-by: Pavel Filipenský <pfilipensky at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
(cherry picked from commit 5d475d26a3d545f04791a04e85a06b8b192e3fcf)

- - - - -
84f82a09 by Pavel Filipenský at 2024-04-17T13:37:12+00:00
selftest: Add "winbind expand groups = 1" to setup_ad_member_idmap_ad

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15605

Signed-off-by: Pavel Filipenský <pfilipensky at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
(cherry picked from commit 2dab3a331b5511b4f2253f2b3b4513db7e52ea9a)

- - - - -
83da49f3 by Pavel Filipenský at 2024-04-17T14:38:42+00:00
tests: Add a test for "all_groups=no" to test_idmap_ad.sh

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15605

Signed-off-by: Pavel Filipenský <pfilipensky at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>

Autobuild-User(master): Pavel Filipensky <pfilipensky at samba.org>
Autobuild-Date(master): Tue Apr  2 13:25:39 UTC 2024 on atb-devel-224

(cherry picked from commit f8b72aa1f72881989990fabc9f4888968bb81967)

Autobuild-User(v4-20-test): Jule Anger <janger at samba.org>
Autobuild-Date(v4-20-test): Wed Apr 17 14:38:42 UTC 2024 on atb-devel-224

- - - - -
d28a889a by yuzu367 at 2024-05-07T07:35:12+00:00
python/samba/tests/blackbox: Add tests for Inherit-only flag propagation

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15636

Signed-off-by: Anna Popova <popova.anna235 at gmail.com>
Reviewed-by: Noel Power <noel.power at suse.com>
Reviewed-by: Ralph Boehme <slow at samba.org>
(cherry picked from commit eba2bfde347041a395f0fbd3c57235be63b1890d)

- - - - -
db658c40 by Anna Popova at 2024-05-07T08:52:48+00:00
s3:utils: Fix Inherit-Only flag being automatically propagated to children

Inherit-only flag applies only to the container it was set to and it
shouldn't be automatically propagated to children.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15636

Signed-off-by: Anna Popova <popova.anna235 at gmail.com>
Reviewed-by: Noel Power <noel.power at suse.com>
Reviewed-by: Ralph Boehme <slow at samba.org>

Autobuild-User(master): Ralph Böhme <slow at samba.org>
Autobuild-Date(master): Mon Apr 29 10:56:48 UTC 2024 on atb-devel-224

(cherry picked from commit 80159018e411c643fbfe7ef82bd33e30b6147901)

Autobuild-User(v4-20-test): Jule Anger <janger at samba.org>
Autobuild-Date(v4-20-test): Tue May  7 08:52:48 UTC 2024 on atb-devel-224

- - - - -
d01b50ec by Jule Anger at 2024-05-08T09:59:43+02:00
WHATSNEW: Add release notes for Samba 4.20.1.

Signed-off-by: Jule Anger <janger at samba.org>

- - - - -
0ba948cb by Jule Anger at 2024-05-08T10:00:17+02:00
VERSION: Disable GIT_SNAPSHOT for the 4.20.1 release.

Signed-off-by: Jule Anger <janger at samba.org>

- - - - -
2667fd06 by Michael Tokarev at 2024-05-08T13:01:44+03:00
New upstream version 4.20.1+dfsg
- - - - -


20 changed files:

- VERSION
- WHATSNEW.txt
- auth/kerberos/kerberos_pac.c
- docs-xml/manpages/idmap_ad.8.xml
- lib/krb5_wrap/krb5_samba.h
- libcli/http/http.c
- libcli/http/http_internal.h
- nsswitch/tests/test_idmap_ad.sh
- + packaging/systemd/samba-bgqd.service.in
- packaging/wscript_build
- + python/samba/tests/blackbox/http_chunk.py
- + python/samba/tests/blackbox/http_content.py
- python/samba/tests/blackbox/smbcacls_propagate_inhertance.py
- selftest/target/Samba3.pm
- selftest/tests.py
- source3/utils/smbcacls.c
- source3/winbindd/winbindd_ads.c
- + source4/client/http_test.c
- source4/dns_server/dnsserver_common.c
- source4/wscript_build


Changes:

=====================================
VERSION
=====================================
@@ -27,7 +27,7 @@ SAMBA_COPYRIGHT_STRING="Copyright Andrew Tridgell and the Samba Team 1992-2024"
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=20
-SAMBA_VERSION_RELEASE=0
+SAMBA_VERSION_RELEASE=1
 
 ########################################################
 # If a official release has a serious bug              #


=====================================
WHATSNEW.txt
=====================================
@@ -1,3 +1,58 @@
+                   ==============================
+                   Release Notes for Samba 4.20.1
+                            May 08, 2024
+                   ==============================
+
+
+This is the latest stable release of the Samba 4.20 release series.
+
+
+Changes since 4.20.0
+--------------------
+
+o  Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
+   * BUG 15630: dns update debug message is too noisy.
+
+o  Alexander Bokovoy <ab at samba.org>
+   * BUG 15635: Do not fail PAC validation for RFC8009 checksums types.
+
+o  Pavel Filipenský <pfilipensky at samba.org>
+   * BUG 15605: Improve performance of lookup_groupmem() in idmap_ad.
+
+o  Anna Popova <popova.anna235 at gmail.com>
+   * BUG 15636: Smbcacls incorrectly propagates inheritance with Inherit-Only
+     flag.
+
+o  Noel Power <noel.power at suse.com>
+   * BUG 15611: http library doesn't support 'chunked transfer encoding'.
+
+o  Andreas Schneider <asn at samba.org>
+   * BUG 15600: Provide a systemd service file for the background queue daemon.
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical:matrix.org matrix room, or
+#samba-technical IRC channel on irc.libera.chat.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored.  All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
                    ==============================
                    Release Notes for Samba 4.20.0
                            March 27, 2024


=====================================
auth/kerberos/kerberos_pac.c
=====================================
@@ -33,6 +33,7 @@
 #include "librpc/gen_ndr/auth.h"
 #include "auth/common_auth.h"
 #include "auth/kerberos/pac_utils.h"
+#include "lib/krb5_wrap/krb5_samba.h"
 
 krb5_error_code check_pac_checksum(DATA_BLOB pac_data,
 					  struct PAC_SIGNATURE_DATA *sig,
@@ -44,26 +45,34 @@ krb5_error_code check_pac_checksum(DATA_BLOB pac_data,
 	krb5_keyusage usage = 0;
 	krb5_boolean checksum_valid = false;
 	krb5_data input;
-
-	switch (sig->type) {
-	case CKSUMTYPE_HMAC_MD5:
-		/* ignores the key type */
-		break;
-	case CKSUMTYPE_HMAC_SHA1_96_AES_256:
-		if (KRB5_KEY_TYPE(keyblock) != ENCTYPE_AES256_CTS_HMAC_SHA1_96) {
-			return EINVAL;
-		}
-		/* ok */
-		break;
-	case CKSUMTYPE_HMAC_SHA1_96_AES_128:
-		if (KRB5_KEY_TYPE(keyblock) != ENCTYPE_AES128_CTS_HMAC_SHA1_96) {
-			return EINVAL;
+	size_t idx = 0;
+	struct {
+		krb5_cksumtype cksum_type;
+		krb5_enctype enc_type;
+	} supported_types[] = {
+		{CKSUMTYPE_HMAC_SHA1_96_AES_256, ENCTYPE_AES256_CTS_HMAC_SHA1_96},
+		{CKSUMTYPE_HMAC_SHA1_96_AES_128, ENCTYPE_AES128_CTS_HMAC_SHA1_96},
+		/* RFC8009 types. Not supported by AD yet but used by FreeIPA and MIT Kerberos */
+		{CKSUMTYPE_HMAC_SHA256_128_AES128, ENCTYPE_AES128_CTS_HMAC_SHA256_128},
+		{CKSUMTYPE_HMAC_SHA384_192_AES256, ENCTYPE_AES256_CTS_HMAC_SHA384_192},
+		{0, 0},
+	};
+
+	for(idx = 0; supported_types[idx].cksum_type != 0; idx++) {
+		if (sig->type == supported_types[idx].cksum_type) {
+			if (KRB5_KEY_TYPE(keyblock) != supported_types[idx].enc_type) {
+				return EINVAL;
+			}
+			/* ok */
+			break;
 		}
-		/* ok */
-		break;
-	default:
-		DEBUG(2,("check_pac_checksum: Checksum Type %"PRIu32" is not supported\n",
-			sig->type));
+	}
+
+	/* do not do key type check for HMAC-MD5 */
+	if ((sig->type != CKSUMTYPE_HMAC_MD5) &&
+	    (supported_types[idx].cksum_type == 0)) {
+		DEBUG(2,("check_pac_checksum: Checksum Type %d is not supported\n",
+			(int)sig->type));
 		return EINVAL;
 	}
 


=====================================
docs-xml/manpages/idmap_ad.8.xml
=====================================
@@ -105,6 +105,16 @@
 		</listitem>
 		</varlistentry>
 		<varlistentry>
+		<term>all_groupmem = yes/no</term>
+		<listitem><para>
+		  If set to <parameter>yes</parameter> winbind will retrieve all
+		  group members for getgrnam(3), getgrgid(3) and getgrent(3) calls,
+		  including those with missing uidNumber.
+		</para>
+		<para>Default: no</para>
+		</listitem>
+		</varlistentry>
+		<varlistentry>
 		<term>deny ous</term>
 		<listitem><para>This parameter is a list of OUs from
 		which objects will not be mapped via the ad idmap


=====================================
lib/krb5_wrap/krb5_samba.h
=====================================
@@ -88,6 +88,34 @@
 #define CKSUMTYPE_HMAC_SHA1_96_AES_256 CKSUMTYPE_HMAC_SHA1_96_AES256
 #endif
 
+/*
+ * RFC8009 encryption types' defines have different names:
+ *
+ * KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128 in Heimdal
+ * ENCTYPE_AES128_CTS_HMAC_SHA256_128 in MIT
+ *
+ * and
+ *
+ * KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192 in Heimdal
+ * ENCTYPE_AES256_CTS_HMAC_SHA384_192 in MIT
+ */
+#if !defined(ENCTYPE_AES128_CTS_HMAC_SHA256_128)
+#define ENCTYPE_AES128_CTS_HMAC_SHA256_128 KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128
+#endif
+#if !defined(ENCTYPE_AES256_CTS_HMAC_SHA384_192)
+#define ENCTYPE_AES256_CTS_HMAC_SHA384_192 KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192
+#endif
+
+/*
+ * Same for older encryption types, rename to have the same defines
+ */
+#if !defined(ENCTYPE_AES128_CTS_HMAC_SHA1_96)
+#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96
+#endif
+#if !defined(ENCTYPE_AES256_CTS_HMAC_SHA1_96)
+#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96
+#endif
+
 /*
  * KRB5_KU_OTHER_ENCRYPTED in Heimdal
  * KRB5_KEYUSAGE_APP_DATA_ENCRYPT in MIT


=====================================
libcli/http/http.c
=====================================
@@ -28,16 +28,28 @@
 
 #undef strcasecmp
 
+enum http_body_type {
+	BODY_NONE = 0,
+	BODY_CONTENT_LENGTH,
+	BODY_CHUNKED,
+	BODY_ERROR = -1
+};
+
 /**
  * Determines if a response should have a body.
- * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
- *     a body. Returns -1 on error.
+ * @return 2 if response MUST use chunked encoding,
+ *         1 if the response MUST have a body;
+ *         0 if the response MUST NOT have a body.
+ * Returns -1 on error.
  */
-static int http_response_needs_body(struct http_request *req)
+static enum http_body_type http_response_needs_body(
+					struct http_request *req)
 {
 	struct http_header *h = NULL;
 
-	if (!req) return -1;
+	if (!req) {
+		return BODY_ERROR;
+	}
 
 	for (h = req->headers; h != NULL; h = h->next) {
 		int cmp;
@@ -45,6 +57,18 @@ static int http_response_needs_body(struct http_request *req)
 		char c;
 		unsigned long long v;
 
+		cmp = strcasecmp(h->key, "Transfer-Encoding");
+		if (cmp == 0) {
+			cmp = strcasecmp(h->value, "chunked");
+			if (cmp == 0) {
+				return BODY_CHUNKED;
+			}
+			/* unsupported Transfer-Encoding type */
+			DBG_ERR("Unsupported transfer encoding type %s\n",
+				h->value);
+			return BODY_ERROR;
+		}
+
 		cmp = strcasecmp(h->key, "Content-Length");
 		if (cmp != 0) {
 			continue;
@@ -52,20 +76,25 @@ static int http_response_needs_body(struct http_request *req)
 
 		n = sscanf(h->value, "%llu%c", &v, &c);
 		if (n != 1) {
-			return -1;
+			return BODY_ERROR;
 		}
 
 		req->remaining_content_length = v;
 
 		if (v != 0) {
-			return 1;
+			return BODY_CONTENT_LENGTH;
 		}
 
-		return 0;
+		return BODY_NONE;
 	}
 
-	return 0;
+	return BODY_NONE;
 }
+struct http_chunk
+{
+	struct http_chunk *prev, *next;
+	DATA_BLOB blob;
+};
 
 struct http_read_response_state {
 	enum http_parser_state	parser_state;
@@ -73,6 +102,7 @@ struct http_read_response_state {
 	uint64_t		max_content_length;
 	DATA_BLOB		buffer;
 	struct http_request	*response;
+	struct http_chunk	*chunks;
 };
 
 /**
@@ -86,7 +116,7 @@ static enum http_read_status http_parse_headers(struct http_read_response_state
 	char			*key = NULL;
 	char			*value = NULL;
 	int			n = 0;
-	int			ret;
+	enum http_body_type	ret;
 
 	/* Sanity checks */
 	if (!state || !state->response) {
@@ -119,19 +149,24 @@ static enum http_read_status http_parse_headers(struct http_read_response_state
 
 		ret = http_response_needs_body(state->response);
 		switch (ret) {
-		case 1:
+		case BODY_CHUNKED:
+			DEBUG(11, ("%s: need to process chunks... %d\n", __func__,
+				   state->response->response_code));
+			state->parser_state = HTTP_READING_CHUNK_SIZE;
+			break;
+		case BODY_CONTENT_LENGTH:
 			if (state->response->remaining_content_length <= state->max_content_length) {
 				DEBUG(11, ("%s: Start of read body\n", __func__));
 				state->parser_state = HTTP_READING_BODY;
 				break;
 			}
 			FALL_THROUGH;
-		case 0:
+		case BODY_NONE:
 			DEBUG(11, ("%s: Skipping body for code %d\n", __func__,
 				   state->response->response_code));
 			state->parser_state = HTTP_READING_DONE;
 			break;
-		case -1:
+		case BODY_ERROR:
 			DEBUG(0, ("%s_: Error in http_response_needs_body\n", __func__));
 			TALLOC_FREE(line);
 			return HTTP_DATA_CORRUPTED;
@@ -162,6 +197,141 @@ error:
 	return status;
 }
 
+static bool http_response_process_chunks(struct http_read_response_state *state)
+{
+	struct http_chunk *chunk = NULL;
+	struct http_request *resp = state->response;
+
+	for (chunk = state->chunks; chunk; chunk = chunk->next) {
+		DBG_DEBUG("processing chunk of size %zi\n",
+			  chunk->blob.length);
+		if (resp->body.data == NULL) {
+			resp->body = chunk->blob;
+			chunk->blob = data_blob_null;
+			talloc_steal(resp, resp->body.data);
+			continue;
+		}
+
+		resp->body.data =
+			talloc_realloc(resp,
+				resp->body.data,
+				uint8_t,
+				resp->body.length + chunk->blob.length);
+		if (!resp->body.data) {
+				return false;
+		}
+		memcpy(resp->body.data + resp->body.length,
+		       chunk->blob.data,
+		       chunk->blob.length);
+
+		resp->body.length += chunk->blob.length;
+
+		TALLOC_FREE(chunk->blob.data);
+		chunk->blob = data_blob_null;
+	}
+	return true;
+}
+
+static enum http_read_status http_read_chunk_term(struct http_read_response_state *state)
+{
+	enum http_read_status	status = HTTP_ALL_DATA_READ;
+	char			*ptr = NULL;
+	char			*line = NULL;
+
+	/* Sanity checks */
+	if (!state || !state->response) {
+		DBG_ERR("%s: Invalid Parameter\n", __func__);
+		return HTTP_DATA_CORRUPTED;
+	}
+
+	line = talloc_strndup(state, (char *)state->buffer.data, state->buffer.length);
+	if (!line) {
+		DBG_ERR("%s: Memory error\n", __func__);
+		return HTTP_DATA_CORRUPTED;
+	}
+	ptr = strstr(line, "\r\n");
+	if (ptr == NULL) {
+		TALLOC_FREE(line);
+		return HTTP_MORE_DATA_EXPECTED;
+	}
+
+	if (strncmp(line, "\r\n", 2) == 0) {
+		/* chunk terminator */
+		if (state->parser_state == HTTP_READING_FINAL_CHUNK_TERM) {
+			if (http_response_process_chunks(state) == false) {
+				status = HTTP_DATA_CORRUPTED;
+				goto out;
+			}
+			state->parser_state = HTTP_READING_DONE;
+		} else {
+			state->parser_state = HTTP_READING_CHUNK_SIZE;
+		}
+		status = HTTP_ALL_DATA_READ;
+		goto out;
+	}
+
+	status = HTTP_DATA_CORRUPTED;
+out:
+	TALLOC_FREE(line);
+	return status;
+}
+
+static enum http_read_status http_read_chunk_size(struct http_read_response_state *state)
+{
+	enum http_read_status	status = HTTP_ALL_DATA_READ;
+	char			*ptr = NULL;
+	char			*line = NULL;
+	char			*value = NULL;
+	int			n = 0;
+	unsigned long long v;
+
+	/* Sanity checks */
+	if (!state || !state->response) {
+		DBG_ERR("%s: Invalid Parameter\n", __func__);
+		return HTTP_DATA_CORRUPTED;
+	}
+
+	line = talloc_strndup(state, (char *)state->buffer.data, state->buffer.length);
+	if (!line) {
+		DBG_ERR("%s: Memory error\n", __func__);
+		return HTTP_DATA_CORRUPTED;
+	}
+	ptr = strstr(line, "\r\n");
+	if (ptr == NULL) {
+		TALLOC_FREE(line);
+		return HTTP_MORE_DATA_EXPECTED;
+	}
+
+	n = sscanf(line, "%m[^\r\n]\r\n", &value);
+	if (n != 1) {
+		DBG_ERR("%s: Error parsing chunk size '%s'\n", __func__, line);
+		status = HTTP_DATA_CORRUPTED;
+		goto out;
+	}
+
+	DBG_DEBUG("Got chunk size string %s\n", value);
+	n = sscanf(value, "%llx", &v);
+	if (n != 1) {
+		DBG_ERR("%s: Error parsing chunk size '%s'\n", __func__, line);
+		status = HTTP_DATA_CORRUPTED;
+		goto out;
+	}
+	DBG_DEBUG("Got chunk size %llu 0x%llx\n", v, v);
+	if (v == 0) {
+		state->parser_state = HTTP_READING_FINAL_CHUNK_TERM;
+	} else {
+		state->parser_state = HTTP_READING_CHUNK;
+	}
+	state->response->remaining_content_length = v;
+	status = HTTP_ALL_DATA_READ;
+out:
+	if (value) {
+		free(value);
+	}
+	TALLOC_FREE(line);
+	return status;
+}
+
 /**
  * Parses the first line of a HTTP response
  */
@@ -301,6 +471,55 @@ static enum http_read_status http_read_body(struct http_read_response_state *sta
 	return HTTP_ALL_DATA_READ;
 }
 
+static enum http_read_status http_read_chunk(struct http_read_response_state *state)
+{
+	struct http_request *resp = state->response;
+	struct http_chunk *chunk = NULL;
+	size_t total = 0;
+	size_t prev = 0;
+
+	if (state->buffer.length < resp->remaining_content_length) {
+		return HTTP_MORE_DATA_EXPECTED;
+	}
+
+	for (chunk = state->chunks; chunk; chunk = chunk->next) {
+		total += chunk->blob.length;
+	}
+
+	prev = total;
+	total = total + state->buffer.length;
+	if (total < prev) {
+		DBG_ERR("adding chunklen %zu to buf len %zu "
+			"will overflow\n",
+			state->buffer.length,
+			prev);
+		return HTTP_DATA_CORRUPTED;
+	}
+	if (total > state->max_content_length)  {
+		DBG_DEBUG("size %zu exceeds "
+			  "max content len %"PRIu64" skipping body\n",
+			  total,
+			  state->max_content_length);
+		state->parser_state = HTTP_READING_DONE;
+		goto out;
+	}
+
+	/* chunk read */
+	chunk = talloc_zero(state, struct http_chunk);
+	if (chunk == NULL) {
+		DBG_ERR("%s: Memory error\n", __func__);
+		return HTTP_DATA_CORRUPTED;
+	}
+	chunk->blob = state->buffer;
+	talloc_steal(chunk, chunk->blob.data);
+	DLIST_ADD_END(state->chunks, chunk);
+	state->parser_state = HTTP_READING_CHUNK_TERM;
+out:
+	state->buffer = data_blob_null;
+	resp->remaining_content_length = 0;
+	return HTTP_ALL_DATA_READ;
+}
+
 static enum http_read_status http_read_trailer(struct http_read_response_state *state)
 {
 	enum http_read_status status = HTTP_DATA_CORRUPTED;
@@ -323,6 +542,16 @@ static enum http_read_status http_parse_buffer(struct http_read_response_state *
 		case HTTP_READING_BODY:
 			return http_read_body(state);
 			break;
+		case HTTP_READING_FINAL_CHUNK_TERM:
+		case HTTP_READING_CHUNK_TERM:
+			return http_read_chunk_term(state);
+			break;
+		case HTTP_READING_CHUNK_SIZE:
+			return http_read_chunk_size(state);
+			break;
+		case HTTP_READING_CHUNK:
+			return http_read_chunk(state);
+			break;
 		case HTTP_READING_TRAILER:
 			return http_read_trailer(state);
 			break;
@@ -527,20 +756,60 @@ static int http_read_response_next_vector(struct tstream_context *stream,
 				*_count = 1;
 			}
 			break;
-		case HTTP_MORE_DATA_EXPECTED:
-			/* TODO Optimize, allocating byte by byte */
-			state->buffer.data = talloc_realloc(state, state->buffer.data,
-							    uint8_t, state->buffer.length + 1);
+		case HTTP_MORE_DATA_EXPECTED: {
+			size_t toread = 1;
+			size_t total;
+			if (state->parser_state == HTTP_READING_BODY ||
+			    state->parser_state == HTTP_READING_CHUNK) {
+				struct http_request *resp = state->response;
+				toread = resp->remaining_content_length -
+					 state->buffer.length;
+			}
+
+			total = toread + state->buffer.length;
+
+			if (total < state->buffer.length)  {
+				DBG_ERR("adding %zu to buf len %zu "
+					"will overflow\n",
+					toread,
+					state->buffer.length);
+					return -1;
+			}
+
+			/*
+			 * test if content-length message exceeds the
+			 * specified max_content_length
+			 * Note: This check won't be hit at the moment
+			 *       due to an existing check in parse_headers
+			 *       which will skip the body. Check is here
+			 *       for completeness and to cater for future
+			 *       code changes.
+			 */
+			if (state->parser_state == HTTP_READING_BODY) {
+				if (total > state->max_content_length)  {
+					DBG_ERR("content size %zu exceeds "
+						"max content len %"PRIu64"\n",
+						total,
+						state->max_content_length);
+					return -1;
+				}
+			}
+
+			state->buffer.data =
+				talloc_realloc(state, state->buffer.data,
+					       uint8_t,
+					       state->buffer.length + toread);
 			if (!state->buffer.data) {
 				return -1;
 			}
-			state->buffer.length++;
+			state->buffer.length += toread;
 			vector[0].iov_base = (void *)(state->buffer.data +
-						      state->buffer.length - 1);
-			vector[0].iov_len = 1;
+					     state->buffer.length - toread);
+			vector[0].iov_len = toread;
 			*_vector = vector;
 			*_count = 1;
 			break;
+		}
 		case HTTP_DATA_CORRUPTED:
 		case HTTP_REQUEST_CANCELED:
 		case HTTP_DATA_TOO_LONG:
@@ -603,7 +872,7 @@ static void http_read_response_done(struct tevent_req *subreq)
 {
 	NTSTATUS			status;
 	struct tevent_req		*req;
-	int				ret;
+	enum http_body_type		ret;
 	int				sys_errno;
 
 	if (!subreq) {


=====================================
libcli/http/http_internal.h
=====================================
@@ -28,6 +28,10 @@ enum http_parser_state {
 	HTTP_READING_BODY,
 	HTTP_READING_TRAILER,
 	HTTP_READING_DONE,
+	HTTP_READING_CHUNK_SIZE,
+	HTTP_READING_CHUNK,
+	HTTP_READING_CHUNK_TERM,
+	HTTP_READING_FINAL_CHUNK_TERM,
 };
 
 enum http_read_status {


=====================================
nsswitch/tests/test_idmap_ad.sh
=====================================
@@ -94,6 +94,14 @@ gidNumber: 2000001
 unixHomeDirectory: /home/forbidden
 loginShell: /bin/tcsh
 gecos: User in forbidden OU
+
+dn: CN=no_posix_id,CN=Users,$BASE_DN
+changetype: add
+objectClass: user
+samaccountName: no_posix_id
+unixHomeDirectory: /home/no_posix_id
+loginShell: /bin/sh
+gecos: User without uidNumber and gidNumber
 EOF
 
 #
@@ -171,6 +179,17 @@ then
 	failed=$(($failed + 1))
 fi
 
+#
+# Test 6: Make sure that with the default "all_groups=no"
+# the group "domain users" will not show user "no_posix_id"
+# but will show "SAMBA2008R2/administrator"
+#
+
+dom_users="$DOMAIN/domain users"  # Extra step to make sure that all is one word
+out="$($wbinfo --group-info "$dom_users")"
+testit_grep_count "no_posix_id1" "no_posix_id" 0 echo "$out" || failed=$(expr $failed + 1)
+testit_grep "no_posix_id2" "SAMBA2008R2/administrator" echo "$out" || failed=$(expr $failed + 1)
+
 #
 # Trusted domain test 1: Test uid of Administrator, should be 2500000
 #
@@ -241,6 +260,9 @@ gidNumber: 2000002
 dn: cn=forbidden,ou=sub,$BASE_DN
 changetype: delete
 
+dn: CN=no_posix_id,CN=Users,$BASE_DN
+changetype: delete
+
 dn: ou=sub,$BASE_DN
 changetype: delete
 EOF


=====================================
packaging/systemd/samba-bgqd.service.in
=====================================
@@ -0,0 +1,16 @@
+[Unit]
+Description=Samba Background Queue Daemon for printing-related jobs
+Documentation=man:samba-bgqd(8) man:smb.conf(5)
+Wants=network-online.target
+After=network.target network-online.target
+
+[Service]
+Type=notify
+LimitNOFILE=16384
+PIDFile=@PIDDIR@/samba-bgqd.pid
+EnvironmentFile=- at SYSCONFDIR@/sysconfig/samba
+ExecStart=@LIBEXECDIR@/samba/samba-bgqd --foreground --no-process-group $SAMBAOPTIONS
+ExecReload=/bin/kill -HUP $MAINPID
+
+[Install]
+WantedBy=multi-user.target


=====================================
packaging/wscript_build
=====================================
@@ -4,7 +4,8 @@ systemd_services = [
     'systemd/smb.service',
     'systemd/nmb.service',
     'systemd/winbind.service',
-    'systemd/samba.service'
+    'systemd/samba.service',
+    'systemd/samba-bgqd.service',
 ]
 
 for srv in systemd_services:


=====================================
python/samba/tests/blackbox/http_chunk.py
=====================================
@@ -0,0 +1,129 @@
+# Blackbox tests for http_test
+#
+# Copyright (C) Noel Power noel.power at suse.com
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import time
+import threading
+import logging
+import json
+from http.server import HTTPServer, BaseHTTPRequestHandler
+from samba.logger import get_samba_logger
+from samba.tests import BlackboxTestCase, BlackboxProcessError
+
+logger = get_samba_logger(name=__name__)
+COMMAND = "bin/http_test"
+def make_chunks(msg, chunk_size):
+    chunks = []
+    while len(msg) > chunk_size:
+        chunk = msg[:chunk_size]
+        chunks.append(chunk)
+        msg = msg[chunk_size:]
+    if len(msg):
+        chunks.append(msg)
+    return chunks
+
+# simple handler, spits back the 'path' passed in
+# GET or POST and a chunked encoded http response
+# where the chunk size is 10 octets
+class ChunkHTTPRequestHandler(BaseHTTPRequestHandler):
+    def handle_req(self):
+        msg = bytes(self.path, encoding="utf-8")
+        chunks = make_chunks(msg, 10)
+
+        self.send_response(200)
+        self.send_header('content-type', 'application/json; charset=UTF-8')
+        if self.path == "usegziptransferencoding":
+            self.send_header('Transfer-Encoding', 'gzip')
+        else:
+            self.send_header('Transfer-Encoding', 'chunked')
+        self.end_headers()
+        resp = bytes()
+        for chunk in chunks:
+            resp = resp + ("%x" % len(chunk)).encode("utf-8") + b'\r\n' + chunk + b'\r\n'
+        resp += b'0\r\n\r\n'
+        self.wfile.write(resp)
+
+    def do_POST(self):
+        self.handle_req()
+    def do_GET(self):
+        self.handle_req()
+
+class HttpChunkBlackboxTests(BlackboxTestCase):
+    def setUp(self):
+        self.server = HTTPServer((os.getenv("SERVER_IP", "localhost"), 8080),
+                                 ChunkHTTPRequestHandler,
+                                 bind_and_activate=False)
+        self.t = threading.Thread(target=HttpChunkBlackboxTests.http_server, args=(self,))
+        self.t.setDaemon(True)
+        self.t.start()
+        time.sleep(1)
+
+    def tearDown(self):
+        super().tearDown()
+
+    def http_server(self):
+        self.server.server_bind()
+        self.server.server_activate()
+        self.server.serve_forever()
+
+    def test_single_chunk(self):
+        try:
+            msg = "one_chunk"
+            resp = self.check_output("%s -U%% -I%s --uri %s" % (COMMAND, os.getenv("SERVER_IP", "localhost"), msg))
+            self.assertEqual(msg,resp.decode('utf-8'))
+        except BlackboxProcessError as e:
+            print("Failed with: %s" % e)
+            self.fail(str(e))
+
+    def test_multi_chunks(self):
+        try:
+            msg = "snglechunksnglechunksnglechunksnglechunksnglechunk"
+            resp = self.check_output("%s -U%% -I%s --uri %s" % (COMMAND, os.getenv("SERVER_IP", "localhost"), msg))
+            self.assertEqual(msg, resp.decode('utf-8'))
+        except BlackboxProcessError as e:
+            print("Failed with: %s" % e)
+            self.fail(str(e))
+
+    def test_exceed_request_size(self):
+        try:
+            msg = "snglechunksnglechunksnglechunksnglechunksnglechunk"
+            resp = self.check_output("%s -d11 -U%% -I%s --rsize 49 --uri %s" % (COMMAND, os.getenv("SERVER_IP", "localhost"), msg))
+            self.fail("unexpected success")
+        except BlackboxProcessError as e:
+            if "http_read_chunk: size 50 exceeds max content len 49 skipping body" not in e.stderr.decode('utf-8'):
+                self.fail(str(e))
+            if "unexpected 0 len response" not in e.stdout.decode('utf-8'):
+                self.fail(str(e))
+
+    def test_exact_request_size(self):
+        try:
+            msg = "snglechunksnglechunksnglechunksnglechunksnglechunk"
+            resp = self.check_output("%s -U%% -I%s --rsize 50 --uri %s" % (COMMAND, os.getenv("SERVER_IP", "localhost"), msg))
+            self.assertEqual(msg, resp.decode('utf-8'))
+        except BlackboxProcessError as e:
+            print("Failed with: %s" % e)
+            self.fail(str(e))
+
+    def test_gzip_transfer_encoding(self):
+        try:
+            msg = "usegziptransferencoding"
+            resp = self.check_output("%s -U%% -I%s --rsize 50 --uri %s" % (COMMAND, os.getenv("SERVER_IP", "localhost"), msg))
+            self.assertEqual(msg, resp.decode('utf-8'))
+            self.fail("unexpected success")
+        except BlackboxProcessError as e:
+            if "http_response_needs_body: Unsupported transfer encoding type gzip" not in e.stderr.decode('utf-8'):
+                self.fail(str(e))


=====================================
python/samba/tests/blackbox/http_content.py
=====================================
@@ -0,0 +1,95 @@
+# Blackbox tests for http_test
+#
+# Copyright (C) Noel Power noel.power at suse.com
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import time
+import threading
+import logging
+import json
+from http.server import HTTPServer, BaseHTTPRequestHandler
+from samba.logger import get_samba_logger
+from samba.tests import BlackboxTestCase, BlackboxProcessError
+
+logger = get_samba_logger(name=__name__)
+COMMAND = "bin/http_test"
+
+# simple handler, spits back the 'path' passed in
+# GET or POST and a chunked encoded http response
+# where the chunk size is 10 octets
+class ContentHTTPRequestHandler(BaseHTTPRequestHandler):
+    def handle_req(self):
+        msg = bytes(self.path, encoding="utf-8")
+
+        self.send_response(200)
+        self.send_header('content-type', 'application/json; charset=UTF-8')
+        self.send_header('content-length', len(msg))
+        self.end_headers()
+        self.wfile.write(msg)
+
+    def do_POST(self):
+        self.handle_req()
+    def do_GET(self):
+        self.handle_req()
+
+class HttpContentBlackboxTests(BlackboxTestCase):
+    def setUp(self):
+        self.server = HTTPServer((os.getenv("SERVER_IP", "localhost"), 8080),
+                                 ContentHTTPRequestHandler,
+                                 bind_and_activate=False)
+        self.t = threading.Thread(target=HttpContentBlackboxTests.http_server, args=(self,))
+        self.t.setDaemon(True)
+        self.t.start()
+        time.sleep(1)
+
+    def tearDown(self):
+        super().tearDown()
+
+    def http_server(self):
+        self.server.server_bind()
+        self.server.server_activate()
+        self.server.serve_forever()
+
+    def notest_simple_msg(self):
+        try:
+            msg = "simplemessage"
+            resp = self.check_output("%s -U%% -I%s --uri %s" % (COMMAND, os.getenv("SERVER_IP", "localhost"), msg))
+            self.assertEqual(msg, resp.decode('utf-8'))
+        except BlackboxProcessError as e:
+            print("Failed with: %s" % e)
+            self.fail(str(e))
+
+    def test_exceed_request_size(self):
+        try:
+            msg = "012345678" # 9 bytes
+            # limit response to 8 bytes
+            resp = self.check_output("%s -d11 -U%% -I%s --rsize 8 --uri %s" % (COMMAND, os.getenv("SERVER_IP", "localhost"), msg))
+            self.fail("unexpected success")
+        except BlackboxProcessError as e:
+            if "unexpected 0 len response" not in e.stdout.decode('utf-8'):
+                self.fail(str(e))
+            if "http_parse_headers: Skipping body for code 200" not in e.stderr.decode('utf-8'):
+                self.fail(str(e))
+
+    def test_exact_request_size(self):
+        try:
+            msg = "012345678" # 9 bytes
+            # limit response to 9 bytes
+            resp = self.check_output("%s -U%% -I%s --rsize 9 --uri %s" % (COMMAND, os.getenv("SERVER_IP", "localhost"), msg))
+            self.assertEqual(msg, resp.decode('utf-8'))
+        except BlackboxProcessError as e:
+            print("Failed with: %s" % e)
+            self.fail(str(e))


=====================================
python/samba/tests/blackbox/smbcacls_propagate_inhertance.py
=====================================
@@ -1288,3 +1288,111 @@ class InheritanceSmbCaclsTests(SmbCaclsBlockboxTestBase):
 
         except BlackboxProcessError as e:
             self.fail(str(e))
+
+    def test_simple_iocioi_add(self):
+        """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
+        for the file and additionally use inheritance rules to propagate appropriate
+        changes to children
+
+        This test adds an ACL with (IO)(CI)(OI)(READ)
+
+        before:
+
+        +-tar_test_dir/    (OI)(CI)(I)(F)
+          +-oi_dir/        (OI)(CI)(I)(F)
+          | +-file.1            (I)(F)
+          | +-nested/      (OI)(CI)(I)(F)
+          |   +-file.2          (I)(F)
+          |   +-nested_again/     (OI)(CI)(I)(F)
+          |     +-file.3          (I)(F)
+
+        after/expected:
+
+        +-tar_test_dir/    (OI)(CI)(I)(F)
+          +-oi_dir/        (OI)(CI)(I)(F), (IO)(CI)(OI)(READ)
+          | +-file.1            (I)(F), (I)(READ)
+          | +-nested/      (OI)(CI)(I)(F), (I)(CI)(OI)(READ)
+          |   +-file.2          (I)(F), (I)(READ)
+          |   +-nested_again/     (OI)(CI)(I)(F), (I)(CI)(OI)(READ)
+          |     +-file.3          (I)(F), (I)(READ)"""
+
+        dir_add_acl_str = "ACL:%s:ALLOWED/OI|CI|IO/READ" % self.user
+        obj_inherited_ace_str = "ACL:%s:ALLOWED/I/READ" % self.user
+        dir_inherited_ace_str = "ACL:%s:ALLOWED/OI|CI|I/READ" % self.user
+
+        try:
+
+            self.smb_cacls(["--propagate-inheritance", "--add",
+                            dir_add_acl_str, self.oi_dir])
+
+            # check top level container 'oi_dir' has IO|CI|OI/READ
+            dir_ace = self.ace_parse_str(dir_add_acl_str)
+            self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
+
+            # file 'oi_dir/file-1' should  have inherited I/READ
+            child_file_ace = self.ace_parse_str(obj_inherited_ace_str)
+            self.assertTrue(self.file_ace_check(self.f1, child_file_ace))
+
+            # nested dir  'oi_dir/nested/' should have I|CI|OI/READ
+            child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
+            self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
+
+            # nested file 'oi_dir/nested/file-2' should  have inherited I/READ
+            self.assertTrue(self.file_ace_check(self.f2, child_file_ace))
+
+            # nested_again dir  'oi_dir/nested/nested_again' should have I|CI|OI/READ
+            child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
+            self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace))
+            # nested_again file 'oi_dir/nested/nested_again/file-3' should  have inherited I/READ
+            self.assertTrue(self.file_ace_check(self.f3, child_file_ace))
+        except BlackboxProcessError as e:
+            self.fail(str(e))
+
+    def test_simple_ioci_add(self):
+        """test smbcacls '--propagate-inheritance --add' which attempts to add the ACL
+        for the file and additionally use inheritance rules to propagate appropriate
+        changes to children
+
+        This test adds an ACL with (IO)(CI)(READ)
+
+        before:
+
+        +-tar_test_dir/    (OI)(CI)(I)(F)
+          +-oi_dir/        (OI)(CI)(I)(F)
+          | +-file.1            (I)(F)
+          | +-nested/      (OI)(CI)(I)(F)
+          |   +-file.2          (I)(F)
+          |   +-nested_again/     (OI)(CI)(I)(F)
+          |     +-file.3          (I)(F)
+
+        after/expected:
+
+        +-tar_test_dir/    (OI)(CI)(I)(F)
+          +-oi_dir/        (OI)(CI)(I)(F), (IO)(CI)(READ)
+          | +-file.1            (I)(F)
+          | +-nested/      (OI)(CI)(I)(F), (I)(CI)(READ)
+          |   +-file.2          (I)(F)
+          |   +-nested_again/     (OI)(CI)(I)(F), (I)(CI)(READ)
+          |     +-file.3          (I)(F)"""
+
+        dir_add_acl_str = "ACL:%s:ALLOWED/CI|IO/READ" % self.user
+        dir_inherited_ace_str = "ACL:%s:ALLOWED/CI|I/READ" % self.user
+
+        try:
+
+            self.smb_cacls(["--propagate-inheritance", "--add",
+                            dir_add_acl_str, self.oi_dir])
+
+            # check top level container 'oi_dir' has IO|CI/READ
+            dir_ace = self.ace_parse_str(dir_add_acl_str)
+            self.assertTrue(self.file_ace_check(self.oi_dir, dir_ace))
+
+            # nested dir  'oi_dir/nested/' should have I|CI/READ
+            child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
+            self.assertTrue(self.file_ace_check(self.nested_dir, child_dir_ace))
+
+            # nested_again dir  'oi_dir/nested/nested_again' should have I|CI/READ
+            child_dir_ace = self.ace_parse_str(dir_inherited_ace_str)
+            self.assertTrue(self.file_ace_check(self.nested_again_dir, child_dir_ace))
+        except BlackboxProcessError as e:
+            self.fail(str(e))


=====================================
selftest/target/Samba3.pm
=====================================
@@ -1420,6 +1420,7 @@ sub setup_ad_member_idmap_ad
 	idmap config $dcvars->{TRUST_DOMAIN} : range = 2000000-2999999
 	gensec_gssapi:requested_life_time = 5
 	winbind scan trusted domains = yes
+	winbind expand groups = 1
 ";
 
 	my $ret = $self->provision(


=====================================
selftest/tests.py
=====================================
@@ -221,6 +221,8 @@ plantestsuite(
     "samba4.blackbox.test_special_group", "none",
     cmdline('test_special_group.sh', '$PREFIX_ABS/provision'))
 
+planpythontestsuite("fileserver", "samba.tests.blackbox.http_content")
+planpythontestsuite("fileserver", "samba.tests.blackbox.http_chunk")
 planpythontestsuite("none", "samba.tests.upgradeprovision")
 planpythontestsuite("none", "samba.tests.xattr")
 planpythontestsuite("none", "samba.tests.ntacls")


=====================================
source3/utils/smbcacls.c
=====================================
@@ -914,6 +914,10 @@ static uint8_t get_flags_to_propagate(bool is_container,
 	/* Assume we are not propagating the ACE */
 
 	newflags &= ~SEC_ACE_FLAG_INHERITED_ACE;
+
+	/* Inherit-only flag is not propagated to children */
+
+	newflags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
 	/* all children need to have the SEC_ACE_FLAG_INHERITED_ACE set */
 	if (acl_cntrinherit || acl_objinherit) {
 		/*


=====================================
source3/winbindd/winbindd_ads.c
=====================================
@@ -1039,7 +1039,7 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
 }
 
 static NTSTATUS add_primary_group_members(
-	ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, uint32_t rid,
+	ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, uint32_t rid, const char *domname,
 	char ***all_members, size_t *num_all_members)
 {
 	char *filter;
@@ -1051,10 +1051,13 @@ static NTSTATUS add_primary_group_members(
 	char **members;
 	size_t num_members;
 	ads_control args;
+	bool all_groupmem = idmap_config_bool(domname, "all_groupmem", false);
 
 	filter = talloc_asprintf(
-		mem_ctx, "(&(objectCategory=user)(primaryGroupID=%u))",
-		(unsigned)rid);
+		mem_ctx,
+		"(&(objectCategory=user)(primaryGroupID=%u)%s)",
+		(unsigned)rid,
+		all_groupmem ? "" : "(uidNumber=*)(!(uidNumber=0))");
 	if (filter == NULL) {
 		goto done;
 	}
@@ -1206,7 +1209,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 
 	DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", (int)num_members));
 
-	status = add_primary_group_members(ads, mem_ctx, rid,
+	status = add_primary_group_members(ads, mem_ctx, rid, domain->name,
 					   &members, &num_members);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(10, ("%s: add_primary_group_members failed: %s\n",


=====================================
source4/client/http_test.c
=====================================
@@ -0,0 +1,401 @@
+#include "includes.h"
+#include "version.h"
+#include "libcli/libcli.h"
+#include "lib/events/events.h"
+#include "libcli/resolve/resolve.h"
+#include "param/param.h"
+#include "libcli/raw/raw_proto.h"
+#include "libcli/http/http.h"
+#include "credentials.h"
+#include "util/tevent_ntstatus.h"
+#include "lib/tls/tls.h"
+#include "lib/cmdline/cmdline.h"
+
+
+struct http_client_info {
+	struct http_conn *http_conn;
+	uint16_t server_port;
+	const char *server_addr;
+	struct tstream_tls_params *tls_params;
+	struct cli_credentials *creds;
+	struct loadparm_context *lp_ctx;
+	const char *uri;
+};
+
+static bool send_http_request(TALLOC_CTX *mem_ctx,
+	struct tevent_context *ev_ctx,
+	struct http_client_info* es,
+	size_t response_size,
+	NTSTATUS *pstatus)
+{
+	struct http_request *http_req = NULL;
+	struct tevent_req *req = NULL;
+	char *uri = NULL;
+	struct http_request *http_response = NULL;
+	NTSTATUS status;
+
+	http_req = talloc_zero(mem_ctx, struct http_request);
+	if (!http_req) {
+		DBG_ERR("no memory\n");
+		return false;
+	}
+
+	uri = talloc_strdup(mem_ctx, es->uri);
+
+	http_req->type = HTTP_REQ_POST;
+	http_req->uri = uri;
+	http_req->body = data_blob_null;
+	http_req->major = '1';
+	http_req->minor = '1';
+
+	http_add_header(mem_ctx, &http_req->headers,
+			"User-Agent", "Samba/http_test");
+	http_add_header(mem_ctx, &http_req->headers,
+			"Accept", "*/*");
+
+	req = http_send_auth_request_send(mem_ctx,
+				ev_ctx,
+				es->http_conn,
+				http_req,
+				es->creds,
+				es->lp_ctx,
+				HTTP_AUTH_BASIC);
+	if (!tevent_req_set_endtime(req, ev_ctx, timeval_current_ofs(10, 0))) {
+		DBG_ERR("Failed to set timeout\n");
+		return false;
+	}
+
+	if (!tevent_req_poll_ntstatus(req, ev_ctx, pstatus)) {
+		DBG_ERR("Failed to connect: %s\n", nt_errstr(*pstatus));
+		return false;
+	}
+
+	status = http_send_auth_request_recv(req);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_ERR("Auth request failed: %s\n", nt_errstr(status));
+		return false;
+	}
+
+	req = http_read_response_send(mem_ctx,
+				ev_ctx,
+				es->http_conn,
+				response_size);
+	if (!req) {
+		DBG_ERR("no memory\n");
+		return -1;
+	}
+
+	if (!tevent_req_set_endtime(req, ev_ctx, timeval_current_ofs(10, 0))) {
+		DBG_ERR("Failed to set timeout\n");
+		return false;
+	}
+
+	if (!tevent_req_poll_ntstatus(req, ev_ctx, pstatus)) {
+		DBG_ERR("Failed to read_resonse: %s\n", nt_errstr(*pstatus));
+		return false;
+	}
+
+	*pstatus = http_read_response_recv(req, mem_ctx, &http_response);
+
+	if (!NT_STATUS_IS_OK(*pstatus)) {
+		DBG_ERR("Failed to receive response: %s\n", nt_errstr(*pstatus));
+		return false;
+	}
+	/* following are not 'hard' errors */
+	if (http_response->response_code != 200) {
+		fprintf(stdout, "HTTP server response: %u\n",
+			http_response->response_code);
+		fflush(stdout);
+		return false;
+
+	}
+	if (http_response->body.length == 0) {
+		fprintf(stdout, "unexpected 0 len response\n");
+		fflush(stdout);
+		return false;
+	}
+	DBG_ERR("response: len (%d)\n%s\n",
+		  (int)http_response->body.length,
+		  talloc_strndup(mem_ctx,
+				 (char *)http_response->body.data,
+				 http_response->body.length));
+	fprintf(stdout,"%s", talloc_strndup(mem_ctx,
+					    (char *)http_response->body.data,
+					    http_response->body.length));
+	fflush(stdout);
+	return true;
+}
+
+int main(int argc, const char *argv[])
+
+{
+	TALLOC_CTX *mem_ctx;
+	struct tevent_context *ev_ctx;
+	int retries = 4;
+	int count = 0;
+	struct http_client_info *http_info = NULL;
+	bool use_tls = false;
+	int res;
+	NTSTATUS status;
+	struct tevent_req *req = NULL;
+	bool connected = false;
+	poptContext pc;
+	const char **const_argv = discard_const_p(const char *, argv);
+	int opt;
+	bool ok;
+	const char *ca_file = NULL;
+	int port = 0;
+	size_t response_size = 8192000;
+	struct cli_credentials *cli_creds;
+
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+
+		{
+			.longName   = "usetls",
+			.shortName  = 't',
+			.argInfo    = POPT_ARG_NONE,
+			.arg        = NULL,
+			.val        = 't',
+			.descrip    = "Use tls",
+			.argDescrip = "enable tls",
+		},
+		{
+			.longName   = "ip-address",
+			.shortName  = 'I',
+			.argInfo    = POPT_ARG_STRING,
+			.arg        = NULL,
+			.val        = 'I',
+			.descrip    = "Use this IP to connect to",
+			.argDescrip = "IP",
+		},
+		{
+			.longName   = "port",
+			.shortName  = 'p',
+			.argInfo    = POPT_ARG_INT,
+			.arg        = &port,
+			.val        = 'p',
+			.descrip    = "port to connect to",
+			.argDescrip = "port",
+		},
+		{
+			.longName   = "cacart",
+			.shortName  = 'c',
+			.argInfo    = POPT_ARG_STRING,
+			.arg        = NULL,
+			.val        = 'c',
+			.descrip    = "CA certificate to verify peer against",
+			.argDescrip = "ca cert",
+		},
+		{
+			.longName   = "uri",
+			.shortName  = 'u',
+			.argInfo    = POPT_ARG_STRING,
+			.arg        = NULL,
+			.val        = 'u',
+			.descrip    = "uri to send as part of http request",
+			.argDescrip = "uri",
+		},
+		{
+			.longName   = "rsize",
+			.argInfo    = POPT_ARG_LONG,
+			.arg        = &response_size,
+			.descrip    = "response size",
+		},
+		POPT_COMMON_SAMBA
+		POPT_COMMON_CREDENTIALS
+		POPT_TABLEEND
+	};
+
+	mem_ctx = talloc_init("http_test");
+
+	if (!mem_ctx) {
+		DBG_ERR("Not enough memory\n");
+		res = -1;
+		goto done;
+	}
+
+	http_info = talloc_zero(mem_ctx, struct http_client_info);
+
+	if (http_info == NULL) {
+		DBG_ERR("Not enough memory\n");
+		res = -1;
+		goto done;
+	}
+
+	ok = samba_cmdline_init(mem_ctx,
+				SAMBA_CMDLINE_CONFIG_CLIENT,
+				false /* require_smbconf */);
+	if (!ok) {
+		DBG_ERR("Failed to init cmdline parser!\n");
+		res = -1;
+		goto done;
+	}
+
+	pc = samba_popt_get_context(getprogname(),
+				    argc,
+				    const_argv,
+				    long_options,
+				    0);
+	if (pc == NULL) {
+		DBG_ERR("Failed to setup popt context!\n");
+		res = -1;
+		goto done;
+	}
+
+	/* some defaults */
+
+	http_info->server_addr = "localhost";
+	http_info->uri = "/_search?pretty";
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch (opt) {
+			case 't':
+				use_tls = true;
+				break;
+			case  'c': {
+				ca_file = talloc_strdup(mem_ctx,
+							poptGetOptArg(pc));
+				if (ca_file == NULL) {
+					DBG_ERR("Not enough memory\n");
+					res = -1;
+					goto done;
+				}
+				break;
+			}
+			case 'I': {
+				http_info->server_addr = talloc_strdup(mem_ctx,
+							poptGetOptArg(pc));
+				if (http_info->server_addr == NULL) {
+					DBG_ERR("Not enough memory\n");
+					res = -1;
+					goto done;
+				}
+				break;
+			}
+			case 'u': {
+				http_info->uri = talloc_strdup(mem_ctx,
+							poptGetOptArg(pc));
+				if (http_info->uri == NULL) {
+					DBG_ERR("Not enough memory\n");
+					res = -1;
+					goto done;
+				}
+				break;
+			}
+		}
+	}
+
+	if (use_tls && ca_file == NULL) {
+		DBG_ERR("No cacert\n");
+		res = -1;
+		poptPrintUsage(pc, stderr, 0);
+		goto done;
+	}
+
+	if (!port) {
+		port = 8080;
+	}
+	http_info->server_port = port;
+
+	ev_ctx = s4_event_context_init(mem_ctx);
+	if (!ev_ctx) {
+		DBG_ERR("Not enough memory\n");
+		res = -1;
+		goto done;
+	}
+
+
+	cli_creds = samba_cmdline_get_creds();
+	if (!cli_credentials_is_anonymous(cli_creds)) {
+		http_info->creds = cli_credentials_init(mem_ctx);
+		cli_credentials_set_username(
+			http_info->creds,
+			cli_credentials_get_username(cli_creds),
+			CRED_SPECIFIED);
+		cli_credentials_set_password(http_info->creds,
+			cli_credentials_get_password(cli_creds),
+			CRED_SPECIFIED);
+	} else {
+		DBG_DEBUG("Anonymous creds!!!\n");
+		http_info->creds = cli_creds;
+	}
+	if (http_info->creds == NULL) {
+		DBG_ERR("Failed to create creds\n");
+		res = -1;
+		goto done;
+	}
+	http_info->lp_ctx = samba_cmdline_get_lp_ctx();
+
+	DBG_ERR("retries = %d/%d, Using server %s, port %d, using tls %s\n",
+		count, retries,
+		http_info->server_addr,
+		http_info->server_port,
+		use_tls ? "true" : "false");
+
+	while (count < retries) {
+		int error;
+		DBG_ERR("Connecting to HTTP [%s] port [%"PRIu16"]%s\n",
+			http_info->server_addr, http_info->server_port,
+			use_tls ? " with tls" : " without tls");
+		if (use_tls) {
+			const char *crl_file = NULL;
+			const char *tls_priority = "NORMAL:-VERS-SSL3.0";
+			enum tls_verify_peer_state verify_peer =
+				TLS_VERIFY_PEER_CA_ONLY;
+
+			status = tstream_tls_params_client(mem_ctx,
+						   ca_file,
+						   crl_file,
+						   tls_priority,
+						   verify_peer,
+						   http_info->server_addr,
+						   &http_info->tls_params);
+			if (!NT_STATUS_IS_OK(status)) {
+				DBG_ERR("Failed tstream_tls_params_client - %s\n",
+					nt_errstr(status));
+				res = -1;
+				goto done;
+			}
+		}
+
+		req = http_connect_send(mem_ctx,
+					ev_ctx,
+					http_info->server_addr,
+					http_info->server_port,
+					http_info->creds,
+					http_info->tls_params);
+		if (!tevent_req_poll_ntstatus(req, ev_ctx, &status)) {
+			res = -1;
+			goto done;
+		}
+
+		error = http_connect_recv(req,
+					mem_ctx,
+					&http_info->http_conn);
+		if (error != 0) {
+			count++;
+			DBG_ERR("HTTP connection failed retry %d/%d: %s\n", count, retries, strerror(error));
+		} else {
+			DBG_ERR("HTTP connection succeeded\n");
+			connected = true;
+			break;
+		}
+	}
+
+	if (!connected) {
+		DBG_ERR("Leaving early\n");
+		res = -1;
+		goto done;
+	}
+
+	if (!send_http_request(mem_ctx, ev_ctx, http_info, response_size, &status)) {
+		DBG_ERR("Failure\n");
+		res = -1;
+		goto done;
+	}
+	res = 0;
+done:
+	TALLOC_FREE(mem_ctx);
+	return res;
+}


=====================================
source4/dns_server/dnsserver_common.c
=====================================
@@ -1034,10 +1034,11 @@ WERROR dns_common_replace(struct ldb_context *samdb,
 			 * record.
 			 */
 			if (records[i].data.EntombedTime != 0) {
-				if (rec_count != 1) {
-					DBG_ERR("tombstone record has %u neighbour "
-						"records.\n",
-						rec_count - 1);
+				if (rec_count != 1 && DEBUGLVL(DBGLVL_NOTICE)) {
+					DBG_NOTICE("tombstone record [%u] has "
+						   "%u neighbour records.\n",
+						   i, rec_count - 1);
+					NDR_PRINT_DEBUG(dnsp_DnssrvRpcRecord, &records[i]);
 				}
 				was_tombstoned = true;
 			}


=====================================
source4/wscript_build
=====================================
@@ -6,6 +6,11 @@ bld.SAMBA_BINARY('client/smbclient'  + bld.env.suffix4,
 	install=False
 	)
 
+bld.SAMBA_BINARY('client/http_test',
+    source='client/http_test.c',
+    deps='samba-hostconfig SMBREADLINE samba-util LIBCLI_SMB RPC_NDR_SRVSVC LIBCLI_LSA popt CMDLINE_S4',
+    for_selftest=True,
+    )
 
 bld.SAMBA_BINARY('client/cifsdd',
 	source='client/cifsdd.c client/cifsddio.c',



View it on GitLab: https://salsa.debian.org/samba-team/samba/-/compare/257fe66d8ecd47f42d08abedc42f6419584e4a6f...2667fd06a42bf95e7bf5cae2c8499de940b29211

-- 
View it on GitLab: https://salsa.debian.org/samba-team/samba/-/compare/257fe66d8ecd47f42d08abedc42f6419584e4a6f...2667fd06a42bf95e7bf5cae2c8499de940b29211
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-samba-maint/attachments/20240508/68c8bcd3/attachment-0001.htm>


More information about the Pkg-samba-maint mailing list