The branch, master has been updated
       via  1768e77f3a0 s4:librpc: make use of CHECK_DEBUGLVLC(DBGC_RPC_PARSE, 
...) in dcerpc_bh_do_ndr_print()
       via  e929df1cf49 s4:lib/messaging: make use of 
CHECK_DEBUGLVLC(DBGC_RPC_PARSE, ...) in irpc_bh_do_ndr_print()
       via  22de6ae43e8 s3:winbindd: make use of 
CHECK_DEBUGLVLC(DBGC_RPC_PARSE, ...) in wbint_bh_do_ndr_print()
       via  4fcadeb56ca s3:rpc_client: make use of 
CHECK_DEBUGLVLC(DBGC_RPC_PARSE, ...) rpccli_bh_do_ndr_print
       via  b1528f2a3ef s3:rpc_server:lsa: make use of the lib/util version of 
dns_cmp()
       via  60302bf8490 dsdb:util_trusts: remove unused copy of dns_cmp()
       via  0b505db5046 lib/util: add dns_cmp() as it's own file
       via  218a0f067c8 s4:rpc_server/lsa: let LookupSids* behave like Windows 
2022/2025
       via  9f369c62317 libcli/security: let dom_sid_lookup_predefined_sid() 
behave like Windows 2008R2
       via  abba3495d23 python:tests/dcerpc/lsa: add tests for invalid 
LookupSids2 combinations
       via  6b1ff9a38fc s4:pyrpc: allow connections with 
raise_result_exceptions=False
       via  7ecaf1a7793 pidl:Python: prepare code to avoid NTSTATUS/WERROR 
exceptions
       via  67c35d6b4ef pidl:Python: handle NTSTATUS/WERROR exceptions first
       via  13d9231800e pidl:Python: separate logic to calculate the signature 
string
       via  f7282c0dffb pidl:Python: check PyTuple_New() return value
       via  9dfb0ed8d29 pidl:Python: initialize pointers and add 'result' at 
the end
       via  8cdf7af43a3 pidl:Python: introduce $is_raisable_return helper 
variable
       via  fa6d0fd1b00 pidl:Python: generate nicer code for PyNdrRpcMethodDef 
arrays
      from  faa6290d89e docs: Fix the documentation for NET ADS DNS (UN)REGISTER

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


- Log -----------------------------------------------------------------
commit 1768e77f3a0836333cbcc333373b2127690ea5ac
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jun 5 04:56:02 2018 +0200

    s4:librpc: make use of CHECK_DEBUGLVLC(DBGC_RPC_PARSE, ...) in 
dcerpc_bh_do_ndr_print()
    
    This makes sure the debug class rpc_parse is used for ndr dump output.
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>
    
    Autobuild-User(master): Douglas Bagnall <[email protected]>
    Autobuild-Date(master): Wed Jan 29 02:11:51 UTC 2025 on atb-devel-224

commit e929df1cf491793db0caca817c742239683e4f1e
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jun 5 04:56:02 2018 +0200

    s4:lib/messaging: make use of CHECK_DEBUGLVLC(DBGC_RPC_PARSE, ...) in 
irpc_bh_do_ndr_print()
    
    This makes sure the debug class rpc_parse is used for ndr dump output.
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 22de6ae43e85cfa19080ade96785a6c8cc8eb312
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jun 5 04:56:02 2018 +0200

    s3:winbindd: make use of CHECK_DEBUGLVLC(DBGC_RPC_PARSE, ...) in 
wbint_bh_do_ndr_print()
    
    This makes sure the debug class rpc_parse is used for ndr dump output.
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 4fcadeb56caea716175a10317b512115b5fe992f
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jun 5 04:56:02 2018 +0200

    s3:rpc_client: make use of CHECK_DEBUGLVLC(DBGC_RPC_PARSE, ...) 
