[SCM] Samba Shared Repository - branch master updated

Douglas Bagnall dbagnall at samba.org
Wed Jun 2 04:47:01 UTC 2021


The branch, master has been updated
       via  58b5513d523 selftest: standardise and shorten winbind socket name
       via  3bc680c1e38 pidl: Avoid leaving array_size NDR tokens around
       via  a7d4f93cfde pidl: Avoid leaving array_length NDR tokens around
       via  139cca7c206 librpc: Use helper function ndr_get_array_size() in ndr_check_array_size()
       via  40aabcb5cf7 librpc: Add const to cookie pointer in ndr_check_array_{size,length}
       via  c35f4180a44 libndr: Return error code from ndr_token_peek()
       via  0cc4478070b selftest: Add test of NDR marshalling from python, starting with wbint
       via  e583140e81b spoolss: Avoid indirection via ndr_get_array_size()
       via  2f7aa81a9f3 samba-tool dns zoneoptions: timestamp manipulation options
       via  074f9e14866 pytest:samba-tool dns: more robust clean-up
       via  b11ea9d7ada samba-tool dns: remove unused imports
       via  eeaa1380325 samba-tool dns: move dns_record_match to dnsserver.py
      from  537f2d19b55 pidl: Handle assigning to an inline array from Python

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


- Log -----------------------------------------------------------------
commit 58b5513d5237c29489f0e8abb4cc02ccee7bd67a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed May 19 13:57:21 2021 +1200

    selftest: standardise and shorten winbind socket name
    
    The full path to the winbindd socket must fit within a struct sockaddr_un and this helps us work
    where this is quite deep on the server.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    
    Autobuild-User(master): Douglas Bagnall <dbagnall at samba.org>
    Autobuild-Date(master): Wed Jun  2 04:46:39 UTC 2021 on sn-devel-184

