[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Fri Jan 26 18:05:02 UTC 2024


The branch, master has been updated
       via  447e131ebf2 smb2_tcon: add "smb3 share cap:{CONTINUOUS AVAILABILITY,SCALE OUT,CLUSTER,ASYMMETRIC}" options
       via  941f53f0c93 python:tests/rpcd_witness_samba_only: add tests for 'net witness force-response'
       via  946bf100685 s3:utils: add 'net witness force-response'
       via  8a643fea95c python:tests/rpcd_witness_samba_only: add tests for 'net witness force-unregister'
       via  8536a217922 s3:utils: add 'net witness force-unregister'
       via  290ef547d86 python:tests/rpcd_witness_samba_only: add tests for 'net witness {client,share}-move'
       via  df3b5f93390 s3:utils: add 'net witness client-move' and 'net witness share-move'
       via  4fba5bcaad7 s3:rpc_server/witness: add handling of MSG_RPCD_WITNESS_REGISTRATION_UPDATE messages
       via  b722dc74f86 s3:rpcd_witness.idl: add rpcd_witness_registration_updateB message definitions
       via  0744d55be03 messaging.idl: add MSG_RPCD_WITNESS_REGISTRATION_UPDATE
       via  3e70b31f013 python:tests/rpcd_witness_samba_only: add tests for 'net witness list'
       via  46fdeca696e s3:utils: add 'net witness list' command
       via  fcc8e0978b6 s3:rpc_server/witness: let Register[Ex] store rpcd_witness_registration.tdb records
       via  a9829ce6cf3 s3:rpcd_witness.idl: introduce definitions for rpcd_witness_registration.tdb records
       via  b17e090e7c1 python/blackbox: add rpcd_witness_samba_only.py test
       via  b3c51c4b825 python/tests: add TestCase.get_loadparm(s3=True) support
       via  ea1ec424ad0 script/autobuild.py: also pass PYTHONPATH to make test of 'samba-ctdb'
       via  3ede69552ca selftest/Samba: export CTDB_PREFIX in clusteredmember testenv
       via  2f9dfaae448 selftest/Samba3: start samba_dcerpcd in clusteredmember
       via  15b17f1fffc selftest/Samba3: remove unused variable in setup_clusteredmember
       via  bc2a77373a0 selftest/Samba3: get NETBIOSNAME correct for clusteredmember
       via  cb1d711e25a s3:rpc_server/witness: add implementation based on CTDB_SRVID_IPREALLOCATED and ctdbd_all_ip_foreach()
       via  85f30bcf0b6 s3:rpc_server: add basic rpcd_witness template
       via  9083f49e767 s3:ctdbd_conn: add ctdbd_all_ip_foreach() helper
       via  3106709c891 s3:ctdbd_conn: split out ctdbd_control_get_nodemap()
       via  ceda79b6cc0 s3:ctdbd_conn: pass vnn to ctdbd_control_get_public_ips()
       via  f21e3800644 witness.idl: make witness_interfaceList public to that ndr_print works in python
       via  b9bd7e89f28 smbstatus: let --json include session.{creation,expiration,auth}_time
      from  fe8d866d2c6 vfs_ceph: Implement SMB_VFS_FSTATAT

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


- Log -----------------------------------------------------------------
commit 447e131ebf2b7bb02e7dfbb0ee38c2d656632856
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jul 31 08:55:20 2012 +0200

    smb2_tcon: add "smb3 share cap:{CONTINUOUS AVAILABILITY,SCALE OUT,CLUSTER,ASYMMETRIC}" options
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Fri Jan 26 18:04:10 UTC 2024 on atb-devel-224

commit 941f53f0c937fa75562183e9a4e1c95adf5d9524
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jan 22 19:27:03 2024 +0100

    python:tests/rpcd_witness_samba_only: add tests for 'net witness force-response'
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 946bf100685da22cebbc38bcf96139c02ea35921
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Dec 15 14:49:37 2023 +0100

    s3:utils: add 'net witness force-response'
    
    This allows generating any possible AsyncNotify response
    for the specified selection of witness registrations
    from rpcd_witness_registration.tdb.
    
    This can be used by developers to test the (windows)
    client behavior to specific AsyncNotify responses.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 8a643fea95c2d7d4f6709a10ff798bf3f9e210aa
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jan 15 14:20:00 2024 +0100

    python:tests/rpcd_witness_samba_only: add tests for 'net witness force-unregister'
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 8536a217922f7a2c5545b8f87084d08ea955ac61
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Dec 15 14:49:37 2023 +0100

    s3:utils: add 'net witness force-unregister'
    
    This allows removing of the specified selection
    of witness registrations from rpcd_witness_registration.tdb.
    
    Any pending AsyncNotify will get WERR_NOT_FOUND.
    
    Typically this triggers a clean re-registration on the client.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 290ef547d869100bdea42784b8a8783085eed805
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jan 15 14:20:00 2024 +0100

    python:tests/rpcd_witness_samba_only: add tests for 'net witness {client,share}-move'
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit df3b5f93390ce154c761b6337a3acad3ef254cc8
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Dec 15 14:49:37 2023 +0100

    s3:utils: add 'net witness client-move' and 'net witness share-move'
    
    These can be used to generate CLIENT_MOVE or SHARE_MOVE message
    to the specified selection of witness registrations from
    rpcd_witness_registration.tdb
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 4fba5bcaad7b54cb840fa006a4f6d0477980d9b2
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Dec 20 19:22:25 2023 +0100

    s3:rpc_server/witness: add handling of MSG_RPCD_WITNESS_REGISTRATION_UPDATE messages
    
    This implements the server side features for the
    'net witness [client-move,...]' commands in the end.
    
    These are administrator driven notifications for the witness client.
    
    RPCD_WITNESS_REGISTRATION_UPDATE_FORCE_RESPONSE and
    RPCD_WITNESS_REGISTRATION_UPDATE_FORCE_UNREGISTER will be very useful
    for later automated testing.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit b722dc74f86038eeaf3de875b5ca2cf2dadfe7a7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Dec 21 15:03:05 2023 +0100

    s3:rpcd_witness.idl: add rpcd_witness_registration_updateB message definitions
    
    This will be used for rpcd_witness_registration_updateB messages
    in 'net witness [client-move,...]' commands later.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 0744d55be03331808c99c159e7d8ca02b5323781
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Dec 21 15:03:05 2023 +0100

    messaging.idl: add MSG_RPCD_WITNESS_REGISTRATION_UPDATE
    
    This will be used for rpcd_witness_registration_updateB messages
    in 'net witness [client-move,...]' commands later.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 3e70b31f013b7835b1e9da19ecb7b6977433b48c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 12 17:30:41 2024 +0100

    python:tests/rpcd_witness_samba_only: add tests for 'net witness list'
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 46fdeca696e3fc308d8978ae6a2fc62bd13c5dcf
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Dec 15 14:49:37 2023 +0100

    s3:utils: add 'net witness list' command
    
    It lists the entries from the rpcd_witness_registration.tdb.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit fcc8e0978b61ea28be9c96ab14798ed6a97b21c3
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 24 17:15:36 2023 +0100

    s3:rpc_server/witness: let Register[Ex] store rpcd_witness_registration.tdb records
    
    This will allow 'net witness list' to be implemented in the end.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit a9829ce6cf3a8ca745bbf8ceceb1566d2dc17dce
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Dec 21 15:03:05 2023 +0100

    s3:rpcd_witness.idl: introduce definitions for rpcd_witness_registration.tdb records
    
    A rpcd_witness_registration.tdb will be added shortly in order to
    implement useful 'net witness [list,client-move,...]' commands
    in the end.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit b17e090e7c1b864eb6e8a9663c6145fb97d91e0f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Jan 10 15:11:24 2024 +0100

    python/blackbox: add rpcd_witness_samba_only.py test
    
    This tests the witness service and its interaction with
    ctdb.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit b3c51c4b825b2886e789a34f7df2469f0e0742ce
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 12 16:56:58 2024 +0100

    python/tests: add TestCase.get_loadparm(s3=True) support
    
    This will be used for tests with registry shares,
    as the top level loadparm system doesn't support them.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit ea1ec424ad02a79b4e29453bc50d4e631251f2ae
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jan 15 13:06:57 2024 +0100

    script/autobuild.py: also pass PYTHONPATH to make test of 'samba-ctdb'
    
    Otherwise tests won't find the custom tdb python bindings
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 3ede69552ca7b06438a46f52d04683d655f3a180
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 12 17:09:51 2024 +0100

    selftest/Samba: export CTDB_PREFIX in clusteredmember testenv
    
    It means ctdb/tests/local_daemons.sh will be easily useable
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 2f9dfaae4481cc3e9c907a774b5ef57461cbe879
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 12 17:08:06 2024 +0100

    selftest/Samba3: start samba_dcerpcd in clusteredmember
    
    This enables the rpcd_witness to be available.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 15b17f1fffc45d624352a81c485c82d9e2d491eb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 12 17:06:05 2024 +0100

    selftest/Samba3: remove unused variable in setup_clusteredmember
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit bc2a77373a0a786fa8ea13a237a04850a5f5f0d7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 12 17:03:38 2024 +0100

    selftest/Samba3: get NETBIOSNAME correct for clusteredmember
    
    It was missed in commit
    7598b9069d3b983f8eb3b89b8459ec993ee43c80
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit cb1d711e25ab62cc4950561a94abc9bca0363d2d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 9 20:24:52 2023 +0200

    s3:rpc_server/witness: add implementation based on CTDB_SRVID_IPREALLOCATED and ctdbd_all_ip_foreach()
    
    The design is relatively simple in the end:
    
    - We use ctdbd_all_ip_foreach() in order to build an
      in memory list of interfaces(ip addresses) and
      record if:
      - they are currently available or not
      - if they node local or not
    
    - The current list is would we use for the
      GetInterfaceList() call.
    
    - Register[Ex] will create an in memory structure
      holding a queue for pending AsyncNotify requests.
    
    - Unregister() will cancel pending AsyncNotify requests and
      let them return NOT_FOUND.
    
    - CTDB_SRVID_IPREALLOCATED messages will cause we refresh
      with ctdbd_all_ip_foreach():
      - this will detect changes in the interface state
        and remove stale interfaces.
      - for each change the list of registrations is checked
        for a matching ip address and a RESOURCE_CHANGE
        will be scheduled in the queue of the registration,
        the started queue will trigger AsyncNotify responses
    
    - We also register the connections with ctdb in order
      to give other nodes a chance to generate tickle-acks
      for the witness tcp connections.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 85f30bcf0b621356fcfb39b447dce6ff7d6eb5fc
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 9 12:18:05 2023 +0200

    s3:rpc_server: add basic rpcd_witness template
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 9083f49e767409a34c629242086746622684d365
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 11 13:07:46 2023 +0200

    s3:ctdbd_conn: add ctdbd_all_ip_foreach() helper
    
    This can we used to traverse through all ip addresses ctdb knows
    about.
    
    The caller can select node ips and/or public ips.
    
    This will we useful to monitor the addresses from a witness
    service...
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit 3106709c8911d3684d0e3c6dea939df5ce558c6d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 11 11:51:04 2023 +0200

    s3:ctdbd_conn: split out ctdbd_control_get_nodemap()
    
    This will simplify future changes...
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit ceda79b6cc0857333ce2fdea464a7b9df8b691e6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 11 11:30:07 2023 +0200

    s3:ctdbd_conn: pass vnn to ctdbd_control_get_public_ips()
    
    In future we also want to ask other nodes for their public_ips.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit f21e38006447833c114ac6477aefcfb800a7c150
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Jan 12 16:54:32 2024 +0100

    witness.idl: make witness_interfaceList public to that ndr_print works in python
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

commit b9bd7e89f28b2ed5f32c8c1eba7b9b7d6b8b8e29
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jan 9 16:46:06 2024 +0100

    smbstatus: let --json include session.{creation,expiration,auth}_time
    
    This is very useful in order to predict NETWORK_SESSION_EXPIRED
    messages...
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Günther Deschner <gd at samba.org>

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

Summary of changes:
 librpc/idl/messaging.idl                           |    3 +
 librpc/idl/witness.idl                             |    2 +-
 librpc/wscript_build                               |    2 +-
 python/samba/tests/__init__.py                     |   14 +-
 .../tests/blackbox/rpcd_witness_samba_only.py      | 1338 +++++++++++
 python/samba/tests/usage.py                        |    2 +
 script/autobuild.py                                |    2 +-
 selftest/target/Samba.pm                           |    1 +
 selftest/target/Samba3.pm                          |    9 +-
 source3/include/ctdbd_conn.h                       |    9 +
 source3/lib/ctdb_dummy.c                           |   13 +
 source3/lib/ctdbd_conn.c                           |  319 ++-
 source3/librpc/idl/rpcd_witness.idl                |  109 +
 source3/librpc/idl/wscript_build                   |    1 +
 source3/librpc/wscript_build                       |    5 +
 source3/rpc_server/rpcd_witness.c                  |  120 +
 source3/rpc_server/witness/srv_witness_nt.c        | 2465 ++++++++++++++++++++
 source3/rpc_server/wscript_build                   |   15 +
 source3/smbd/smb2_tcon.c                           |   72 +
 source3/utils/net.c                                |   64 +
 source3/utils/net.h                                |    9 +
 source3/utils/net_proto.h                          |    2 +
 source3/utils/net_witness.c                        | 2361 +++++++++++++++++++
 source3/utils/status_json.c                        |   34 +
 source3/utils/wscript_build                        |    1 +
 source4/selftest/tests.py                          |   12 +
 26 files changed, 6951 insertions(+), 33 deletions(-)
 create mode 100755 python/samba/tests/blackbox/rpcd_witness_samba_only.py
 create mode 100644 source3/librpc/idl/rpcd_witness.idl
 create mode 100644 source3/rpc_server/rpcd_witness.c
 create mode 100644 source3/rpc_server/witness/srv_witness_nt.c
 create mode 100644 source3/utils/net_witness.c


Changeset truncated at 500 lines:

diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl
index 2bcf1021453..df579cfa845 100644
--- a/librpc/idl/messaging.idl
+++ b/librpc/idl/messaging.idl
@@ -141,6 +141,9 @@ interface messaging
 		MSG_SMBXSRV_CONNECTION_PASSED	= 0x0602,
 		MSG_SMBXSRV_CONNECTION_DROP	= 0x0603,
 
+		/* rpcd_witness messages */
+		MSG_RPCD_WITNESS_REGISTRATION_UPDATE = 0x0680,
+
 		/* source4 and NTVFS smb server messages */
 		MSG_BRL_RETRY                   = 0x0700,
 		MSG_PVFS_RETRY_OPEN             = 0x0701,
diff --git a/librpc/idl/witness.idl b/librpc/idl/witness.idl
index f69c9bbc009..dc3af4a6e0b 100644
--- a/librpc/idl/witness.idl
+++ b/librpc/idl/witness.idl
@@ -43,7 +43,7 @@ interface witness
 		witness_interfaceInfo_flags flags;
 	} witness_interfaceInfo;
 
