From: Andrew Bartlett Date: Thu, 14 Sep 2023 10:09:50 +0000 (+1200) Subject: libcli/security: Pass in claims evaluation state when building any security token X-Git-Tag: tevent-0.16.0~430 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2cc29d132b9f99417e8a522c97571438ca51e5a;p=thirdparty%2Fsamba.git libcli/security: Pass in claims evaluation state when building any security token Signed-off-by: Andrew Bartlett Reviewed-by: Douglas Bagnall --- diff --git a/libcli/security/security_token.c b/libcli/security/security_token.c index 17d6c73abbb..95bf68e8e24 100644 --- a/libcli/security/security_token.c +++ b/libcli/security/security_token.c @@ -22,6 +22,8 @@ */ #include "replace.h" +#include +#include "lib/util/talloc_stack.h" #include "lib/util/debug.h" #include "lib/util/fault.h" #include "libcli/security/security_token.h" @@ -31,10 +33,13 @@ /* return a blank security token */ -struct security_token *security_token_initialise(TALLOC_CTX *mem_ctx) +struct security_token *security_token_initialise(TALLOC_CTX *mem_ctx, + enum claims_evaluation_control evaluate_claims) { struct security_token *st = talloc_zero( mem_ctx, struct security_token); + st->evaluate_claims = evaluate_claims; + return st; } diff --git a/libcli/security/security_token.h b/libcli/security/security_token.h index bb8795919e9..1c9b2402853 100644 --- a/libcli/security/security_token.h +++ b/libcli/security/security_token.h @@ -36,7 +36,8 @@ /* return a blank security token */ -struct security_token *security_token_initialise(TALLOC_CTX *mem_ctx); +struct security_token *security_token_initialise(TALLOC_CTX *mem_ctx, + enum claims_evaluation_control evaluate_claims); /**************************************************************************** prints a struct security_token to debug output. diff --git a/python/samba/tests/token_factory.py b/python/samba/tests/token_factory.py index 63777ea6928..cf5e490b621 100644 --- a/python/samba/tests/token_factory.py +++ b/python/samba/tests/token_factory.py @@ -229,7 +229,7 @@ def token(sids=None, **kwargs): else: raise TypeError(f"{k} is an invalid keyword argument") - t = security.token() + t = security.token(evaluate_claims=security.CLAIMS_EVALUATION_ALWAYS) for k, v in norm_args.items(): setattr(t, k, v) diff --git a/source3/auth/token_util.c b/source3/auth/token_util.c index f508dfd3a86..aac5749a815 100644 --- a/source3/auth/token_util.c +++ b/source3/auth/token_util.c @@ -307,6 +307,26 @@ NTSTATUS get_user_sid_info3_and_extra(const struct netr_SamInfo3 *info3, return NT_STATUS_OK; } +static struct security_token *init_local_nt_token(TALLOC_CTX *mem_ctx) +{ + /* + * We do not have a method to populate the claims into this + * buffer in the source3/ stack. When that changes, we will + * instead this optional based on lp_acl_claims_evaluation() + */ + + struct security_token *result + = security_token_initialise(mem_ctx, + CLAIMS_EVALUATION_NEVER); + + if (result == NULL) { + DBG_ERR("talloc failed for security_token\n"); + return NULL; + } + + return result; +} + NTSTATUS create_local_nt_token_from_info3(TALLOC_CTX *mem_ctx, bool is_guest, const struct netr_SamInfo3 *info3, @@ -321,9 +341,8 @@ NTSTATUS create_local_nt_token_from_info3(TALLOC_CTX *mem_ctx, DEBUG(10, ("Create local NT token for %s\n", info3->base.account_name.string)); - usrtok = talloc_zero(mem_ctx, struct security_token); + usrtok = init_local_nt_token(mem_ctx); if (!usrtok) { - DEBUG(0, ("talloc failed\n")); return NT_STATUS_NO_MEMORY; } @@ -441,8 +460,8 @@ NTSTATUS create_local_nt_token(TALLOC_CTX *mem_ctx, DEBUG(10, ("Create local NT token for %s\n", dom_sid_str_buf(user_sid, &buf))); - if (!(result = talloc_zero(mem_ctx, struct security_token))) { - DEBUG(0, ("talloc failed\n")); + result = init_local_nt_token(mem_ctx); + if (result == NULL) { status = NT_STATUS_NO_MEMORY; goto err; } diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index f0f7345d62f..054d1bddcb3 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -731,6 +731,10 @@ static NTSTATUS contact_winbind_change_pswd_auth_crap(const char *username, return nt_status; } +/* + * This function does not create a full auth_session_info, just enough + * for the caller to get the "unix" username + */ static NTSTATUS ntlm_auth_generate_session_info(struct auth4_context *auth_context, TALLOC_CTX *mem_ctx, void *server_returned_info, @@ -759,7 +763,17 @@ static NTSTATUS ntlm_auth_generate_session_info(struct auth4_context *auth_conte return NT_STATUS_NO_MEMORY; } - session_info->security_token = talloc_zero(session_info, struct security_token); + /* + * This is not a full session_info - it is not created + * correctly and misses any claims etc, because all we + * actually use in the caller is the unix username. + * + * Therefore so no claims need to be added and + * se_access_check() will never run. + */ + session_info->security_token + = security_token_initialise(talloc_tos(), + CLAIMS_EVALUATION_INVALID_STATE); if (session_info->security_token == NULL) { TALLOC_FREE(session_info); return NT_STATUS_NO_MEMORY; diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 6d41421be1a..ece0eb3d544 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -457,7 +457,13 @@ static NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3, return NT_STATUS_OK; } - token = talloc_zero(talloc_tos(), struct security_token); + /* + * This is a limited-use security_token for the purpose of + * checking the SID list below, so no claims need to be added + * and se_access_check() will never run. + */ + token = security_token_initialise(talloc_tos(), + CLAIMS_EVALUATION_INVALID_STATE); if (token == NULL) { DEBUG(0, ("talloc failed\n")); return NT_STATUS_NO_MEMORY; diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c index a39e90e575e..ca3f5d5371e 100644 --- a/source4/dsdb/samdb/samdb.c +++ b/source4/dsdb/samdb/samdb.c @@ -43,6 +43,7 @@ #include "param/secrets.h" #include "auth/auth.h" #include "lib/tsocket/tsocket.h" +#include "lib/param/loadparm.h" /* connect to the SAM database specified by URL @@ -170,8 +171,32 @@ NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, struct security_token *ptoken; uint32_t i; NTSTATUS status; + enum claims_evaluation_control evaluate_claims; - ptoken = security_token_initialise(mem_ctx); + /* + * Some special-case callers can't supply the lp_ctx, but do + * not interact with claims or conditional ACEs + */ + if (lp_ctx == NULL) { + evaluate_claims = CLAIMS_EVALUATION_INVALID_STATE; + } else { + enum acl_claims_evaluation claims_evaultion_setting + = lpcfg_acl_claims_evaluation(lp_ctx); + + /* + * We are well inside the AD DC, so we do not need to check + * the server role etc + */ + switch (claims_evaultion_setting) { + case ACL_CLAIMS_EVALUATION_AD_DC_ONLY: + evaluate_claims = CLAIMS_EVALUATION_ALWAYS; + break; + default: + evaluate_claims = CLAIMS_EVALUATION_NEVER; + } + } + + ptoken = security_token_initialise(mem_ctx, evaluate_claims); NT_STATUS_HAVE_NO_MEMORY(ptoken); if (num_sids > UINT32_MAX - 6) { diff --git a/source4/librpc/ndr/py_security.c b/source4/librpc/ndr/py_security.c index 74c73dd8dfe..9b1e95e0f48 100644 --- a/source4/librpc/ndr/py_security.c +++ b/source4/librpc/ndr/py_security.c @@ -471,8 +471,17 @@ static PyObject *py_token_set_privilege(PyObject *self, PyObject *args) static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs) { - return pytalloc_steal(self, security_token_initialise(NULL)); -} + int evaluate_claims = CLAIMS_EVALUATION_INVALID_STATE; + const char *kwnames[] = { "evaluate_claims", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", + discard_const_p(char *, kwnames), + &evaluate_claims)) { + return NULL; + } + + return pytalloc_steal(self, security_token_initialise(NULL, evaluate_claims)); +} static PyMethodDef py_token_extra_methods[] = { { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,