commit 3bc680c1e38bef75d5b212992e15f094c523923b
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat May 22 18:40:13 2021 +1200

    pidl: Avoid leaving array_size NDR tokens around
    
    In many cases these can and should be consumed as soon as
    they are used.
    
    This is not a complete fix, we don't clean up the array_size
    token after using it split between an NDR_SCALARS and
    an NDR_BUFFERS pass, but it is much better than it was
    and helps the winbind case with a large number of groups
    (eg 100,000) as otherwise we hit the 65535 NDR token limit.
    
    (This is an arbitary Samba-only limit to avoid DoS conditions)
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14710
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit a7d4f93cfdee0a2005be11880f8dd31f55149369
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat May 22 10:17:49 2021 +1200

    pidl: Avoid leaving array_length NDR tokens around
    
    In many cases these can and should be consumed as soon as
    they are used.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14710
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 139cca7c206efc6c6e9a93fd4045285f25117414
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat May 22 19:37:45 2021 +1200

    librpc: Use helper function ndr_get_array_size() in ndr_check_array_size()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14710
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 40aabcb5cf76ff076e04bff00f4ff0b4374f2354
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat May 22 09:10:56 2021 +1200

    librpc: Add const to cookie pointer in ndr_check_array_{size,length}
    
    This pointer is only used to find the right token in the list
    so can be declared const.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14710
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit c35f4180a44eb3caecad0f2daab46574bc52be83
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri May 28 12:18:48 2021 +1200

    libndr: Return error code from ndr_token_peek()
    
    This makes it safer to change our code to remove tokens after use
    if failing to obtain a token would result in an error.
    
    This means changing ndr_get_array_size() and ndr_get_array_length()
    to also return an error code.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14710
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 0cc4478070b9c980d653adf31647dd541cf4be22
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue May 25 21:12:44 2021 +1200

    selftest: Add test of NDR marshalling from python, starting with wbint
    
    These patches are to address an issue unpacking a very large
    winbind.wbint_Principals array (100,000).
    
    We need the NDR_TOKEN_MAX_LIST_SIZE value exposed as
    otherwise a well-meaning incrase of this value would
    invalidate the test.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14710
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit e583140e81bce9853ccb86370a2143c8b27b4984
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat May 22 08:46:26 2021 +1200

    spoolss: Avoid indirection via ndr_get_array_size()
    
    This is set in the call just above and otherwise we will (in the next commit)
    need an intermediate variable once we need to check error codes from
    ndr_get_array_size().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14710
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 2f7aa81a9f36685f0a349ae125fa4fce54c4c442
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu May 27 09:46:02 2021 +1200

    samba-tool dns zoneoptions: timestamp manipulation options
    
    There was a bug in Samba before 4.9 that marked all records intended
    to be static with a current timestamp, and all records intended to be
    dynamic with a zero timestamp. This was exactly the opposite of
    correct behaviour.
    
    It follows that a domain which has been upgraded past 4.9, but on
    which aging is not enabled, records intended to be static will have a
    timestamp from before the upgrade date (unless their nodes have
    suffered a DNS update, which due to another bug, will change the
    timestmap). The following command will make these truly static:
    
    $ samba-tool dns zoneoptions --mark-old-records-static=2018-07-23 -U...
    
    where '2018-07-23' should be replaced by the approximate date of the
    upgrade beyond 4.9.
    
    It seems riskier making blanket conversions of static records into
    dynamic records, but there are sometimes useful patterns in the names
    given to machines that we can exploit. For example, if there is a
    group of machines with names like 'desktop-123' that are all supposed
    to using dynamic DNS, the adminstrator can go
    
    $ samba-tool dns zoneoptions --mark-records-dynamic-regex='desktop-\d+'
    
    and there's a --mark-records-static-regex for symmetry.
    
    These options are deliberately long and cumbersome to type, so people
    have a chance to think before they get to the end. We also introduce a
    '--dry-run' (or '-n') option so they can inspect the likely results
    before going ahead.
    
    *NOTE* ageing will still not work properly after this commit, due to
    other bugs that will be fixed in other commits.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 074f9e1486613c6e4f6bbff9222a23ba6bdf3603
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Fri May 28 16:54:33 2021 +1200

    pytest:samba-tool dns: more robust clean-up
    
    If setUp() fails (and here we have a big .setUp), .tearDown is not run,
    and that can leave the zone undeleted, breaking all the other tests who
    expect to be able to recreate it.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b11ea9d7adad8c6f147a8f6c610311004bf60c93
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Fri May 28 22:56:10 2021 +1200

    samba-tool dns: remove unused imports
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit eeaa1380325379ad58f7ff3a40ba5635028e540e
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu May 27 09:45:18 2021 +1200

    samba-tool dns: move dns_record_match to dnsserver.py
    
    This function is used here and in tests, but the tests should not be
    importing things from netcmd.dns, which is really supposed to be UI
    code. So we move to a common place.
    
    the only difference is the function raises DNSParseError instead of
    CommandError, and netcmd.dns has to catch and wrap that.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 librpc/ABI/{ndr-1.0.2.sigs => ndr-2.0.0.sigs}      |  14 +-
 librpc/ndr/libndr.h                                |  14 +-
 librpc/ndr/ndr.c                                   |  79 ++--
 librpc/ndr/ndr_basic.c                             |   8 +-
 librpc/ndr/ndr_negoex.c                            |   8 +-
 .../smbd/scavenger.h => librpc/ndr/ndr_private.h   |  19 +-
 librpc/ndr/ndr_spoolss_buf.c                       |   4 +-
 librpc/wscript_build                               |   2 +-
 pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm           |  37 +-
 python/pyglue.c                                    |   9 +
 python/samba/dnsserver.py                          |  91 +++++
 python/samba/netcmd/dns.py                         | 296 ++++++++++----
 python/samba/tests/dns.py                          |   3 +-
 python/samba/tests/ndr.py                          | 138 +++++++
 python/samba/tests/samba_tool/dnscmd.py            | 453 ++++++++++++++++++++-
 python/wscript                                     |   1 +
 selftest/target/Samba3.pm                          |   2 +-
 selftest/target/Samba4.pm                          |   2 +-
 selftest/tests.py                                  |   1 +
 19 files changed, 1024 insertions(+), 157 deletions(-)
 copy librpc/ABI/{ndr-1.0.2.sigs => ndr-2.0.0.sigs} (96%)
 copy source3/smbd/scavenger.h => librpc/ndr/ndr_private.h (68%)
 create mode 100644 python/samba/tests/ndr.py


Changeset truncated at 500 lines:

