libcli/security: Pass in claims evaluation state when building any security token
authorAndrew Bartlett <abartlet@samba.org>
Thu, 14 Sep 2023 10:09:50 +0000 (22:09 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 26 Sep 2023 23:45:35 +0000 (23:45 +0000)
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
libcli/security/security_token.c
libcli/security/security_token.h
python/samba/tests/token_factory.py
source3/auth/token_util.c
source3/utils/ntlm_auth.c
source3/winbindd/winbindd_pam.c
source4/dsdb/samdb/samdb.c
source4/librpc/ndr/py_security.c

index 17d6c73abbb5bd612cde5536f205d19970a60f95..95bf68e8e24f1f36fbc2d3f6e2f1bcb9d7b68852 100644 (file)
@@ -22,6 +22,8 @@
 */
 
 #include "replace.h"
+#include <talloc.h>
+#include "lib/util/talloc_stack.h"
 #include "lib/util/debug.h"
 #include "lib/util/fault.h"
 #include "libcli/security/security_token.h"
 /*
   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;
 }
 
index bb8795919e917271d3dc98f6d68b8a4f7e162d9e..1c9b24028534b1ccf94591b75e9016ff39481fac 100644 (file)
@@ -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.
index 63777ea69284b8cc4cea66b9d25999b2ad03b7ca..cf5e490b621452ec88665f68eb33b6245022123a 100644 (file)
@@ -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)
index f508dfd3a86fbf69aa57e7b289bc77ac4d799b5d..aac5749a8152c06c03daceeeeffb893ce022ad57 100644 (file)
@@ -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;
        }
index f0f7345d62f7fe27918af070d6b5635d92721c1e..054d1bddcb32503aff84e76f5fb6b6d3c9283f94 100644 (file)
@@ -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;
index 6d41421be1a697118e1c19bae1620ba6b64b1117..ece0eb3d5445bf377a9fdafbbbff323a33eea3bf 100644 (file)
@@ -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;
index a39e90e575eef07c89817894b2ec138d6a2c2736..ca3f5d5371e6a4baf7680c03d77623a445dfc8f0 100644 (file)
@@ -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) {
index 74c73dd8dfed6639fd3925d04b4fece94dcfbd9c..9b1e95e0f48ceeede98d29d1b84c75e1c353a837 100644 (file)
@@ -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,