-	typedef struct {
+	typedef [public] struct {
 		uint32 num_interfaces;
 		[size_is(num_interfaces)] witness_interfaceInfo *interfaces;
 	} witness_interfaceList;
diff --git a/librpc/wscript_build b/librpc/wscript_build
index f7763e1013d..ee2ad70857d 100644
--- a/librpc/wscript_build
+++ b/librpc/wscript_build
@@ -646,7 +646,7 @@ bld.SAMBA_LIBRARY('ndr-samba',
     deps='''NDR_DRSBLOBS NDR_DRSUAPI NDR_IDMAP NDR_NTLMSSP NDR_NEGOEX NDR_SCHANNEL NDR_MGMT
     NDR_DNSSERVER NDR_EPMAPPER NDR_XATTR NDR_UNIXINFO NDR_NAMED_PIPE_AUTH
     NDR_NTPRINTING NDR_FSRVP NDR_WITNESS NDR_MDSSVC NDR_OPEN_FILES NDR_SMBXSRV
-    NDR_SMB3POSIX
+    NDR_SMB3POSIX NDR_RPCD_WITNESS
     NDR_KRB5CCACHE NDR_WSP NDR_GKDI NDR_GMSA''',
     private_library=True,
     grouping_library=True
diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py
index 6a28c0de4c0..136dd2fc316 100644
--- a/python/samba/tests/__init__.py
+++ b/python/samba/tests/__init__.py
@@ -194,8 +194,8 @@ class TestCase(unittest.TestCase):
             self.addCleanup(samba.set_debug_level, test_debug_level)
 
     @classmethod
-    def get_loadparm(cls):
-        return env_loadparm()
+    def get_loadparm(cls, s3=False):
+        return env_loadparm(s3=s3)
 
     def get_credentials(self):
         return cmdline_credentials
@@ -424,15 +424,19 @@ class TestCaseInTempDir(TestCase):
         self.rm_files(*dirs, allow_missing=allow_missing, _rm=shutil.rmtree)
 
 
-def env_loadparm():
-    lp = param.LoadParm()
+def env_loadparm(s3=False):
+    if s3:
+        from samba.samba3 import param as s3param
+        lp = s3param.get_context()
+    else:
+        lp = param.LoadParm()
+
     try:
         lp.load(os.environ["SMB_CONF_PATH"])
     except KeyError:
         raise KeyError("SMB_CONF_PATH not set")
     return lp
 
-
 def env_get_var_value(var_name, allow_missing=False):
     """Returns value for variable in os.environ
 
diff --git a/python/samba/tests/blackbox/rpcd_witness_samba_only.py b/python/samba/tests/blackbox/rpcd_witness_samba_only.py
new file mode 100755
index 00000000000..aa81c347f99
--- /dev/null
+++ b/python/samba/tests/blackbox/rpcd_witness_samba_only.py
@@ -0,0 +1,1338 @@
+#!/usr/bin/env python3
+# Unix SMB/CIFS implementation.
+#
+# Copyright © 2024 Stefan Metzmacher <metze at samba.org>
+#
+# 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 sys
+import os
+
+sys.path.insert(0, "bin/python")
+os.environ["PYTHONUNBUFFERED"] = "1"
+
+import json
+
+import samba.tests
+from samba.credentials import Credentials
+from samba.ndr import ndr_print
+from samba.dcerpc import witness
+from samba.tests import DynamicTestCase, BlackboxTestCase
+from samba.common import get_string
+from samba import werror, WERRORError
+
+ at DynamicTestCase
+class RpcdWitnessSambaTests(BlackboxTestCase):
+    @classmethod
+    def setUpDynamicTestCases(cls):
+        cls.num_nodes = int(samba.tests.env_get_var_value('NUM_NODES'))
+
+        def _define_tests(idx1, idx2, ndr64=False):
+            cls._define_GetInterfaceList_test(idx1, idx2, ndr64)
+            if idx1 == 0 and idx2 != -1:
+                cls._define_ResourceChangeCTDB_tests(idx1, idx2, ndr64)
+
+        for idx1 in range(0, cls.num_nodes):
+            _define_tests(idx1, -1, ndr64=False)
+            _define_tests(idx1, -1, ndr64=True)
+            for idx2 in range(0, cls.num_nodes):
+                _define_tests(idx1, idx2, ndr64=False)
+                _define_tests(idx1, idx2, ndr64=True)
+
+    def setUp(self):
+        super().setUp()
+
+        # ctdb/tests/local_daemons.sh doesn't like CTDB_SOCKET to be set already
+        # and it doesn't need CTDB_BASE, so we stash them away
+        self.saved_CTDB_SOCKET = samba.tests.env_get_var_value('CTDB_SOCKET',
+                                                               allow_missing=True)
+        if self.saved_CTDB_SOCKET is not None:
+            del os.environ["CTDB_SOCKET"]
+        self.saved_CTDB_BASE = samba.tests.env_get_var_value('CTDB_BASE',
+                                                             allow_missing=True)
+        if self.saved_CTDB_BASE is not None:
+            del os.environ["CTDB_BASE"]
+
+        self.disabled_idx = -1
+
+        # set this to True in order to get verbose output
+        self.verbose = False
+
+        self.ctdb_prefix = samba.tests.env_get_var_value('CTDB_PREFIX')
+
+        self.cluster_share = samba.tests.env_get_var_value('CLUSTER_SHARE')
+
+        self.lp = self.get_loadparm(s3=True)
+        self.remote_domain = samba.tests.env_get_var_value('DOMAIN')
+        self.remote_user = samba.tests.env_get_var_value('USERNAME')
+        self.remote_password = samba.tests.env_get_var_value('PASSWORD')
+        self.remote_creds = Credentials()
+        self.remote_creds.guess(self.lp)
+        self.remote_creds.set_username(self.remote_user)
+        self.remote_creds.set_domain(self.remote_domain)
+        self.remote_creds.set_password(self.remote_password)
+
+        self.server_hostname = samba.tests.env_get_var_value('SERVER_HOSTNAME')
+        self.interface_group_name = samba.tests.env_get_var_value('INTERFACE_GROUP_NAME')
+
+        common_binding_args = "spnego,sign,target_hostname=%s" % (
+            self.server_hostname)
+        if self.verbose:
+            common_binding_args += ",print"
+
+        common_binding_args32 = common_binding_args
+        common_binding_args64 = common_binding_args + ",ndr64"
+
+        self.nodes = []
+        for node_idx in range(0, self.num_nodes):
+            node = {}
+
+            name_var = 'CTDB_SERVER_NAME_NODE%u' % node_idx
+            node["name"] = samba.tests.env_get_var_value(name_var)
+
+            ip_var = 'CTDB_IFACE_IP_NODE%u' % node_idx
+            node["ip"] = samba.tests.env_get_var_value(ip_var)
+
+            node["binding_string32"] = "ncacn_ip_tcp:%s[%s]" % (
+                    node["ip"], common_binding_args32)
+            node["binding_string64"] = "ncacn_ip_tcp:%s[%s]" % (
+                    node["ip"], common_binding_args64)
+            self.nodes.append(node)
+
+        self.all_registrations = None
+
+    def tearDown(self):
+        self.destroy_all_registrations()
+
+        if self.disabled_idx != -1:
+            self.enable_node(self.disabled_idx)
+
+        if self.saved_CTDB_SOCKET is not None:
+            os.environ["CTDB_SOCKET"] = self.saved_CTDB_SOCKET
+            self.saved_CTDB_SOCKET = None
+        if self.saved_CTDB_BASE is not None:
+            os.environ["CTDB_BASE"] = self.saved_CTDB_BASE
+            self.saved_CTDB_BASE = None
+
+        super().tearDown()
+
+    def call_onnode(self, nodes, cmd):
+        COMMAND = "ctdb/tests/local_daemons.sh"
+
+        argv = "%s '%s' onnode %s '%s'" % (COMMAND, self.ctdb_prefix, nodes, cmd)
+
+        try:
+            if self.verbose:
+                print("Calling: %s" % argv)
+            out = self.check_output(argv)
+        except samba.tests.BlackboxProcessError as e:
+            self.fail("Error calling [%s]: %s" % (argv, e))
+
+        out_str = get_string(out)
+        return out_str
+
+    def dump_ctdb_status_all(self):
+        for node_idx in range(0, self.num_nodes):
+            print("%s" % self.call_onnode(str(node_idx), "ctdb status"))
+
+    def disable_node(self, node_idx, dump_status=False):
+        if dump_status:
+            self.dump_ctdb_status_all()
+
+        self.assertEqual(self.disabled_idx, -1)
+        self.call_onnode(str(node_idx), "ctdb disable")
+        self.disabled_idx = node_idx
+
+        if dump_status:
+            self.dump_ctdb_status_all()
+
+    def enable_node(self, node_idx, dump_status=False):
+        if dump_status:
+            self.dump_ctdb_status_all()
+
+        self.assertEqual(self.disabled_idx, node_idx)
+        self.call_onnode(str(node_idx), "ctdb enable")
+        self.disabled_idx = -1
+
+        if dump_status:
+            self.dump_ctdb_status_all()
+
+    def call_net_witness_subcmd(self, subcmd,
+                                as_json=False,
+                                apply_to_all=False,
+                                registration=None,
+                                net_name=None,
+                                share_name=None,
+                                ip_address=None,
+                                client_computer=None,
+                                new_ip=None,
+                                new_node=None,
+                                forced_response=None):
+        COMMAND = "UID_WRAPPER_ROOT=1 bin/net witness"
+
+        argv = "%s %s" % (COMMAND, subcmd)
+        if as_json:
+            argv += " --json"
+
+        if apply_to_all:
+            argv += " --witness-apply-to-all"
+
+        if registration is not None:
+            argv += " --witness-registration='%s'" % (
+                    registration.uuid)
+
+        if net_name is not None:
+            argv += " --witness-net-name='%s'" % (net_name)
+
+        if share_name is not None:
+            argv += " --witness-share-name='%s'" % (share_name)
+
+        if ip_address is not None:
+            argv += " --witness-ip-address='%s'" % (ip_address)
+
+        if client_computer is not None:
+            argv += " --witness-client-computer-name='%s'" % (client_computer)
+
+        if new_ip is not None:
+            argv += " --witness-new-ip='%s'" % (new_ip)
+
+        if new_node is not None:
+            argv += " --witness-new-node='%s'" % (new_node)
+
+        if forced_response:
+            argv += " --witness-forced-response='%s'" % (forced_response)
+
+        try:
+            if self.verbose:
+                print("Calling: %s" % argv)
+            out = self.check_output(argv)
+        except samba.tests.BlackboxProcessError as e:
+            self.fail("Error calling [%s]: %s" % (argv, e))
+
+        out_str = get_string(out)
+        if not as_json:
+            return out_str
+
+        json_out = json.loads(out_str)
+        return json_out
+
+    @classmethod
+    def _define_GetInterfaceList_test(cls, conn_idx, disable_idx, ndr64=False):
+        if disable_idx != -1:
+            disable_name = "%u_disabled" % disable_idx
+        else:
+            disable_name = "all_enabled"
+
+        if ndr64:
+            ndr_name = "NDR64"
+        else:
+            ndr_name = "NDR32"
+
+        name = "Node%u_%s_%s" % (conn_idx, disable_name, ndr_name)
+        args = {
+            'conn_idx': conn_idx,
+            'disable_idx': disable_idx,
+            'ndr64': ndr64,
+        }
+        cls.generate_dynamic_test('test_GetInterfaceList', name, args)
+
+    def _test_GetInterfaceList_with_args(self, args):
+        conn_idx = args.pop('conn_idx')
+        disable_idx = args.pop('disable_idx')
+        ndr64 = args.pop('ndr64')
+        self.assertEqual(len(args.keys()), 0)
+
+        conn_node = self.nodes[conn_idx]
+        if ndr64:
+            binding_string = conn_node["binding_string64"]
+        else:
+            binding_string = conn_node["binding_string32"]
+
+        if disable_idx != -1:
+            self.disable_node(disable_idx)
+
+        conn = witness.witness(binding_string, self.lp, self.remote_creds)
+        interface_list = conn.GetInterfaceList()
+
+        if disable_idx != -1:
+            self.enable_node(disable_idx)
+
+        self.assertIsNotNone(interface_list)
+        self.assertEqual(interface_list.num_interfaces, len(self.nodes))
+        for idx in range(0, interface_list.num_interfaces):
+            iface = interface_list.interfaces[idx]
+            node = self.nodes[idx]
+
+            expected_flags = 0
+            expected_flags |= witness.WITNESS_INFO_IPv4_VALID
+            if conn_idx != idx:
+                expected_flags |= witness.WITNESS_INFO_WITNESS_IF
+
+            if disable_idx == idx:
+                expected_state = witness.WITNESS_STATE_UNAVAILABLE
+            else:
+                expected_state = witness.WITNESS_STATE_AVAILABLE
+
+            self.assertIsNotNone(iface.group_name)
+            self.assertEqual(iface.group_name, self.interface_group_name)
+
+            self.assertEqual(iface.version, witness.WITNESS_V2)
+            self.assertEqual(iface.state, expected_state)
+
+            self.assertIsNotNone(iface.ipv4)
+            self.assertEqual(iface.ipv4, node["ip"])
+
+            self.assertIsNotNone(iface.ipv6)
+            self.assertEqual(iface.ipv6,
+                    "0000:0000:0000:0000:0000:0000:0000:0000")
+
+            self.assertEqual(iface.flags, expected_flags)
+
+    def assertResourceChanges(self, response, expected_resource_changes):
+        self.assertIsNotNone(response)
+        self.assertEqual(response.type,
+                witness.WITNESS_NOTIFY_RESOURCE_CHANGE)
+        self.assertEqual(response.num, len(expected_resource_changes))
+        self.assertEqual(len(response.messages), len(expected_resource_changes))
+        for ri in range(0, len(expected_resource_changes)):
+            expected_resource_change = expected_resource_changes[ri]
+            resource_change = response.messages[ri]
+            self.assertIsNotNone(resource_change)
+
+            expected_type = witness.WITNESS_RESOURCE_STATE_UNAVAILABLE
+            expected_type = expected_resource_change.get('type', expected_type)
+
+            expected_name = expected_resource_change.get('name')
+
+            self.assertEqual(resource_change.type, expected_type)
+            self.assertIsNotNone(resource_change.name)
+            self.assertEqual(resource_change.name, expected_name)
+
+    def assertResourceChange(self, response, expected_type, expected_name):
+        expected_resource_change = {
+            'type': expected_type,
+            'name': expected_name,
+        }
+        expected_resource_changes = [expected_resource_change]
+        self.assertResourceChanges(response, expected_resource_changes)
+
+    def assertGenericIpLists(self, response, expected_type, expected_ip_lists):
+        self.assertIsNotNone(response)
+        self.assertEqual(response.type, expected_type)
+        self.assertEqual(response.num, len(expected_ip_lists))
+        self.assertEqual(len(response.messages), len(expected_ip_lists))
+        for li in range(0, len(expected_ip_lists)):
+
+            expected_ip_list = expected_ip_lists[li]
+            ip_list = response.messages[li]
+            self.assertIsNotNone(ip_list)
+            self.assertEqual(ip_list.num, len(expected_ip_list))
+
+            for i in range(0, len(expected_ip_list)):
+                ip_info = ip_list.addr[i]
+
+                expected_flags = 0
+                expected_flags |= witness.WITNESS_IPADDR_V4
+                expected_flags |= witness.WITNESS_IPADDR_ONLINE
+                expected_flags = expected_ip_list[i].get('flags', expected_flags)
+
+                expected_ipv4 = '0.0.0.0'
+                expected_ipv4 = expected_ip_list[i].get('ipv4', expected_ipv4)
+
+                expected_ipv6 = '0000:0000:0000:0000:0000:0000:0000:0000'
+                expected_ipv6 = expected_ip_list[i].get('ipv6', expected_ipv6)
+
+                self.assertEqual(ip_info.flags, expected_flags)
+
+                self.assertIsNotNone(ip_info.ipv4)
+                self.assertEqual(ip_info.ipv4, expected_ipv4)
+
+                self.assertIsNotNone(ip_info.ipv6)
+                self.assertEqual(ip_info.ipv6, expected_ipv6)
+
+    @classmethod
+    def _define_ResourceChangeCTDB_tests(cls, conn_idx, monitor_idx, ndr64=False):
+        if ndr64:
+            ndr_name = "NDR64"
+        else:
+            ndr_name = "NDR32"
+
+        name_suffix = "WNode%u_RNode%u_%s" % (conn_idx, monitor_idx, ndr_name)
+        base_args = {
+            'conn_idx': conn_idx,
+            'monitor_idx': monitor_idx,
+            'ndr64': ndr64,
+        }
+
+        name = "v1_disabled_after_%s" % name_suffix
+        args = base_args.copy()
+        args['reg_v1'] = True
+        args['disable_after_reg'] = True
+        args['explicit_unregister'] = False
+        cls.generate_dynamic_test('test_ResourceChangeCTDB', name, args)
+
+        name = "v1_disabled_after_enabled_after_%s" % name_suffix
+        args = base_args.copy()
+        args['reg_v1'] = True
+        args['disable_after_reg'] = True
+        args['enable_after_reg'] = True
+        args['explicit_unregister'] = False
+        cls.generate_dynamic_test('test_ResourceChangeCTDB', name, args)
+
+        name = "v2_disabled_before_enable_after_%s" % name_suffix
+        args = base_args.copy()
+        args['disable_before_reg'] = True
+        args['enable_after_reg'] = True
+        args['wait_for_timeout'] = True
+        args['timeout'] = 6
+        cls.generate_dynamic_test('test_ResourceChangeCTDB', name, args)
+
+        name = "v2_disabled_after_%s" % name_suffix
+        args = base_args.copy()
+        args['disable_after_reg'] = True
+        args['wait_for_not_found'] = True
+        args['explicit_unregister'] = False
+        cls.generate_dynamic_test('test_ResourceChangeCTDB', name, args)
+
+        name = "v2_disabled_after_enabled_after_%s" % name_suffix
+        args = base_args.copy()
+        args['disable_after_reg'] = True
+        args['enable_after_reg'] = True
+        args['wait_for_not_found'] = True
+        args['explicit_unregister'] = False
+        cls.generate_dynamic_test('test_ResourceChangeCTDB', name, args)
+


-- 
Samba Shared Repository



More information about the samba-cvs mailing list