diff --git a/librpc/ABI/ndr-1.0.2.sigs b/librpc/ABI/ndr-2.0.0.sigs
similarity index 96%
copy from librpc/ABI/ndr-1.0.2.sigs
copy to librpc/ABI/ndr-2.0.0.sigs
index 0ec8575906a..aefe5aae64b 100644
--- a/librpc/ABI/ndr-1.0.2.sigs
+++ b/librpc/ABI/ndr-2.0.0.sigs
@@ -16,13 +16,14 @@ _ndr_pull_error: enum ndr_err_code (struct ndr_pull *, enum ndr_err_code, const
 _ndr_push_error: enum ndr_err_code (struct ndr_push *, enum ndr_err_code, const char *, const char *, const char *, ...)
 ndr_align_size: size_t (uint32_t, size_t)
 ndr_charset_length: uint32_t (const void *, charset_t)
-ndr_check_array_length: enum ndr_err_code (struct ndr_pull *, void *, uint32_t)
-ndr_check_array_size: enum ndr_err_code (struct ndr_pull *, void *, uint32_t)
+ndr_check_array_size: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t)
 ndr_check_padding: void (struct ndr_pull *, size_t)
 ndr_check_pipe_chunk_trailer: enum ndr_err_code (struct ndr_pull *, int, uint32_t)
+ndr_check_steal_array_length: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t)
+ndr_check_steal_array_size: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t)
 ndr_check_string_terminator: enum ndr_err_code (struct ndr_pull *, uint32_t, uint32_t)
-ndr_get_array_length: uint32_t (struct ndr_pull *, const void *)
-ndr_get_array_size: uint32_t (struct ndr_pull *, const void *)
+ndr_get_array_length: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t *)
+ndr_get_array_size: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t *)
 ndr_map_error2errno: int (enum ndr_err_code)
 ndr_map_error2ntstatus: NTSTATUS (enum ndr_err_code)
 ndr_map_error2string: const char *(enum ndr_err_code)
@@ -249,6 +250,8 @@ ndr_size_string_array: size_t (const char **, uint32_t, int)
 ndr_size_struct: size_t (const void *, int, ndr_push_flags_fn_t)
 ndr_size_union: size_t (const void *, int, uint32_t, ndr_push_flags_fn_t)
 ndr_size_winreg_Data_GPO: size_t (const union winreg_Data_GPO *, uint32_t, int)
+ndr_steal_array_length: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t *)
+ndr_steal_array_size: enum ndr_err_code (struct ndr_pull *, const void *, uint32_t *)
 ndr_string_array_size: size_t (struct ndr_push *, const char *)
 ndr_string_length: uint32_t (const void *, uint32_t)
 ndr_syntax_id_buf_string: char *(const struct ndr_syntax_id *, struct ndr_syntax_id_buf *)