rpccli_bh_do_ndr_print
    
    This makes sure the debug class rpc_parse is used for ndr dump output.
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit b1528f2a3efef0c1ab7064eec669397fe04f14f8
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jun 5 03:28:09 2018 +0200

    s3:rpc_server:lsa: make use of the lib/util version of dns_cmp()
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 60302bf84900e233df5040ea7311455c42a0ff33
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jun 5 03:21:39 2018 +0200

    dsdb:util_trusts: remove unused copy of dns_cmp()
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 0b505db5046dff05347470012eaca169ad5ff1c2
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jun 5 03:18:56 2018 +0200

    lib/util: add dns_cmp() as it's own file
    
    This is a copy of the function in source4/dsdb/common/util_trusts.c, which 
will
    be removed soon.
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 218a0f067c894cbf61cde6183a269c0474d64ddc
Author: Stefan Metzmacher <[email protected]>
Date:   Fri Mar 10 15:05:15 2023 +0100

    s4:rpc_server/lsa: let LookupSids* behave like Windows 2022/2025
    
    The important part is the INVALID_SID should not
    cause an early exit of the loop.
    
    We need to return the intact names array with the
    correct count. And only return INVALID_SID
    if we would otherwise return NONE_MAPPED.
    
    For SOME_NOT_MAPPED we need to ignore invalid sids
    and just pretend they are not mapped.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 9f369c62317d74615834f99a088caababef685fc
Author: Stefan Metzmacher <[email protected]>
Date:   Wed Aug 12 17:08:14 2020 +0200

    libcli/security: let dom_sid_lookup_predefined_sid() behave like Windows 
2008R2
    
    Windows 2008R2 (172.31.9.133) returns the following:
    
     #> rpcclient 172.31.9.133 -Uadministrator%A1b2C3d4 -c 'lookupsids S-1-22-1 
S-1-22-1-0;lookupsids S-1-22;lookupsids S-1-3-0 S-1-3-99;lookupsids S-1-3'
     S-1-22-1 *unknown*\*unknown* (8)
     S-1-22-1-0 *unknown*\*unknown* (8)
     result was NT_STATUS_INVALID_SID
     S-1-3-0 \CREATOR OWNER (5)
     S-1-3-99 *unknown*\*unknown* (8)
     result was NT_STATUS_INVALID_SID
    
    While the current Samba (172.31.9.163) returns the following:
    
     #> rpcclient 172.31.9.163 -Uadministrator%A1b2C3d4 -c 'lookupsids S-1-22-1 
S-1-22-1-0;lookupsids S-1-22;lookupsids S-1-3-0 S-1-3-99;lookupsids S-1-3'
     result was NT_STATUS_INVALID_SID
     result was NT_STATUS_INVALID_SID
     S-1-3-0 \CREATOR OWNER (5)
     S-1-3-99 *unknown*\*unknown* (8)
     S-1-3 *unknown*\*unknown* (8)
    
    With this change also return the same as Windows 2008R2:
    
     #> rpcclient 172.31.9.163 -Uadministrator%A1b2C3d4 -c 'lookupsids S-1-22-1 
