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 <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Fri Jan 26 18:04:10 UTC 2024 on atb-devel-224 commit 941f53f0c937fa75562183e9a4e1c95adf5d9524 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 946bf100685da22cebbc38bcf96139c02ea35921 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 8a643fea95c2d7d4f6709a10ff798bf3f9e210aa Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 8536a217922f7a2c5545b8f87084d08ea955ac61 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 290ef547d869100bdea42784b8a8783085eed805 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit df3b5f93390ce154c761b6337a3acad3ef254cc8 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 4fba5bcaad7b54cb840fa006a4f6d0477980d9b2 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit b722dc74f86038eeaf3de875b5ca2cf2dadfe7a7 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 0744d55be03331808c99c159e7d8ca02b5323781 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 3e70b31f013b7835b1e9da19ecb7b6977433b48c Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 46fdeca696e3fc308d8978ae6a2fc62bd13c5dcf Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit fcc8e0978b61ea28be9c96ab14798ed6a97b21c3 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit a9829ce6cf3a8ca745bbf8ceceb1566d2dc17dce Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit b17e090e7c1b864eb6e8a9663c6145fb97d91e0f Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit b3c51c4b825b2886e789a34f7df2469f0e0742ce Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit ea1ec424ad02a79b4e29453bc50d4e631251f2ae Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 3ede69552ca7b06438a46f52d04683d655f3a180 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 2f9dfaae4481cc3e9c907a774b5ef57461cbe879 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 15b17f1fffc45d624352a81c485c82d9e2d491eb Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jan 12 17:06:05 2024 +0100 selftest/Samba3: remove unused variable in setup_clusteredmember Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit bc2a77373a0a786fa8ea13a237a04850a5f5f0d7 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit cb1d711e25ab62cc4950561a94abc9bca0363d2d Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 85f30bcf0b621356fcfb39b447dce6ff7d6eb5fc Author: Stefan Metzmacher <me...@samba.org> Date: Wed Aug 9 12:18:05 2023 +0200 s3:rpc_server: add basic rpcd_witness template Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 9083f49e767409a34c629242086746622684d365 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit 3106709c8911d3684d0e3c6dea939df5ce558c6d Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit ceda79b6cc0857333ce2fdea464a7b9df8b691e6 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit f21e38006447833c114ac6477aefcfb800a7c150 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> commit b9bd7e89f28b2ed5f32c8c1eba7b9b7d6b8b8e29 Author: Stefan Metzmacher <me...@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 <me...@samba.org> Reviewed-by: Günther Deschner <g...@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 <me...@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 + +@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