@@ -256,7 +259,8 @@ ndr_syntax_id_equal: bool (const struct ndr_syntax_id *, const struct ndr_syntax
 ndr_syntax_id_from_string: bool (const char *, struct ndr_syntax_id *)
 ndr_syntax_id_null: uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\000", node = "\000\000\000\000\000"}, if_version = 0
 ndr_syntax_id_to_string: char *(TALLOC_CTX *, const struct ndr_syntax_id *)
-ndr_token_peek: uint32_t (struct ndr_token_list *, const void *)
+ndr_token_max_list_size: size_t (void)
+ndr_token_peek: enum ndr_err_code (struct ndr_token_list *, const void *, uint32_t *)
 ndr_token_retrieve: enum ndr_err_code (struct ndr_token_list *, const void *, uint32_t *)
 ndr_token_retrieve_cmp_fn: enum ndr_err_code (struct ndr_token_list *, const void *, uint32_t *, comparison_fn_t, bool)
 ndr_token_store: enum ndr_err_code (TALLOC_CTX *, struct ndr_token_list *, const void *, uint32_t)
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
index 25b68db3466..8a0b072d800 100644
--- a/librpc/ndr/libndr.h
+++ b/librpc/ndr/libndr.h
@@ -653,13 +653,17 @@ enum ndr_err_code ndr_token_store(TALLOC_CTX *mem_ctx,
 enum ndr_err_code ndr_token_retrieve_cmp_fn(struct ndr_token_list *list, const void *key, uint32_t *v,
 					    int(*_cmp_fn)(const void*,const void*), bool erase);
 enum ndr_err_code ndr_token_retrieve(struct ndr_token_list *list, const void *key, uint32_t *v);
-uint32_t ndr_token_peek(struct ndr_token_list *list, const void *key);
+enum ndr_err_code ndr_token_peek(struct ndr_token_list *list, const void *key, uint32_t *v);
 enum ndr_err_code ndr_pull_array_size(struct ndr_pull *ndr, const void *p);
-uint32_t ndr_get_array_size(struct ndr_pull *ndr, const void *p);
-enum ndr_err_code ndr_check_array_size(struct ndr_pull *ndr, void *p, uint32_t size);
+enum ndr_err_code ndr_get_array_size(struct ndr_pull *ndr, const void *p, uint32_t *size);
+enum ndr_err_code ndr_steal_array_size(struct ndr_pull *ndr, const void *p, uint32_t *size);
+enum ndr_err_code ndr_check_array_size(struct ndr_pull *ndr, const void *p, uint32_t size);
+enum ndr_err_code ndr_check_steal_array_size(struct ndr_pull *ndr, const void *p, uint32_t size);
 enum ndr_err_code ndr_pull_array_length(struct ndr_pull *ndr, const void *p);
-uint32_t ndr_get_array_length(struct ndr_pull *ndr, const void *p);
-enum ndr_err_code ndr_check_array_length(struct ndr_pull *ndr, void *p, uint32_t length);
+enum ndr_err_code ndr_get_array_length(struct ndr_pull *ndr, const void *p, uint32_t *length);
+enum ndr_err_code ndr_steal_array_length(struct ndr_pull *ndr, const void *p, uint32_t *length);
+enum ndr_err_code ndr_check_array_length(struct ndr_pull *ndr, const void *p, uint32_t length);
+enum ndr_err_code ndr_check_steal_array_length(struct ndr_pull *ndr, const void *p, uint32_t length);
 enum ndr_err_code ndr_push_pipe_chunk_trailer(struct ndr_push *ndr, int ndr_flags, uint32_t count);
 enum ndr_err_code ndr_check_pipe_chunk_trailer(struct ndr_pull *ndr, int ndr_flags, uint32_t count);
 enum ndr_err_code ndr_push_set_switch_value(struct ndr_push *ndr, const void *p, uint32_t val);
diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
index 024634d0a09..031e02a22da 100644
--- a/librpc/ndr/ndr.c
+++ b/librpc/ndr/ndr.c
@@ -29,6 +29,7 @@
 
 #include "includes.h"
 #include "librpc/ndr/libndr.h"
+#include "librpc/ndr/ndr_private.h"
 #include "../lib/util/dlinklist.h"
 
 #undef DBGC_CLASS
@@ -47,6 +48,10 @@
  */
 #define NDR_TOKEN_MAX_LIST_SIZE 65535
 
+size_t ndr_token_max_list_size(void) {
+	return NDR_TOKEN_MAX_LIST_SIZE;
+};
+
 /* this guid indicates NDR encoding in a protocol tower */
 const struct ndr_syntax_id ndr_transfer_syntax_ndr = {
   { 0x8a885d04, 0x1ceb, 0x11c9, {0x9f, 0xe8}, {0x08,0x00,0x2b,0x10,0x48,0x60} },
@@ -143,6 +148,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_pop(struct ndr_pull *ndr)
 {
 	uint32_t skip = 0;
 	uint32_t append = 0;
+	enum ndr_err_code ndr_err;
 
 	if (ndr->relative_base_offset != 0) {
 		return ndr_pull_error(ndr, NDR_ERR_RELATIVE,
@@ -174,8 +180,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_pop(struct ndr_pull *ndr)
 	ndr->offset -= skip;
 	ndr->data_size -= skip;
 
-	append = ndr_token_peek(&ndr->array_size_list, ndr);
-	if (append != UINT32_MAX) {
+	ndr_err = ndr_token_peek(&ndr->array_size_list, ndr, &append);
+	if (ndr_err == NDR_ERR_TOKEN) {
 		/*
 		 * here we assume, that ndr->data is not a
 		 * talloc child of ndr.
@@ -1060,18 +1066,10 @@ _PUBLIC_ enum ndr_err_code ndr_token_retrieve(struct ndr_token_list *list,
 /*
   peek at but don't removed a token from a ndr context
 */
-_PUBLIC_ uint32_t ndr_token_peek(struct ndr_token_list *list, const void *key)
+_PUBLIC_ enum ndr_err_code ndr_token_peek(struct ndr_token_list *list,
+					  const void *key, uint32_t *v)
 {
-	unsigned i;
-	struct ndr_token *tokens = list->tokens;
-
-	for (i = list->count - 1; i < list->count; i--) {
-		if (tokens[i].key == key) {
-			return tokens[i].value;
-		}
-	}
-
-	return 0;
+	return ndr_token_retrieve_cmp_fn(list, key, v, NULL, false);
 }
 
 /*
@@ -1094,18 +1092,44 @@ _PUBLIC_ enum ndr_err_code ndr_pull_array_size(struct ndr_pull *ndr, const void
 /*
   get the stored array size field
 */
-_PUBLIC_ uint32_t ndr_get_array_size(struct ndr_pull *ndr, const void *p)
+_PUBLIC_ enum ndr_err_code ndr_get_array_size(struct ndr_pull *ndr, const void *p, uint32_t *size)
 {
-	return ndr_token_peek(&ndr->array_size_list, p);
+	return ndr_token_peek(&ndr->array_size_list, p, size);
 }
 
 /*
-  check the stored array size field
+  get and remove from the stored list the stored array size field
 */
-_PUBLIC_ enum ndr_err_code ndr_check_array_size(struct ndr_pull *ndr, void *p, uint32_t size)
+_PUBLIC_ enum ndr_err_code ndr_steal_array_size(struct ndr_pull *ndr, const void *p, uint32_t *size)
+{
+	return ndr_token_retrieve(&ndr->array_size_list, p, size);
+}
+
+/*
+ * check the stored array size field and remove from the stored list
+ * (the array_size NDR token list).  We try to remove when possible to
+ * avoid the list growing towards the bounds check
+ */
+_PUBLIC_ enum ndr_err_code ndr_check_steal_array_size(struct ndr_pull *ndr, const void *p, uint32_t size)
 {
 	uint32_t stored;
-	stored = ndr_token_peek(&ndr->array_size_list, p);
+	NDR_CHECK(ndr_steal_array_size(ndr, p, &stored));
+	if (stored != size) {
+		return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE,
+				      "Bad array size - got %u expected %u\n",
+				      stored, size);
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+/*
+ * check the stored array size field (leaving it on the array_size
+ * token list)
+ */
+_PUBLIC_ enum ndr_err_code ndr_check_array_size(struct ndr_pull *ndr, const void *p, uint32_t size)
+{
+	uint32_t stored;
+	NDR_CHECK(ndr_get_array_size(ndr, p, &stored));
 	if (stored != size) {
 		return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE,
 				      "Bad array size - got %u expected %u\n",
@@ -1139,18 +1163,27 @@ _PUBLIC_ enum ndr_err_code ndr_pull_array_length(struct ndr_pull *ndr, const voi
 /*
   get the stored array length field
 */
-_PUBLIC_ uint32_t ndr_get_array_length(struct ndr_pull *ndr, const void *p)
+_PUBLIC_ enum ndr_err_code ndr_get_array_length(struct ndr_pull *ndr, const void *p, uint32_t *length)
 {
-	return ndr_token_peek(&ndr->array_length_list, p);
+	return ndr_token_peek(&ndr->array_length_list, p, length);
 }
 
 /*
-  check the stored array length field
+ * check the stored array length field and remove from the stored list
+ * (the array_size NDR token list).  We try to remove when possible to
+ * avoid the list growing towards the bounds check
+ */
+_PUBLIC_ enum ndr_err_code ndr_steal_array_length(struct ndr_pull *ndr, const void *p, uint32_t *length)
+{
+	return ndr_token_retrieve(&ndr->array_length_list, p, length);
+}
+/*
+  check the stored array length field, removing it from the list
 */
-_PUBLIC_ enum ndr_err_code ndr_check_array_length(struct ndr_pull *ndr, void *p, uint32_t length)
+_PUBLIC_ enum ndr_err_code ndr_check_steal_array_length(struct ndr_pull *ndr, const void *p, uint32_t length)
 {
 	uint32_t stored;
-	stored = ndr_token_peek(&ndr->array_length_list, p);
+	NDR_CHECK(ndr_steal_array_length(ndr, p, &stored));
 	if (stored != length) {
 		return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE,
 				      "Bad array length - got %u expected %u\n",
diff --git a/librpc/ndr/ndr_basic.c b/librpc/ndr/ndr_basic.c
index 82d2f3cfae6..e239cfb27d9 100644
--- a/librpc/ndr/ndr_basic.c
+++ b/librpc/ndr/ndr_basic.c
@@ -805,18 +805,20 @@ _PUBLIC_ enum ndr_err_code ndr_push_unique_ptr(struct ndr_push *ndr, const void
 */
 _PUBLIC_ enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p)
 {
+	enum ndr_err_code ret = NDR_ERR_SUCCESS;
 	uint32_t ptr = 0;
 	if (p) {
 		/* Check if the pointer already exists and has an id */
-		ptr = ndr_token_peek(&ndr->full_ptr_list, p);
-		if (ptr == 0) {
-			enum ndr_err_code ret = NDR_ERR_SUCCESS;
+		ret = ndr_token_peek(&ndr->full_ptr_list, p, &ptr);
+		if (ret == NDR_ERR_TOKEN) {
 			ndr->ptr_count++;
 			ptr = ndr->ptr_count;
 			ret = ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr);
 			if (ret != NDR_ERR_SUCCESS) {
 				return ret;
 			}
+		} else if (ret != NDR_ERR_SUCCESS) {
+			return ret;
 		}
 	}
 	return ndr_push_uint3264(ndr, NDR_SCALARS, ptr);
diff --git a/librpc/ndr/ndr_negoex.c b/librpc/ndr/ndr_negoex.c
index 95adce5a7e3..72c8774ce5c 100644
--- a/librpc/ndr/ndr_negoex.c
+++ b/librpc/ndr/ndr_negoex.c
@@ -99,7 +99,7 @@ enum ndr_err_code ndr_pull_negoex_BYTE_VECTOR(struct ndr_pull *ndr, int ndr_flag
 		}
 #if 0
 		if (r->blob.data) {
-			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->blob.data, r->blob.length));
+			NDR_CHECK(ndr_check_steal_array_size(ndr, (void*)&r->blob.data, r->blob.length));
 		}
 #endif
 	}
@@ -179,7 +179,7 @@ enum ndr_err_code ndr_pull_negoex_AUTH_SCHEME_VECTOR(struct ndr_pull *ndr, int n
 		}
 #if 0
 		if (r->array) {
-			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count));
+			NDR_CHECK(ndr_check_steal_array_size(ndr, (void*)&r->array, r->count));
 		}
 #endif
 	}
@@ -265,7 +265,7 @@ enum ndr_err_code ndr_pull_negoex_EXTENSION_VECTOR(struct ndr_pull *ndr, int ndr
 		}
 #if 0
 		if (r->array) {
-			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count));
+			NDR_CHECK(ndr_check_steal_array_size(ndr, (void*)&r->array, r->count));
 		}
 #endif
 	}
@@ -351,7 +351,7 @@ enum ndr_err_code ndr_pull_negoex_ALERT_VECTOR(struct ndr_pull *ndr, int ndr_fla
 		}
 #if 0
 		if (r->array) {
-			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->array, r->count));
+			NDR_CHECK(ndr_check_steal_array_size(ndr, (void*)&r->array, r->count));
 		}
 #endif
 	}
diff --git a/source3/smbd/scavenger.h b/librpc/ndr/ndr_private.h
similarity index 68%
copy from source3/smbd/scavenger.h
copy to librpc/ndr/ndr_private.h
index 966c80dabf0..08521be66fb 100644
--- a/source3/smbd/scavenger.h
+++ b/librpc/ndr/ndr_private.h
@@ -1,8 +1,8 @@
 /*
    Unix SMB/CIFS implementation.
-   smbd scavenger daemon
+   rpc interface definitions
 
-   Copyright (C) Gregor Beck                    2013
+   Copyright (C) Andrew Tridgell 2003
 
    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
@@ -18,14 +18,15 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _SCAVENGER_H_
-#define _SCAVENGER_H_
-
+/* This is not a public header file that is installed as part of Samba.
+ * 
+ * Instead, this is to allow our python layer to get to the
+ * NDR_TOKEN_MAX_LIST_SIZE
+*/
 
-bool smbd_scavenger_init(TALLOC_CTX *mem_ctx,
-			 struct messaging_context *msg,
-			 struct tevent_context *ev);
+#ifndef __NDR_PRIVATE_H__
+#define __NDR_PRIVATE_H__
 
-void scavenger_schedule_disconnected(struct files_struct *fsp);
+size_t ndr_token_max_list_size(void);
 
 #endif
diff --git a/librpc/ndr/ndr_spoolss_buf.c b/librpc/ndr/ndr_spoolss_buf.c
index 393d7addeb5..c5fa82cdfde 100644
--- a/librpc/ndr/ndr_spoolss_buf.c
+++ b/librpc/ndr/ndr_spoolss_buf.c
@@ -1084,7 +1084,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr,
 #else
 			NDR_CHECK(ndr_token_store(ndr, &ndr->array_size_list, &r->file_info, r->file_count));
 #endif
-			NDR_PULL_ALLOC_N(ndr, r->file_info, ndr_get_array_size(ndr, &r->file_info));
+			NDR_PULL_ALLOC_N(ndr, r->file_info, r->file_count);
 			_mem_save_file_info_1 = NDR_PULL_GET_MEM_CTX(ndr);
 			NDR_PULL_SET_MEM_CTX(ndr, r->file_info, 0);
 			for (cntr_file_info_1 = 0; cntr_file_info_1 < r->file_count; cntr_file_info_1++) {
@@ -1227,7 +1227,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr,
 			ndr->flags = _flags_save_string;
 		}
 		if (r->file_info) {
-			NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->file_info, r->file_count));
+			NDR_CHECK(ndr_check_steal_array_size(ndr, (void*)&r->file_info, r->file_count));
 		}
 	}
 	return NDR_ERR_SUCCESS;