S-1-22-1-0;lookupsids S-1-22;lookupsids S-1-3-0 S-1-3-99;lookupsids S-1-3'
     S-1-22-1 *unknown*\*unknown* (8)
     S-1-22-1-0 *unknown*\*unknown* (8)
     result was NT_STATUS_INVALID_SID
     S-1-3-0 \CREATOR OWNER (5)
     S-1-3-99 *unknown*\*unknown* (8)
     result was NT_STATUS_INVALID_SID
    
    This is a minimal fix in order to avoid crashes in the Windows Explorer.
    The real fix needs more work and additional tests, as the behavior seems
    to be different in newer Windows releases.
    
    The following patch will let us behave like Windows 2022/2025...
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit abba3495d23524142a4cf55d208dce041adee96b
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jan 28 09:51:14 2025 +0100

    python:tests/dcerpc/lsa: add tests for invalid LookupSids2 combinations
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 6b1ff9a38fcddbe72b00e28960414526a42bde14
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jan 28 14:57:53 2025 +0100

    s4:pyrpc: allow connections with raise_result_exceptions=False
    
    This is needed in order to do useful tests with
    specific error codes and still checking all other
    out parameters.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 7ecaf1a779370ef3ecf189e51a5e668329fa24c7
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jan 28 14:56:54 2025 +0100

    pidl:Python: prepare code to avoid NTSTATUS/WERROR exceptions
    
    They are returned as additional result.
    
    It means callers can look at all out params,
    even if the status is an error.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 67c35d6b4ef6b7dbe9db3c52547b25580cd4756c
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jan 28 14:56:54 2025 +0100

    pidl:Python: handle NTSTATUS/WERROR exceptions first
    
    If we raise an exception we should not leak temporary
    python objects.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 13d9231800ea969675f3207cd2c863e433104b4d
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jan 28 10:27:16 2025 +0100

    pidl:Python: separate logic to calculate the signature string
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit f7282c0dffbf30d72051a81d46d831344a9bbcf9
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jan 28 10:20:08 2025 +0100

    pidl:Python: check PyTuple_New() return value
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 9dfb0ed8d29bd4a9146cf38bd63c4bb55b5faf73
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jan 28 10:19:09 2025 +0100

    pidl:Python: initialize pointers and add 'result' at the end
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 8cdf7af43a365b0545562033f6c51150f2fbb3a4
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jan 28 10:07:18 2025 +0100

    pidl:Python: introduce $is_raisable_return helper variable
    
    No change in the generated code.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit fa6d0fd1b00e4836215b4d80f1a9f527db82e01a
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Jan 28 12:02:08 2025 +0100

    pidl:Python: generate nicer code for PyNdrRpcMethodDef arrays
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

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

Summary of changes:
 lib/util/dns_cmp.c                   | 188 +++++++++++++++++++++++++++++
 lib/util/dns_cmp.h                   |  63 ++++++++++
 lib/util/wscript_build               |   1 +
 libcli/security/util_sid.c           |   5 +-
 pidl/lib/Parse/Pidl/Samba4/Python.pm | 157 ++++++++++++++++++++----
 python/samba/tests/dcerpc/lsa.py     | 226 ++++++++++++++++++++++++++++++++++-
 source3/rpc_client/cli_pipe.c        |   2 +-
 source3/rpc_server/lsa/srv_lsa_nt.c  |  56 +--------
 source3/winbindd/winbindd_dual_ndr.c |   2 +-
 source4/dsdb/common/util_trusts.c    | 175 +--------------------------
 source4/lib/messaging/messaging.c    |   2 +-
 source4/librpc/rpc/dcerpc.c          |   2 +-
 source4/librpc/rpc/pyrpc.h           |   1 +
 source4/librpc/rpc/pyrpc_util.c      |  27 ++++-
 source4/librpc/rpc/pyrpc_util.h      |   2 +-
 source4/rpc_server/lsa/lsa_lookup.c  |  15 +++
 16 files changed, 659 insertions(+), 265 deletions(-)
 create mode 100644 lib/util/dns_cmp.c
 create mode 100644 lib/util/dns_cmp.h


Changeset truncated at 500 lines:

