[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Wed Nov 29 04:16:02 UTC 2023
The branch, master has been updated
via e2651628844 tests: claims blackbox: add device and server silo restrictions test
via 834fc223e2e python: tests: claims blackbox tests use ntstatus constants
via 0d907a02141 tests: claims blackbox: use raw strings rather than escaping \
via dc74cabaa4d tests: claims: blackbox device tests
via 64212a371be selftest: Run samba.tests.gensec in an enviroment build also with MIT Krb5
via c49fd98ed7a s4-auth/kerberos: Use FAST credentials for armor if specified in cli_credentials
via 0293d233bf2 python/tests: Add test for creds.set_krb5_fast_credentials()
via ebdb1f6b43a python/tests: Lock in key-word arguments as key-word only in samba.tests.gssapi
via 61b0397de20 python/tests: Import samba.gensec, not gensec
via cc2c9b2a1e7 auth/credentials: Add Python bindings for association of a connection for FAST
via bed1893a75e auth/credentials: Add API to allow requesting a Kerberos ticket to be protected with FAST
via dbb682f5fac build: Add build time detection for the MIT FAST ccache API
via 6222d572eec third_party/heimdal: Provide krb5_init_creds_opt_set_fast_ccache() and krb5_init_creds_opt_set_fast_flags() (import lorikeet-heimdal-202311290114 (commit 4c8517e161396330c76240bf09609a0dd5f9ea20))
from a757a51a26f libcli/security: note suboptimality of conditional ACE Contains operators
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit e2651628844d6a4262de4093770d958fc1ee4535
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Tue Nov 28 13:05:33 2023 +1300
tests: claims blackbox: add device and server silo restrictions test
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Wed Nov 29 04:15:27 UTC 2023 on atb-devel-224
commit 834fc223e2e3a9c07e1df57cf7f4ae39afb13db2
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Wed Nov 29 11:37:42 2023 +1300
python: tests: claims blackbox tests use ntstatus constants
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 0d907a021415d1a94469faf3fcd301022979fefc
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Tue Nov 28 12:46:53 2023 +1300
tests: claims blackbox: use raw strings rather than escaping \
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit dc74cabaa4d7ec52c9d33b19aaafe4272de249a5
Author: Rob van der Linde <rob at catalyst.net.nz>
Date: Tue Nov 21 16:27:09 2023 +1300
tests: claims: blackbox device tests
Signed-off-by: Rob van der Linde <rob at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 64212a371be2c262338d604944cc73b397913fdb
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Nov 28 17:07:15 2023 +1300
selftest: Run samba.tests.gensec in an enviroment build also with MIT Krb5
We would like confidence that the FAST hooks work with both implementations.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit c49fd98ed7a547fe37b354d93671a9d2f05c8b34
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Nov 20 14:12:19 2023 +1300
s4-auth/kerberos: Use FAST credentials for armor if specified in cli_credentials
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 0293d233bf206fabe1e209548c0c44d511f9e73f
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Nov 20 12:17:57 2023 +1300
python/tests: Add test for creds.set_krb5_fast_credentials()
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit ebdb1f6b43af4141bf598f6dffdc47df94401336
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Nov 20 12:42:15 2023 +1300
python/tests: Lock in key-word arguments as key-word only in samba.tests.gssapi
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 61b0397de2031813bdcf35a742eeba2dc9c5f9b9
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Nov 20 13:02:21 2023 +1300
python/tests: Import samba.gensec, not gensec
This allows this function to be used by gensec.py (a test) without collision.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit cc2c9b2a1e72802675a6e0494679774b920abe8c
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Nov 20 12:16:04 2023 +1300
auth/credentials: Add Python bindings for association of a connection for FAST
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit bed1893a75e7bf5e7b607fb1bc5712e3175d17a9
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri Nov 17 17:41:53 2023 +1300
auth/credentials: Add API to allow requesting a Kerberos ticket to be protected with FAST
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit dbb682f5fac1094bfd5ad70c35bfe9e9c877b935
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Nov 28 13:51:07 2023 +1300
build: Add build time detection for the MIT FAST ccache API
This will allow us to link against an older system Heimdal.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
commit 6222d572eecb958174e7795e2dc8143188c6ae2e
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Nov 29 14:16:16 2023 +1300
third_party/heimdal: Provide krb5_init_creds_opt_set_fast_ccache() and krb5_init_creds_opt_set_fast_flags() (import lorikeet-heimdal-202311290114 (commit 4c8517e161396330c76240bf09609a0dd5f9ea20))
It is easier for external callers to manipulate the krb5_get_init_creds_opt
(via the helpers) as this is passed down from higher up than the krb5_init_creds_context.
And just as importantly, alignment with MIT makes end-user callers happier.
Finally, this resolves the ambiguity as to which layer owns the
krb5_ccache, because now we match the MIT behaviour the init_creds code
re-opens a private copy inside libkrb5, meaning the caller closes the
cache it opened, rather than handing it over to the library.
(The unrelated changes are fixes to the test_pac test, also included in this import,
but in distinct lorikeet-heimdal commits, to allow it to compile)
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
-----------------------------------------------------------------------
Summary of changes:
auth/credentials/credentials.h | 12 +
auth/credentials/credentials_internal.h | 6 +
auth/credentials/credentials_krb5.c | 51 +++-
auth/credentials/pycredentials.c | 94 +++++++
python/samba/tests/__init__.py | 4 +-
python/samba/tests/blackbox/claims.py | 305 ++++++++++++++++++++-
python/samba/tests/gensec.py | 39 ++-
source4/auth/kerberos/kerberos_credentials.h | 1 +
source4/auth/kerberos/kerberos_util.c | 47 ++++
source4/selftest/tests.py | 6 +-
third_party/heimdal/kdc/kdc-tester.c | 16 +-
third_party/heimdal/kuser/kinit.c | 50 ++--
third_party/heimdal/lib/krb5/init_creds.c | 46 ++++
third_party/heimdal/lib/krb5/init_creds_pw.c | 19 ++
third_party/heimdal/lib/krb5/krb5.h | 2 +
third_party/heimdal/lib/krb5/krb5_locl.h | 37 +--
.../heimdal/lib/krb5/libkrb5-exports.def.in | 3 +
third_party/heimdal/lib/krb5/test_pac.c | 38 ++-
third_party/heimdal/lib/krb5/version-script.map | 3 +
third_party/heimdal_build/wscript_configure | 2 +
wscript_configure_system_heimdal | 7 +
wscript_configure_system_mitkrb5 | 2 +
22 files changed, 720 insertions(+), 70 deletions(-)
Changeset truncated at 500 lines:
diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h
index c3a048ecc8d..3ad40267e2e 100644
--- a/auth/credentials/credentials.h
+++ b/auth/credentials/credentials.h
@@ -351,4 +351,16 @@ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
const char *salt,
DATA_BLOB *aes_256);
+/**
+ * Kerberos FAST handling
+ */
+
+NTSTATUS cli_credentials_set_krb5_fast_armor_credentials(struct cli_credentials *creds,
+ struct cli_credentials *armor_creds,
+ bool require_fast_armor);
+
+struct cli_credentials *cli_credentials_get_krb5_fast_armor_credentials(struct cli_credentials *creds);
+
+bool cli_credentials_get_krb5_require_fast_armor(struct cli_credentials *creds);
+
#endif /* __CREDENTIALS_H__ */
diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h
index 966926919b0..cda361e1dd0 100644
--- a/auth/credentials/credentials_internal.h
+++ b/auth/credentials/credentials_internal.h
@@ -131,6 +131,12 @@ struct cli_credentials {
enum smb_signing_setting ipc_signing_state;
enum smb_encryption_setting encryption_state;
+
+ /* Credentials to use for FAST */
+ struct cli_credentials *krb5_fast_armor_credentials;
+
+ /* Should we require FAST? */
+ bool krb5_require_fast_armor;
};
#endif /* __CREDENTIALS_INTERNAL_H__ */
diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index 7d7d0248cb4..4463401a767 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -726,7 +726,14 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred,
return ret;
}
- ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, event_ctx, (*ccc)->ccache, &obtained, error_string);
+ ret = kinit_to_ccache(cred,
+ cred,
+ (*ccc)->smb_krb5_context,
+ lp_ctx,
+ event_ctx,
+ (*ccc)->ccache,
+ &obtained,
+ error_string);
if (ret) {
return ret;
}
@@ -1125,7 +1132,7 @@ static int cli_credentials_shallow_ccache(struct cli_credentials *cred)
_PUBLIC_ struct cli_credentials *cli_credentials_shallow_copy(TALLOC_CTX *mem_ctx,
struct cli_credentials *src)
{
- struct cli_credentials *dst;
+ struct cli_credentials *dst, *armor_credentials;
int ret;
dst = talloc(mem_ctx, struct cli_credentials);
@@ -1135,6 +1142,14 @@ _PUBLIC_ struct cli_credentials *cli_credentials_shallow_copy(TALLOC_CTX *mem_ct
*dst = *src;
+ if (dst->krb5_fast_armor_credentials != NULL) {
+ armor_credentials = talloc_reference(dst, dst->krb5_fast_armor_credentials);
+ if (armor_credentials == NULL) {
+ TALLOC_FREE(dst);
+ return NULL;
+ }
+ }
+
ret = cli_credentials_shallow_ccache(dst);
if (ret != 0) {
TALLOC_FREE(dst);
@@ -1532,3 +1547,35 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
return 0;
}
+
+/* This take a reference to the armor credentials to ensure the lifetime is appropriate */
+
+NTSTATUS cli_credentials_set_krb5_fast_armor_credentials(struct cli_credentials *creds,
+ struct cli_credentials *armor_creds,
+ bool require_fast_armor)
+{
+ talloc_unlink(creds, creds->krb5_fast_armor_credentials);
+ if (armor_creds == NULL) {
+ creds->krb5_fast_armor_credentials = NULL;
+ return NT_STATUS_OK;
+ }
+
+ creds->krb5_fast_armor_credentials = talloc_reference(creds, armor_creds);
+ if (creds->krb5_fast_armor_credentials == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ creds->krb5_require_fast_armor = require_fast_armor;
+
+ return NT_STATUS_OK;
+}
+
+struct cli_credentials *cli_credentials_get_krb5_fast_armor_credentials(struct cli_credentials *creds)
+{
+ return creds->krb5_fast_armor_credentials;
+}
+
+bool cli_credentials_get_krb5_require_fast_armor(struct cli_credentials *creds)
+{
+ return creds->krb5_require_fast_armor;
+}
diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c
index 3687050bde9..8e7d8ae7b56 100644
--- a/auth/credentials/pycredentials.c
+++ b/auth/credentials/pycredentials.c
@@ -41,6 +41,11 @@ static PyObject *py_creds_new(PyTypeObject *type, PyObject *args, PyObject *kwar
return pytalloc_steal(type, cli_credentials_init(NULL));
}
+static PyObject *PyCredentials_from_cli_credentials(struct cli_credentials *creds)
+{
+ return pytalloc_reference(&PyCredentials, creds);
+}
+
static PyObject *py_creds_get_username(PyObject *self, PyObject *unused)
{
struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
@@ -1219,6 +1224,74 @@ static PyObject *py_creds_set_smb_encryption(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+static PyObject *py_creds_get_krb5_fast_armor_credentials(PyObject *self, PyObject *unused)
+{
+ struct cli_credentials *creds = NULL;
+ struct cli_credentials *fast_creds = NULL;
+
+ creds = PyCredentials_AsCliCredentials(self);
+ if (creds == NULL) {
+ PyErr_Format(PyExc_TypeError, "Credentials expected");
+ return NULL;
+ }
+
+ fast_creds = cli_credentials_get_krb5_fast_armor_credentials(creds);
+ if (fast_creds == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ return PyCredentials_from_cli_credentials(fast_creds);
+}
+
+static PyObject *py_creds_set_krb5_fast_armor_credentials(PyObject *self, PyObject *args)
+{
+ struct cli_credentials *creds = NULL;
+ PyObject *pyfast_creds;
+ struct cli_credentials *fast_creds = NULL;
+ int fast_armor_required = 0;
+ NTSTATUS status;
+
+ creds = PyCredentials_AsCliCredentials(self);
+ if (creds == NULL) {
+ PyErr_Format(PyExc_TypeError, "Credentials expected");
+ return NULL;
+ }
+ if (!PyArg_ParseTuple(args, "Op", &pyfast_creds, &fast_armor_required)) {
+ return NULL;
+ }
+ if (pyfast_creds == Py_None) {
+ fast_creds = NULL;
+ } else {
+ fast_creds = PyCredentials_AsCliCredentials(pyfast_creds);
+ if (fast_creds == NULL) {
+ PyErr_Format(PyExc_TypeError, "Credentials expected");
+ return NULL;
+ }
+ }
+
+ status = cli_credentials_set_krb5_fast_armor_credentials(creds,
+ fast_creds,
+ fast_armor_required);
+
+ PyErr_NTSTATUS_IS_ERR_RAISE(status);
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_creds_get_krb5_require_fast_armor(PyObject *self, PyObject *unused)
+{
+ bool krb5_fast_armor_required;
+ struct cli_credentials *creds = NULL;
+
+ creds = PyCredentials_AsCliCredentials(self);
+ if (creds == NULL) {
+ PyErr_Format(PyExc_TypeError, "Credentials expected");
+ return NULL;
+ }
+
+ krb5_fast_armor_required = cli_credentials_get_krb5_require_fast_armor(creds);
+ return PyBool_FromLong(krb5_fast_armor_required);
+}
+
static PyMethodDef py_creds_methods[] = {
{
.ml_name = "get_username",
@@ -1558,6 +1631,27 @@ static PyMethodDef py_creds_methods[] = {
.ml_meth = py_creds_set_smb_encryption,
.ml_flags = METH_VARARGS,
},
+ {
+ .ml_name = "get_krb5_fast_armor_credentials",
+ .ml_meth = py_creds_get_krb5_fast_armor_credentials,
+ .ml_flags = METH_NOARGS,
+ .ml_doc = "S.get_krb5_fast_armor_credentials() -> Credentials\n"
+ "Get the Kerberos FAST credentials set on this credentials object"
+ },
+ {
+ .ml_name = "set_krb5_fast_armor_credentials",
+ .ml_meth = py_creds_set_krb5_fast_armor_credentials,
+ .ml_flags = METH_VARARGS,
+ .ml_doc = "S.set_krb5_fast_armor_credentials(credentials, required) -> None\n"
+ "Set Kerberos FAST credentials for this credentials object, and if FAST armoring must be used."
+ },
+ {
+ .ml_name = "get_krb5_require_fast_armor",
+ .ml_meth = py_creds_get_krb5_require_fast_armor,
+ .ml_flags = METH_NOARGS,
+ .ml_doc = "S.get_krb5_fast_armor() -> bool\n"
+ "Indicate if Kerberos FAST armor is required"
+ },
{ .ml_name = NULL }
};
diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py
index 5ba18c9fdcb..9981e1390a2 100644
--- a/python/samba/tests/__init__.py
+++ b/python/samba/tests/__init__.py
@@ -26,13 +26,13 @@ import samba
from samba import param
from samba import credentials
from samba.credentials import Credentials
-from samba import gensec
import subprocess
import sys
import unittest
import re
from enum import IntEnum, unique
import samba.auth
+import samba.gensec
import samba.dcerpc.base
from random import randint
from random import SystemRandom
@@ -256,7 +256,7 @@ class TestCase(unittest.TestCase):
c.set_realm(template.get_realm())
c.set_workstation(template.get_workstation())
c.set_gensec_features(c.get_gensec_features()
- | gensec.FEATURE_SEAL)
+ | samba.gensec.FEATURE_SEAL)
c.set_kerberos_state(kerberos_state)
if simple_bind_dn:
c.set_bind_dn(simple_bind_dn)
diff --git a/python/samba/tests/blackbox/claims.py b/python/samba/tests/blackbox/claims.py
index 135595eec24..1c6cddcec24 100755
--- a/python/samba/tests/blackbox/claims.py
+++ b/python/samba/tests/blackbox/claims.py
@@ -27,6 +27,7 @@ from samba import NTSTATUSError
from samba.auth import AuthContext
from samba.credentials import Credentials
from samba.gensec import FEATURE_SEAL, Security
+from samba.ntstatus import NT_STATUS_LOGON_FAILURE, NT_STATUS_UNSUCCESSFUL
from samba.tests import BlackboxTestCase
SERVER = os.environ["SERVER"]
@@ -46,6 +47,286 @@ class ClaimsSupportTests(BlackboxTestCase):
order after the tests finishes, they don't execute straight away.
"""
+ def test_device_group_restrictions(self):
+ client_password = "T3stPassword0nly"
+ target_password = "T3stC0mputerPassword"
+ device_password = "T3stD3vicePassword"
+
+ # Create target computer.
+ self.check_run("computer create claims-server")
+ self.addCleanup(self.run_command, "computer delete claims-server")
+ self.check_run(rf"user setpassword claims-server\$ --newpassword={target_password}")
+
+ # Create device computer.
+ self.check_run("computer create claims-device")
+ self.addCleanup(self.run_command, "computer delete claims-device")
+ self.check_run(rf"user setpassword claims-device\$ --newpassword={device_password}")
+
+ # Create a user.
+ self.check_run(f"user create claimstestuser {client_password}")
+ self.addCleanup(self.run_command, "user delete claimstestuser")
+
+ # Create an authentication policy.
+ self.check_run("domain auth policy create --enforce --name=device-restricted-users-pol")
+ self.addCleanup(self.run_command,
+ "domain auth policy delete --name=device-restricted-users-pol")
+
+ self.check_run("group add allowed-devices")
+ self.addCleanup(self.run_command, "group delete allowed-devices")
+
+ # Set allowed to authenticate from.
+ self.check_run(f"domain auth policy modify --name=device-restricted-users-pol "
+ "--user-allowed-to-authenticate-from-device-group=allowed-devices")
+
+ self.check_run("user auth policy assign claimstestuser --policy=device-restricted-users-pol")
+
+ with self.assertRaises(NTSTATUSError) as error:
+ self.verify_access(
+ client_username="claimstestuser",
+ client_password=client_password,
+ target_hostname="claims-server",
+ target_username="claims-server",
+ target_password=target_password,
+ device_username="claims-device",
+ device_password=device_password,
+ )
+
+ self.assertEqual(error.exception.args[0], NT_STATUS_LOGON_FAILURE)
+ self.assertEqual(
+ error.exception.args[1],
+ "The attempted logon is invalid. This is either due to a "
+ "bad username or authentication information.")
+
+ self.check_run("group addmembers allowed-devices claims-device")
+
+ self.verify_access(
+ client_username="claimstestuser",
+ client_password=client_password,
+ target_hostname="claims-server",
+ target_username="claims-server",
+ target_password=target_password,
+ device_username="claims-device",
+ device_password=device_password,
+ )
+
+ def test_device_silo_restrictions(self):
+ client_password = "T3stPassword0nly"
+ target_password = "T3stC0mputerPassword"
+ device_password = "T3stD3vicePassword"
+
+ # Create target computer.
+ self.check_run("computer create claims-server")
+ self.addCleanup(self.run_command, "computer delete claims-server")
+ self.check_run(rf"user setpassword claims-server\$ --newpassword={target_password}")
+
+ # Create device computer.
+ self.check_run("computer create claims-device")
+ self.addCleanup(self.run_command, "computer delete claims-device")
+ self.check_run(rf"user setpassword claims-device\$ --newpassword={device_password}")
+
+ # Create a user.
+ self.check_run(f"user create claimstestuser {client_password}")
+ self.addCleanup(self.run_command, "user delete claimstestuser")
+
+ # Create an authentication policy.
+ self.check_run("domain auth policy create --enforce --name=allowed-devices-only-pol")
+ self.addCleanup(self.run_command,
+ "domain auth policy delete --name=allowed-devices-only-pol")
+
+ # Create an authentication silo.
+ self.check_run("domain auth silo create --enforce --name=allowed-devices-only-silo "
+ "--user-authentication-policy=allowed-devices-only-pol "
+ "--computer-authentication-policy=allowed-devices-only-pol "
+ "--service-authentication-policy=allowed-devices-only-pol")
+ self.addCleanup(self.run_command,
+ "domain auth silo delete --name=allowed-devices-only-silo")
+
+ # Set allowed to authenticate from (where the login can happen) and to
+ # (server requires silo that in term has this rule, so knows the user
+ # was required to authenticate from).
+ self.check_run(f"domain auth policy modify --name=allowed-devices-only-pol "
+ "--user-allowed-to-authenticate-from-device-silo=allowed-devices-only-silo")
+
+ # Grant access to silo.
+ self.check_run(r"domain auth silo member grant --name=allowed-devices-only-silo --member=claims-device\$")
+ self.check_run("domain auth silo member grant --name=allowed-devices-only-silo --member=claimstestuser")
+
+ # However with nothing assigned, allow-by-default still applies
+ self.verify_access(
+ client_username="claimstestuser",
+ client_password=client_password,
+ target_hostname="claims-server",
+ target_username="claims-server",
+ target_password=target_password,
+ )
+
+ # Show that adding a FAST armor from the device doesn't change
+ # things either way
+ self.verify_access(
+ client_username="claimstestuser",
+ client_password=client_password,
+ target_hostname="claims-server",
+ target_username="claims-server",
+ target_password=target_password,
+ device_username="claims-device",
+ device_password=device_password,
+ )
+
+ # Assign silo to the user.
+ self.check_run("user auth silo assign claimstestuser --silo=allowed-devices-only-silo")
+
+ # We fail, as the KDC now requires the silo but the client is not using an approved device
+ with self.assertRaises(NTSTATUSError) as error:
+ self.verify_access(
+ client_username="claimstestuser",
+ client_password=client_password,
+ target_hostname="claims-server",
+ target_username="claims-server",
+ target_password=target_password,
+ device_username="claims-device",
+ device_password=device_password,
+ )
+
+ self.assertEqual(error.exception.args[0], NT_STATUS_UNSUCCESSFUL)
+ self.assertIn(
+ "The requested operation was unsuccessful.",
+ error.exception.args[1])
+
+ # Assign silo to the device.
+ self.check_run(r"user auth silo assign claims-device\$ --silo=allowed-devices-only-silo")
+
+ self.verify_access(
+ client_username="claimstestuser",
+ client_password=client_password,
+ target_hostname="claims-server",
+ target_username="claims-server",
+ target_password=target_password,
+ device_username="claims-device",
+ device_password=device_password,
+ )
+
+ def test_device_and_server_silo_restrictions(self):
+ client_password = "T3stPassword0nly"
+ target_password = "T3stC0mputerPassword"
+ device_password = "T3stD3vicePassword"
+
+ # Create target computer.
+ self.check_run("computer create claims-server")
+ self.addCleanup(self.run_command, "computer delete claims-server")
+ self.check_run(rf"user setpassword claims-server\$ --newpassword={target_password}")
+
+ # Create device computer.
+ self.check_run("computer create claims-device")
+ self.addCleanup(self.run_command, "computer delete claims-device")
+ self.check_run(rf"user setpassword claims-device\$ --newpassword={device_password}")
+
+ # Create a user.
+ self.check_run(f"user create claimstestuser {client_password}")
+ self.addCleanup(self.run_command, "user delete claimstestuser")
+
+ # Create an authentication policy.
+ self.check_run("domain auth policy create --enforce --name=allowed-devices-only-pol")
+ self.addCleanup(self.run_command,
+ "domain auth policy delete --name=allowed-devices-only-pol")
+
+ # Create an authentication silo.
+ self.check_run("domain auth silo create --enforce --name=allowed-devices-only-silo "
+ "--user-authentication-policy=allowed-devices-only-pol "
+ "--computer-authentication-policy=allowed-devices-only-pol "
+ "--service-authentication-policy=allowed-devices-only-pol")
+ self.addCleanup(self.run_command,
+ "domain auth silo delete --name=allowed-devices-only-silo")
+
+ # Set allowed to authenticate from (where the login can happen) and to
+ # (server requires silo that in term has this rule, so knows the user
+ # was required to authenticate from).
+ # If we assigned services to the silo we would need to add
+ # --service-allowed-to-authenticate-to/from options as well.
+ # Likewise, if there are services running in user accounts, we need
+ # --user-allowed-to-authenticate-to
+ self.check_run(f"domain auth policy modify --name=allowed-devices-only-pol "
+ "--user-allowed-to-authenticate-from-device-silo=allowed-devices-only-silo "
+ "--computer-allowed-to-authenticate-to-by-silo=allowed-devices-only-silo")
+
+ # Grant access to silo.
+ self.check_run(r"domain auth silo member grant --name=allowed-devices-only-silo --member=claims-device\$")
+ self.check_run(r"domain auth silo member grant --name=allowed-devices-only-silo --member=claims-server\$")
+ self.check_run("domain auth silo member grant --name=allowed-devices-only-silo --member=claimstestuser")
+
+ # However with nothing assigned, allow-by-default still applies
+ self.verify_access(
+ client_username="claimstestuser",
+ client_password=client_password,
+ target_hostname="claims-server",
+ target_username="claims-server",
+ target_password=target_password,
+ )
+
+ # Show that adding a FAST armor from the device doesn't change
+ # things either way
+ self.verify_access(
+ client_username="claimstestuser",
--
Samba Shared Repository
More information about the samba-cvs
mailing list