diff --git a/librpc/wscript_build b/librpc/wscript_build
index 239e2895565..f6349e168fa 100644
--- a/librpc/wscript_build
+++ b/librpc/wscript_build
@@ -649,7 +649,7 @@ bld.SAMBA_LIBRARY('ndr',
     public_deps='samba-errors talloc samba-util util_str_hex',
     public_headers='gen_ndr/misc.h gen_ndr/ndr_misc.h ndr/libndr.h:ndr.h',
     header_path= [('*gen_ndr*', 'gen_ndr')],
-    vnum='1.0.2',
+    vnum='2.0.0',
     abi_directory='ABI',
     abi_match='!ndr_table_* ndr_* GUID_* _ndr_pull_error* _ndr_push_error*',
     )
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index 119590f6696..db992aa9e47 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -340,20 +340,27 @@ sub ParseArrayPullGetSize($$$$$$)
 
 	my $size;
 
-	if ($l->{IS_CONFORMANT}) {
-		$size = "ndr_get_array_size($ndr, " . get_pointer_to($var_name) . ")";
+	my $array_size = "size_$e->{NAME}_$l->{LEVEL_INDEX}";
+
+	if ($l->{IS_CONFORMANT} and (defined($l->{SIZE_IS}) or not $l->{IS_ZERO_TERMINATED})) {
+		$self->pidl("NDR_CHECK(ndr_get_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_size));");
+
+	} elsif ($l->{IS_CONFORMANT}) {
+		# This will be the last use of the array_size token
+		$self->pidl("NDR_CHECK(ndr_steal_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_size));");
+
 	} elsif ($l->{IS_ZERO_TERMINATED} and $l->{SIZE_IS} == 0 and $l->{LENGTH_IS} == 0) { # Noheader arrays
 		$size = "ndr_get_string_size($ndr, sizeof(*$var_name))";
+		$self->pidl("$array_size = $size;");
+
 	} else {
 		$size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL},
 			check_null_pointer($e, $env, sub { $self->pidl(shift); },
 					   "return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"),
 			check_fully_dereferenced($e, $env));