diff --git a/lib/util/dns_cmp.c b/lib/util/dns_cmp.c
new file mode 100644
index 00000000000..e20c4297963
--- /dev/null
+++ b/lib/util/dns_cmp.c
@@ -0,0 +1,188 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2015
+
+   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/>.
+*/
+
+#include "replace.h"
+#include "lib/util/charset/charset.h"
+#include "lib/util/fault.h"
+#include "lib/util/dns_cmp.h"
+
+/*
+ * this function assumes names are well formed DNS names.
+ * it doesn't validate them
+ *
+ * It allows strings up to a length of UINT16_MAX - 1
+ * with up to UINT8_MAX components. On overflow this
+ * just returns the result of strcasecmp_m().
+ *
+ * Trailing dots (only one) are ignored.
+ *
+ * The DNS names are compared per component, starting from
+ * the last one.
+ *
+ * The function is usable in a sort, but the return value contains more
+ * information than a simple comparison. There are 5 return values, defined
+ * above.
+ *
+ * DNS_CMP_FIRST_IS_CHILD (-2) means the first argument is a sub-domain of the
+ * second. e.g. dns_cmp("foo.example.org", "example.org")
+ *
+ * DNS_CMP_FIRST_IS_LESS (-1) means the first argument sorts before the
+ * second, but is not a sub-domain. e.g. dns_cmp("eggsample.org", 
"example.org").
+ *
+ * DNS_CMP_SECOND_IS_CHILD (+2) and DNS_CMP_SECOND_IS_LESS (+1) have the
+ * similar expected meanings. DNS_CMP_MATCH (0) means equality.
+ *
+ * NULL values are the parent of all addresses, which means comparisons
+ * between a string and NULL will return +2 or -2.
+ */
+int dns_cmp(const char *s1, const char *s2)
+{
+       size_t l1 = 0;
+       const char *p1 = NULL;
+       size_t num_comp1 = 0;
+       uint16_t comp1[UINT8_MAX] = {0};
+       size_t l2 = 0;
+       const char *p2 = NULL;
+       size_t num_comp2 = 0;
+       uint16_t comp2[UINT8_MAX] = {0};
+       size_t i;
+
+       if (s1 == s2) {
+               /* this includes the both NULL case */
+               return DNS_CMP_MATCH;
+       }
+       if (s1 == NULL) {
+               return DNS_CMP_SECOND_IS_CHILD;
+       }
+       if (s2 == NULL) {
+               return DNS_CMP_FIRST_IS_CHILD;
+       }
+
+       l1 = strlen(s1);
+       l2 = strlen(s2);
+
+       /*
+        * trailing '.' are ignored.
+        */
+       if (l1 > 1 && s1[l1 - 1] == '.') {
+               l1--;
+       }
+       if (l2 > 1 && s2[l2 - 1] == '.') {
+               l2--;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(comp1); i++) {
+               char *p;
+
+               if (i == 0) {
+                       p1 = s1;
+
+                       if (l1 == 0 || l1 >= UINT16_MAX) {
+                               /* just use one single component on overflow */
+                               break;
+                       }
+               }
+
+               comp1[num_comp1++] = PTR_DIFF(p1, s1);
+
+               p = strchr_m(p1, '.');
+               if (p == NULL) {
+                       p1 = NULL;
+                       break;
+               }
+
+               p1 = p + 1;
+       }
+
+       if (p1 != NULL) {
+               /* just use one single component on overflow */
+               num_comp1 = 0;
+               comp1[num_comp1++] = 0;
+               p1 = NULL;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(comp2); i++) {
+               char *p;
+
+               if (i == 0) {
+                       p2 = s2;
+
+                       if (l2 == 0 || l2 >= UINT16_MAX) {
+                               /* just use one single component on overflow */
+                               break;
+                       }
+               }
+
+               comp2[num_comp2++] = PTR_DIFF(p2, s2);
+
+               p = strchr_m(p2, '.');
+               if (p == NULL) {
+                       p2 = NULL;
+                       break;
+               }
+
+               p2 = p + 1;
+       }
+
+       if (p2 != NULL) {
+               /* just use one single component on overflow */
+               num_comp2 = 0;
+               comp2[num_comp2++] = 0;
+               p2 = NULL;
+       }
+
+       for (i = 0; i < UINT8_MAX; i++) {
+               int cmp;
+
+               if (i < num_comp1) {
+                       size_t idx = num_comp1 - (i + 1);
+                       p1 = s1 + comp1[idx];
+               } else {
+                       p1 = NULL;
+               }
+
+               if (i < num_comp2) {
+                       size_t idx = num_comp2 - (i + 1);
+                       p2 = s2 + comp2[idx];
+               } else {
+                       p2 = NULL;
+               }
+
+               if (p1 == NULL && p2 == NULL) {
+                       return DNS_CMP_MATCH;
+               }
+               if (p1 != NULL && p2 == NULL) {
+                       return DNS_CMP_FIRST_IS_CHILD;
+               }
+               if (p1 == NULL && p2 != NULL) {
+                       return DNS_CMP_SECOND_IS_CHILD;
+               }
+
+               cmp = strcasecmp_m(p1, p2);
+               if (cmp < 0) {
+                       return DNS_CMP_FIRST_IS_LESS;
+               }
+               if (cmp > 0) {
+                       return DNS_CMP_SECOND_IS_LESS;
+               }
+       }
+
+       smb_panic(__location__);
+       return -1;
+}
diff --git a/lib/util/dns_cmp.h b/lib/util/dns_cmp.h
new file mode 100644
index 00000000000..c01a7a9f83e
--- /dev/null
+++ b/lib/util/dns_cmp.h
@@ -0,0 +1,63 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Copyright (C) Stefan Metzmacher 2015
+
+   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/>.
+*/
+
+#ifndef _LIB_UTIL_DNS_CMP_H_
+#define _LIB_UTIL_DNS_CMP_H_ 1
+
+#define DNS_CMP_FIRST_IS_CHILD -2
+#define DNS_CMP_FIRST_IS_LESS -1
+#define DNS_CMP_MATCH 0
+#define DNS_CMP_SECOND_IS_LESS 1
+#define DNS_CMP_SECOND_IS_CHILD 2
+
+#define DNS_CMP_IS_NO_MATCH(__cmp) \
+       ((__cmp == DNS_CMP_FIRST_IS_LESS) || (__cmp == DNS_CMP_SECOND_IS_LESS))
+
+/*
+ * this function assumes names are well formed DNS names.
+ * it doesn't validate them
+ *
+ * It allows strings up to a length of UINT16_MAX - 1
+ * with up to UINT8_MAX components. On overflow this
+ * just returns the result of strcasecmp_m().
+ *
+ * Trailing dots (only one) are ignored.
+ *
+ * The DNS names are compared per component, starting from
+ * the last one.
+ *
+ * The function is usable in a sort, but the return value contains more
+ * information than a simple comparison. There are 5 return values, defined
+ * above.
+ *
+ * DNS_CMP_FIRST_IS_CHILD (-2) means the first argument is a sub-domain of the
+ * second. e.g. dns_cmp("foo.example.org", "example.org")
+ *
+ * DNS_CMP_FIRST_IS_LESS (-1) means the first argument sorts before the
+ * second, but is not a sub-domain. e.g. dns_cmp("eggsample.org", 
"example.org").
+ *
+ * DNS_CMP_SECOND_IS_CHILD (+2) and DNS_CMP_SECOND_IS_LESS (+1) have the
+ * similar expected meanings. DNS_CMP_MATCH (0) means equality.
+ *
+ * NULL values are the parent of all addresses, which means comparisons
+ * between a string and NULL will return +2 or -2.
+ */
+int dns_cmp(const char *s1, const char *s2);
+
+#endif /* _LIB_UTIL_DNS_CMP_H_ */
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
index 1eab2bb5805..9dff0e8925d 100644
--- a/lib/util/wscript_build
+++ b/lib/util/wscript_build
@@ -186,6 +186,7 @@ else:
                   source='''
                          base64.c
                          dprintf.c
+                         dns_cmp.c
                          fsusage.c
                          genrand_util.c
                          getpass.c
diff --git a/libcli/security/util_sid.c b/libcli/security/util_sid.c
index 31f3ad161eb..13d24e04254 100644
--- a/libcli/security/util_sid.c
+++ b/libcli/security/util_sid.c
@@ -1073,7 +1073,6 @@ NTSTATUS dom_sid_lookup_predefined_sid(const struct 
dom_sid *sid,
                                       const char **authority_name)
 {
        size_t di;
-       bool match_domain = false;
 
        *name = NULL;
        *type = SID_NAME_UNKNOWN;
@@ -1095,8 +1094,6 @@ NTSTATUS dom_sid_lookup_predefined_sid(const struct 
dom_sid *sid,
                        continue;
                }
 
-               match_domain = true;
-
                for (ni = 0; ni < d->num_names; ni++) {
                        const struct predefined_name_mapping *n =
                                &d->names[ni];
@@ -1114,7 +1111,7 @@ NTSTATUS dom_sid_lookup_predefined_sid(const struct 
dom_sid *sid,
                }
        }
 
-       if (!match_domain) {
+       if (sid->num_auths == 0) {
                return NT_STATUS_INVALID_SID;
        }
 
diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm 
b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 66c90cfd051..1d32f71c886 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -1017,61 +1017,146 @@ sub PythonFunctionUnpackOut($$$)
        my $env = GenerateFunctionOutEnv($fn, "r->");
        my $result_size = 0;
 
-       $self->pidl("static PyObject *$outfnname(struct $fn->{NAME} *r)");
+       $self->pidl("static PyObject *$outfnname(struct $fn->{NAME} *r, bool 
raise_result_exception)");
        $self->pidl("{");
        $self->indent;
-       $self->pidl("PyObject *result;");
        foreach my $e (@{$fn->{ELEMENTS}}) {
                next unless (grep(/out/,@{$e->{DIRECTION}}));
                next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, 
@{$e->{DIRECTION}})) or
                         ($metadata_args->{out}->{$e->{NAME}}) and grep(/out/, 
@{$e->{DIRECTION}}));
-               $self->pidl("PyObject *py_$e->{NAME};");
+               $self->pidl("PyObject *py_$e->{NAME} = NULL;");
                $result_size++;
        }
 
-       if ($fn->{RETURN_TYPE}) {
-               $result_size++ unless ($fn->{RETURN_TYPE} eq "WERROR" or 
$fn->{RETURN_TYPE} eq "NTSTATUS");
+       my $is_raisable_return = 0;
+       if ($fn->{RETURN_TYPE} and ($fn->{RETURN_TYPE} eq "WERROR" or 
$fn->{RETURN_TYPE} eq "NTSTATUS")) {
+               $is_raisable_return = 1;
        }
 
-       my $i = 0;
+       if ($fn->{RETURN_TYPE} and not $is_raisable_return) {
+               $result_size++;
+       }
+
+       my $max_result_size = $result_size;
+       my $alloc_size = "$result_size";
+       if ($fn->{RETURN_TYPE} and $is_raisable_return) {
+               $max_result_size++;
+       }
+       $self->pidl("PyObject *result = NULL;");
+       if ($max_result_size != $result_size) {
+               $self->pidl("size_t result_size = $result_size;");
+               $alloc_size = "result_size";
+       }
+       $self->pidl("");
 
        if ($result_size > 1) {
-               $self->pidl("result = PyTuple_New($result_size);");
                $signature .= "(";
        } elsif ($result_size == 0) {
-               $self->pidl("result = Py_None;");
-               $self->pidl("Py_INCREF(result);");
                $signature .= "None";
        }
 
+       if ($fn->{RETURN_TYPE} and $is_raisable_return) {
+               $self->pidl("if (raise_result_exception) {");
+               $self->indent;
+               if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq 
"NTSTATUS") {
+                       $self->handle_ntstatus("r->out.result", "NULL", undef);
+               } elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq 
"WERROR") {
+                       $self->handle_werror("r->out.result", "NULL", undef);
+               }
+               $self->deindent;
+               $self->pidl("} else {");
+               $self->indent;
+               $self->pidl("/* $fn->{RETURN_TYPE} will be part of the results 
*/");
+               $self->pidl("result_size += 1;");
+               $self->deindent;
+               $self->pidl("}");
+               $self->pidl("");
+       }
+
+       if ($max_result_size > 1) {
+               if ($max_result_size != $result_size) {
+                       $self->pidl("if (result_size > 1) {");
+                       $self->indent;
+               }
+               $self->pidl("result = PyTuple_New($alloc_size);");
+               $self->pidl("if (result == NULL) {");
+               $self->indent;
+               $self->pidl("return NULL;");
+               $self->deindent;
+               $self->pidl("}");
+               if ($max_result_size != $result_size) {
+                       $self->deindent;
+                       $self->pidl("}");
+               }
+               $self->pidl("");
+       }
+
+       my $i = 0;
+
        foreach my $e (@{$fn->{ELEMENTS}}) {
                next if ($metadata_args->{out}->{$e->{NAME}});
                my $py_name = "py_$e->{NAME}";
                if (grep(/out/,@{$e->{DIRECTION}})) {
                        $self->ConvertObjectToPython("r", $env, $e, 
"r->out.$e->{NAME}", $py_name, "return NULL;");
                        if ($result_size > 1) {
-                               $self->pidl("PyTuple_SetItem(result, $i, 
$py_name);");
-                               $i++;
                                $signature .= "$e->{NAME}, ";
                        } else {
-                               $self->pidl("result = $py_name;");
                                $signature .= $e->{NAME};
                        }
+
+                       if ($max_result_size > 1) {
+                               if ($max_result_size != $result_size and 
$result_size == 1) {
+                                       $self->pidl("if (result_size > 1) {");
+                                       $self->indent;
+                               }
+                               $self->pidl("PyTuple_SetItem(result, $i, 
$py_name);");
+                               if ($max_result_size != $result_size and 
$result_size == 1) {
+                                       $self->deindent;
+                                       $self->pidl("}");
+                               }
+                       }
+                       if ($result_size == 1) {
+                               if ($max_result_size != $result_size) {
+                                       $self->pidl("if (result_size == 1) {");
+                                       $self->indent;
+                               }
+                               $self->pidl("result = $py_name;");
+                               if ($max_result_size != $result_size) {
+                                       $self->deindent;
+                                       $self->pidl("}");
+                               }
+                       }
+                       $self->pidl("");
+                       $i++;
                }
        }
 
-       if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") {
-               $self->handle_ntstatus("r->out.result", "NULL", undef);
-       } elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq 
"WERROR") {
-               $self->handle_werror("r->out.result", "NULL", undef);
-       } elsif (defined($fn->{RETURN_TYPE})) {
+       if ($fn->{RETURN_TYPE} and $is_raisable_return) {
+               $self->pidl("if (!raise_result_exception) {");
+               $self->indent;
+       }
+
+       if ($fn->{RETURN_TYPE}) {
                my $conv = $self->ConvertObjectToPythonData("r", 
$fn->{RETURN_TYPE}, "r->out.result", $fn);
-               if ($result_size > 1) {
+               if ($max_result_size > 1) {
                        $self->pidl("PyTuple_SetItem(result, $i, $conv);");
-               } else {
+               } elsif ($max_result_size == 1) {
                        $self->pidl("result = $conv;");
+               } else {
+                       fatal($fn->{ORIGINAL}, "Internal error 
max_result_size=$max_result_size");
+               }
+
+               if (not $is_raisable_return) {
+                       $signature .= "result";
                }
-               $signature .= "result";
+       }
+
+       if ($fn->{RETURN_TYPE} and $is_raisable_return) {
+               $self->deindent;
+               $self->pidl("}");
+               $self->pidl("");
+       } elsif ($fn->{RETURN_TYPE}) {
+               $self->pidl("");
        }
 
        if (substr($signature, -2) eq ", ") {
@@ -1081,6 +1166,20 @@ sub PythonFunctionUnpackOut($$$)
                $signature .= ")";
        }
 
+       if ($result_size == 0) {
+               if ($max_result_size != $result_size) {
+                       $self->pidl("if (result_size == 0) {");
+                       $self->indent;
+               }
+               $self->pidl("result = Py_None;");
+               $self->pidl("Py_INCREF(result);");
+               if ($max_result_size != $result_size) {
+                       $self->deindent;
+                       $self->pidl("}");
+               }
+               $self->pidl("");
+       }
+
        $self->pidl("return result;");
        $self->deindent;
        $self->pidl("}");
@@ -1467,9 +1566,23 @@ sub Interface($$$)
                $self->indent;
                foreach my $d (@fns) {


-- 
Samba Shared Repository

Reply via email to