+		$self->pidl("$array_size = $size;");
 	}
 
-	$self->pidl("size_$e->{NAME}_$l->{LEVEL_INDEX} = $size;");
-	my $array_size = "size_$e->{NAME}_$l->{LEVEL_INDEX}";
-
 	if (my $range = has_property($e, "range")) {
 		my ($low, $high) = parse_range($range);
 		if ($low < 0) {
@@ -385,9 +392,13 @@ sub ParseArrayPullGetLength($$$$$$;$)
 		return $array_size;
 	}
 
-	my $length = "ndr_get_array_length($ndr, " . get_pointer_to($var_name) .")";
-	$self->pidl("length_$e->{NAME}_$l->{LEVEL_INDEX} = $length;");
 	my $array_length = "length_$e->{NAME}_$l->{LEVEL_INDEX}";
+	if ($l->{IS_VARYING} and (defined($l->{LENGTH_IS}) or not $l->{IS_ZERO_TERMINATED})) {
+		$self->pidl("NDR_CHECK(ndr_get_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_length));");
+	} else {
+		# This will be the last use of the array_length token
+		$self->pidl("NDR_CHECK(ndr_steal_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_length));");
+	}
 
 	if (my $range = has_property($e, "range")) {
 		my ($low, $high) = parse_range($range);
@@ -438,7 +449,14 @@ sub ParseArrayPullHeader($$$$$$)
 			check_null_pointer($e, $env, sub { $self->defer(shift); },
 					   "return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"),
 			check_fully_dereferenced($e, $env));
-		$self->defer("NDR_CHECK(ndr_check_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+		if (ContainsDeferred($e, $l)) {
+			# We will be needing the array_size token in
+			# the NDR_BUFFERS call, so don't steal it now
+			$self->defer("NDR_CHECK(ndr_check_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+		} else {
+			# This will be deferred until after the last ndr_get_array_size()
+			$self->defer("NDR_CHECK(ndr_check_steal_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+		}
 		$self->defer_deindent;
 		$self->defer("}");
 	}
@@ -450,7 +468,8 @@ sub ParseArrayPullHeader($$$$$$)
 			check_null_pointer($e, $env, sub { $self->defer(shift); },
 					   "return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for length_is()\");"),
 			check_fully_dereferenced($e, $env));
-		$self->defer("NDR_CHECK(ndr_check_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", $length));");
+		# This will be deferred until after the last ndr_get_array_length()
+		$self->defer("NDR_CHECK(ndr_check_steal_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", $length));");
 		$self->defer_deindent;
 		$self->defer("}");
 	}
diff --git a/python/pyglue.c b/python/pyglue.c
index 1947373974a..0e1bf82fa7a 100644
--- a/python/pyglue.c
+++ b/python/pyglue.c
@@ -24,6 +24,7 @@
 #include "param/pyparam.h"
 #include "lib/socket/netif.h"
 #include "lib/util/debug.h"
+#include "librpc/ndr/ndr_private.h"
 
 void init_glue(void);
 static PyObject *PyExc_NTSTATUSError;
@@ -266,6 +267,12 @@ static PyObject *py_is_selftest_enabled(PyObject *self,
 #endif
 }
 
+static PyObject *py_ndr_token_max_list_size(PyObject *self,
+                PyObject *Py_UNUSED(ignored))
+{
+	return PyLong_FromLong(ndr_token_max_list_size());
+}
+
 /*
   return the list of interface IPs we have configured
   takes an loadparm context, returns a list of IPs in string form
@@ -460,6 +467,8 @@ static PyMethodDef py_misc_methods[] = {
 		"is Samba built with AD DC?" },
 	{ "is_selftest_enabled", (PyCFunction)py_is_selftest_enabled,
 		METH_NOARGS, "is Samba built with selftest enabled?" },
+	{ "ndr_token_max_list_size", (PyCFunction)py_ndr_token_max_list_size,
+		METH_NOARGS, "How many NDR internal tokens is too many for this build?" },
 	{0}
 };
 
diff --git a/python/samba/dnsserver.py b/python/samba/dnsserver.py
index a9fcb7662e8..68634dbeb5f 100644
--- a/python/samba/dnsserver.py
+++ b/python/samba/dnsserver.py
@@ -295,3 +295,94 @@ def flag_from_string(rec_type):
         return getattr(dnsp, 'DNS_TYPE_' + rtype)
     except AttributeError:
         raise DNSParseError('Unknown type of DNS record %s' % rec_type) from e
+
+
+def dns_name_equal(n1, n2):
+    """Match dns name (of type DNS_RPC_NAME)"""
+    return n1.str.rstrip('.').lower() == n2.str.rstrip('.').lower()
+
+
+def dns_record_match(dns_conn, server, zone, name, record_type, data):
+    """Find a dns record that matches the specified data"""
+
+    # The matching is not as precises as that offered by
+    # dsdb_dns.match_record, which, for example, compares IPv6 records
+    # semantically rather than as strings. However that function
+    # compares database DnssrvRpcRecord structures, not wire
+    # DNS_RPC_RECORD structures.
+    #


-- 
Samba Shared Repository



More information about the samba-cvs mailing list